Changeset: 8dec4e1acd05 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8dec4e1acd05
Modified Files:
        monetdb5/extras/jaql/jaql.c
        monetdb5/extras/jaql/jaql.l
        monetdb5/extras/jaql/jaql.y
Branch: jacqueline
Log Message:

jaql: execute multi-statement queries

Keep on parsing until we finished the entire buffer.  Skip empty bits.


diffs (135 lines):

diff --git a/monetdb5/extras/jaql/jaql.c b/monetdb5/extras/jaql/jaql.c
--- a/monetdb5/extras/jaql/jaql.c
+++ b/monetdb5/extras/jaql/jaql.c
@@ -563,54 +563,59 @@ JAQLexecute(Client cntxt, MalBlkPtr mb, 
                cntxt->state[MAL_SCENARIO_OPTIMIZE] = j;
        }
 
-
        j->buf = jaql;
        yylex_init_extra(j, &j->scanner);
-       yyparse(j);
-       yylex_destroy(j->scanner);
 
+       do {
+               yyparse(j);
+
+               if (j->err[0] != '\0')
+                       break;
+               if (j->p == NULL)
+                       continue;
+
+               switch (j->explain) {
+                       case 0: {
+                               str err;
+                               /* normal (execution) mode */
+                               Symbol prg = newFunction(putName("user", 4), 
putName("jaql", 4),
+                                               FUNCTIONsymbol);
+                               /* we do not return anything */
+                               setVarType(prg->def, 0, TYPE_void);
+                               setVarUDFtype(prg->def, 0);
+                               (void)dumptree(j, prg->def, j->p);
+                               pushEndInstruction(prg->def);
+                               /* codegen could report an error */
+                               if (j->err[0] != '\0')
+                                       break;
+
+                               chkProgram(cntxt->nspace, prg->def);
+                               printFunction(cntxt->fdout, prg->def, 0, 
LIST_MAL_STMT);
+                               err = (str)runMAL(cntxt, prg->def, 1, 0, 0, 0);
+                               freeMalBlk(prg->def);
+                               if (err != MAL_SUCCEED) {
+                                       snprintf(j->err, sizeof(j->err), "%s", 
err);
+                                       GDKfree(err);
+                                       break;
+                               }
+                       }       break;
+                       case 1: /* explain */
+                       case 2: /* plan */
+                               printtree(j->p, 0, j->explain == 1);
+                               break;
+                       /* case 3: trace? */
+               }
+               freetree(j->p);
+               /* reset, j->buf has been reset by the lexer if EOF was found */
+               j->p = NULL;
+               j->esc_depth = 0;
+               j->explain = 0;
+       } while (j->buf != NULL && j->err[0] == '\0');
        if (j->err[0] != '\0')
                throw(MAL, "jaql.execute", "%s", j->err);
 
-       switch (j->explain) {
-               case 0: {
-                       str err;
-                       /* normal (execution) mode */
-                       Symbol prg = newFunction(putName("user", 4), 
putName("jaql", 4),
-                                       FUNCTIONsymbol);
-                       /* we do not return anything */
-                       setVarType(prg->def, 0, TYPE_void);
-                       setVarUDFtype(prg->def, 0);
-                       (void)dumptree(j, prg->def, j->p);
-                       pushEndInstruction(prg->def);
-
-                       if (j->err[0] != '\0') {
-                               freetree(j->p);
-                               throw(MAL, "jaql.execute", "%s", j->err);
-                       }
-                       chkProgram(cntxt->nspace, prg->def);
-                       printFunction(cntxt->fdout, prg->def, 0, LIST_MAL_STMT);
-                       err = (str)runMAL(cntxt, prg->def, 1, 0, 0, 0);
-                       freeMalBlk(prg->def);
-                       if (err != MAL_SUCCEED) {
-                               freetree(j->p);
-                               return err;
-                       }
-               }       break;
-               case 1: /* explain */
-               case 2: /* plan */
-                       printtree(j->p, 0, j->explain == 1);
-                       break;
-               /* case 3: trace? */
-       }
-       freetree(j->p);
-       /* reset all but vars */
-       j->p = NULL;
-       j->esc_depth = 0;
-       j->buf = NULL;
-       j->err[0] = '\0';
+       yylex_destroy(j->scanner);
        j->scanner = NULL;
-       j->explain = 0;
        /* freevars(j->vars);  should do only on client destroy */
 
        *ret = 0;
diff --git a/monetdb5/extras/jaql/jaql.l b/monetdb5/extras/jaql/jaql.l
--- a/monetdb5/extras/jaql/jaql.l
+++ b/monetdb5/extras/jaql/jaql.l
@@ -103,6 +103,7 @@ false      return _FALSE;
 <OBJ>.     yymore();
 [ \t\r\n]+ /* ignore whitespace */;
 [a-zA-Z_][a-zA-Z0-9_]* {yylval->j_ident = GDKstrdup(yytext); return _IDENT;}
+<<EOF>>    {yyextra->buf = NULL; return EOF;}
 .                      {
        char buf[32];
        snprintf(buf, sizeof(buf), "unexpected character: %c", yytext[0]);
diff --git a/monetdb5/extras/jaql/jaql.y b/monetdb5/extras/jaql/jaql.y
--- a/monetdb5/extras/jaql/jaql.y
+++ b/monetdb5/extras/jaql/jaql.y
@@ -86,6 +86,16 @@ stmt: jaql _SCOLON
        {
                j->p = $$ = NULL;
                YYABORT;
+       }
+       | _SCOLON
+       {
+               j->p = $$ = NULL;
+               YYACCEPT;
+       }
+       |
+       {
+               j->p = $$ = NULL;
+               YYACCEPT;
        };
 
 jaql: jaqlpipe                  {$$ = append_jaql_pipe($1, 
make_json_output(NULL));}
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to