Changeset: e75ff4fa24bf for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e75ff4fa24bf
Added Files:
        sql/backends/monet5/Tests/rapi00.sql
        sql/backends/monet5/sql_rapi.mal
Removed Files:
        sql/backends/monet5/Tests/r00.sql
Modified Files:
        sql/backends/monet5/Tests/All
        sql/include/sql_catalog.h
        sql/scripts/50_rapi.sql
        sql/server/sql_parser.y
        sql/server/sql_scan.c
Branch: RIntegration
Log Message:

Extending the parser/lexical analyser
[still buggy]


diffs (196 lines):

diff --git a/sql/backends/monet5/Tests/All b/sql/backends/monet5/Tests/All
--- a/sql/backends/monet5/Tests/All
+++ b/sql/backends/monet5/Tests/All
@@ -1,5 +1,8 @@
 optimizers
 
-r00
+rapi00
+
+inlineR
+inlineUDF
 
 #Mbeddedsql5--help   disabled for now
diff --git a/sql/backends/monet5/Tests/r00.sql 
b/sql/backends/monet5/Tests/rapi00.sql
rename from sql/backends/monet5/Tests/r00.sql
rename to sql/backends/monet5/Tests/rapi00.sql
--- a/sql/backends/monet5/Tests/r00.sql
+++ b/sql/backends/monet5/Tests/rapi00.sql
@@ -1,10 +1,11 @@
 -- MonetDB R interface
-create r_tmp(i integer, j integer);
+
+create table rapi_tmp(i integer, j integer);
 
 select rapi.scalar('return(1234);');
 
 select * from rapi.dataframe('return(df);');
 
-select * from r_tmp where rapi.scalar('return(1);');
+select * from rapi_tmp where rapi.scalar('return(1);');
 
-drop table r_tmp;
+drop table rapi_tmp;
diff --git a/sql/backends/monet5/sql_rapi.mal b/sql/backends/monet5/sql_rapi.mal
new file mode 100644
--- /dev/null
+++ b/sql/backends/monet5/sql_rapi.mal
@@ -0,0 +1,22 @@
+# The contents of this file are subject to the MonetDB Public License
+# Version 1.1 (the "License"); you may not use this file except in
+# compliance with the License. You may obtain a copy of the License at
+# http://www.monetdb.org/Legal/MonetDBLicense
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+# License for the specific language governing rights and limitations
+# under the License.
+#
+# The Original Code is the MonetDB Database System.
+#
+# The Initial Developer of the Original Code is CWI.
+# Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
+# Copyright August 2008-2013 MonetDB B.V.
+# All Rights Reserved.
+
+module rapi;
+
+pattern sql_eval(expr:str,arg:any...):any...
+address RAPIevalSQL
+comment "Execute a simple R script from within SQL";
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -274,12 +274,16 @@ typedef struct sql_arg {
 #define F_AGGR 3
 #define F_FILT 4
 #define F_UNION 5
+#define F_CBODY 6
+#define F_RBODY 7
 
 #define IS_FUNC(f) (f->type == F_FUNC)
 #define IS_PROC(f) (f->type == F_PROC)
 #define IS_AGGR(f) (f->type == F_AGGR)
 #define IS_FILT(f) (f->type == F_FILT)
 #define IS_UNION(f) (f->type == F_UNION)
+#define IS_CBODY(f) (f->type == F_CBODY)
+#define IS_RBODY(f) (f->type == F_RBODY)
 
 typedef struct sql_func {
        sql_base base;
diff --git a/sql/scripts/50_rapi.sql b/sql/scripts/50_rapi.sql
--- a/sql/scripts/50_rapi.sql
+++ b/sql/scripts/50_rapi.sql
@@ -20,8 +20,6 @@ create schema rapi;
 create function rapi.scalar(expr string) returns double external name 
rapi.scalar;
 
 create function rapi.dataframe(expr string) returns table(ret1 double) 
external name rapi.dataframe;
--- create function rapi.vector(expr string) returns table(ret1 double) 
external name rapi.sql_eval;
--- create function rapi.array(expr string) returns table(ret0 integer, ret1 
integer, ret1 double) external name rapi.sql_eval;
 
 -- we need a variable argument and return list
 create function rapi.dataframe(exp string, arg1 int) returns table(ret1 
double) external name rapi.dataframe;
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -366,6 +366,7 @@ int yydebug=1;
        case_opt_else_statement
        variable_list
        routine_body
+       language_body
        table_function_column_list
        select_target_list
        external_function_name
@@ -461,6 +462,7 @@ int yydebug=1;
        tz
 
 %right <sval> STRING
+%right <sval> X_BODY
 
 /* sql prefixes to avoid name clashes on various architectures */
 %token <sval>
@@ -559,6 +561,7 @@ SQLCODE SQLERROR UNDER WHENEVER
 %token AS TRIGGER OF BEFORE AFTER ROW STATEMENT sqlNEW OLD EACH REFERENCING
 %token OVER PARTITION CURRENT EXCLUDE FOLLOWING PRECEDING OTHERS TIES RANGE 
UNBOUNDED
 
+%token X_BODY 
 %%
 
 sqlstmt:
@@ -1864,6 +1867,12 @@ routine_body:
        procedure_statement_list procedure_statement SCOLON 
     END
                { $$ = append_symbol($3,$4); }
+ | language_body {$$ = $1;}
+ ;
+
+language_body:
+   LANGUAGE 'R' X_BODY { $$ =L(); append_string($$,$3); append_int($$,F_FUNC); 
append_int($$,F_RBODY);} 
+ | LANGUAGE 'C' X_BODY { $$ =L(); append_string($$,$3); append_int($$,F_FUNC); 
append_int($$,F_CBODY);}
  ;
 
 /* change into compound statement 
diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c
--- a/sql/server/sql_scan.c
+++ b/sql/server/sql_scan.c
@@ -628,6 +628,51 @@ scanner_string(mvc *c, int quote)
        return LEX_ERROR;
 }
 
+/* scan a structure {blah} into a string. We only count the matching {}
+ * unless escaped. We do not consider embeddings in string literals yet
+ */
+
+static int
+scanner_body(mvc *c)
+{
+       struct scanner *lc = &c->scanner;
+       bstream *rs = lc->rs;
+       int cur = (int) 'x';
+       int blk = 1;
+       int escape = 0;
+
+       lc->started = 1;
+       assert(rs->buf[(int)rs->pos + lc->yycur-1] == '{');
+       while (cur != EOF) {
+               unsigned int pos = (int)rs->pos + lc->yycur;
+
+               while ((((cur = rs->buf[pos++]) & 0x80) == 0) && cur && (blk || 
escape)) {
+                       if (cur != '\\')
+                               escape = 0;
+                       else
+                               escape = !escape;
+                       blk += cur =='{';
+                       blk -= cur =='}';
+               }
+               lc->yycur = pos - (int)rs->pos;
+               assert(pos <= rs->len + 1);
+               if (blk == 0 && !escape)
+                       return scanner_token(lc, X_BODY);
+               lc->yycur--;    /* go back to current (possibly invalid) char */
+               if (!cur) {
+                       if (lc->rs->len >= lc->rs->pos + lc->yycur + 1) {
+                               (void) sql_error(c, 2, "NULL byte in string");
+                               return LEX_ERROR;
+                       }
+                       cur = scanner_read_more(lc, 1);
+               } else {
+                       cur = scanner_getc(lc);
+               }
+       }
+       (void) sql_error(c, 2, "unexpected end of input");
+       return LEX_ERROR;
+}
+
 static int 
 keyword_or_ident(mvc * c, int cur)
 {
@@ -804,6 +849,8 @@ int scanner_symbol(mvc * c, int cur)
        case '\'':
        case '"':
                return scanner_string(c, cur);
+       case '{':
+               return scanner_body(c);
        case '-':
                lc->started = 1;
                next = scanner_getc(lc);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to