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