Changeset: c5971d03df2c for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c5971d03df2c Added Files: monetdb5/extras/jaql/jaqlscenario.c Modified Files: monetdb5/extras/jaql/Makefile.ag monetdb5/extras/jaql/jaql.c monetdb5/extras/jaql/jaql.h monetdb5/extras/jaql/jaql.mal Branch: jacqueline Log Message:
jaqlscenario: add jaql scenario to mserver First preliminary version of the jaql scenario, for clients to connect from remote using language "jaql". diffs (truncated from 349 to 300 lines): diff --git a/monetdb5/extras/jaql/Makefile.ag b/monetdb5/extras/jaql/Makefile.ag --- a/monetdb5/extras/jaql/Makefile.ag +++ b/monetdb5/extras/jaql/Makefile.ag @@ -23,6 +23,7 @@ INCLUDES = ../../mal \ ../../optimizer \ ../../../common/options \ ../../../common/stream \ + ../../../common/utils \ ../../../gdk lib__json = { @@ -36,7 +37,7 @@ lib__json = { lib__jaql = { MODULE DIR = libdir/monetdb5 - SOURCES = jaql.c jaql.h jaqlgencode.c jaqlgencode.h + SOURCES = jaql.c jaql.h jaqlgencode.c jaqlgencode.h jaqlscenario.c # the ./ is necessary for autogen not to generate garbage LIBS = ./parser/libjaqlp ../../tools/libmonetdb5 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 @@ -1621,7 +1621,8 @@ freetree(tree *j) } void -freevars(jvar *v) { +freevars(jvar *v) +{ jvar *n; while (v != NULL) { GDKfree(v->vname); diff --git a/monetdb5/extras/jaql/jaql.h b/monetdb5/extras/jaql/jaql.h --- a/monetdb5/extras/jaql/jaql.h +++ b/monetdb5/extras/jaql/jaql.h @@ -53,6 +53,7 @@ typedef struct _jc { void *scanner; char explain; jvar *vars; + int vtop; } jc; enum treetype { @@ -160,6 +161,8 @@ tree *append_func_arg(tree *oarg, tree * tree *set_func_input_from_pipe(tree *func); void printtree (tree *t, int level, char op); void freetree(tree *t); +void freevars(jvar *v); +str getContext(Client cntxt, jc **c); jaql_export str JAQLexecute(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci); diff --git a/monetdb5/extras/jaql/jaql.mal b/monetdb5/extras/jaql/jaql.mal --- a/monetdb5/extras/jaql/jaql.mal +++ b/monetdb5/extras/jaql/jaql.mal @@ -36,3 +36,12 @@ comment "Set or overwrite value of JSON pattern cast(b:bat[:oid,:any], t:any_1):bat[:oid,:any_1] address JAQLcast comment "Return BAT b as BAT with tail type of t, if the BAT tail in reality is of that type"; + +# scenario functions and init call +command prelude() +address JAQLprelude; + +command epilogue() +address JAQLepilogue; + +jaql.prelude(); diff --git a/monetdb5/extras/jaql/jaqlscenario.c b/monetdb5/extras/jaql/jaqlscenario.c new file mode 100644 --- /dev/null +++ b/monetdb5/extras/jaql/jaqlscenario.c @@ -0,0 +1,275 @@ +/* + * 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-2012 MonetDB B.V. + * All Rights Reserved. + */ + +#include "monetdb_config.h" +/*#include "jaql_scenario.h"*/ +#include "jaql.h" +#include "jaqlgencode.h" +#include "msabaoth.h" +#include "mal.h" +#include "mal_client.h" +#include "mal_exception.h" +#include "mal_scenario.h" +#include "mal_instruction.h" +#include "optimizer.h" + +#include "parser/jaql.tab.h" +#include "parser/jaql.yy.h" + +extern int jaqlparse(jc *j); + +str +JAQLprelude(void) +{ + Scenario s = getFreeScenario(); + + if (!s) + throw(MAL, "jaql.start", "out of scenario slots"); + + s->name = "jaql"; + s->language = "jaql"; + s->initSystem = NULL; + s->exitSystem = "JAQLexit"; + s->initClient = "JAQLinitClient"; + s->exitClient = "JAQLexitClient"; + s->reader = "JAQLreader"; + s->parser = "JAQLparser"; + s->engine = "JAQLengine"; + + fprintf(stdout, "# MonetDB/JAQL module loaded\n"); + fflush(stdout); /* make merovingian see this *now* */ + + return msab_marchScenario(s->name); +} + +str +JAQLepilogue(void) +{ + /* this function is never called, but for the idea of it, we clean + * up our own mess */ + return msab_retreatScenario("jaql"); +} + +str +JAQLexit(Client c) +{ + (void) c; /* not used */ + return MAL_SUCCEED; +} + +str +JAQLinitClient(Client c) +{ + jc *j = NULL; + str msg = MAL_SUCCEED; + + j = GDKzalloc(sizeof(jc)); + c->state[MAL_SCENARIO_OPTIMIZE] = j; + jaqllex_init_extra(j, &j->scanner); + + optimizerInit(); /* for all xxxRef vars in dumpcode */ + + return msg; +} + +str +JAQLexitClient(Client c) +{ + if (c->state[MAL_SCENARIO_PARSER] != NULL) { + jc *j = (jc *) c->state[MAL_SCENARIO_PARSER]; + + jaqllex_destroy(j->scanner); + j->scanner = NULL; + freevars(j->vars); + + c->state[MAL_SCENARIO_PARSER] = NULL; + } + + return MAL_SUCCEED; +} + + +void +freeVariables(Client c, MalBlkPtr mb, MalStkPtr glb, int start) +{ + int i, j; + + for (i = start; i < mb->vtop;) { + if (glb) { + if (isVarCleanup(mb,i)) + garbageElement(c,&glb->stk[i]); + /* clean stack entry */ + glb->stk[i].vtype = TYPE_int; + glb->stk[i].val.ival = 0; + glb->stk[i].len = 0; + } + clearVariable(mb, i); + i++; + } + mb->vtop = start; + for (i = j = 0; i < mb->ptop; i++) { + if (mb->prps[i].var < start) { + if (i > j) + mb->prps[j] = mb->prps[i]; + j++; + } + } + mb->ptop = j; +} + + +str +JAQLreader(Client c) +{ + if (MCreadClient(c) > 0) + return MAL_SUCCEED; + + c->mode = FINISHING; + if (c->fdin) { + c->fdin->buf[c->fdin->pos] = 0; + } else { + throw(MAL, "jaql.reader", RUNTIME_IO_EOF); + } + + return MAL_SUCCEED; +} + +str +JAQLparser(Client c) +{ + bstream *in = c->fdin; + stream *out = c->fdout; + jc *j; + int oldvtop, oldstop; + str errmsg; + + if ((errmsg = getContext(c, &j)) != MAL_SUCCEED) { + /* tell the client */ + mnstr_printf(out, "!%s, aborting\n", errmsg); + mnstr_flush(out); + /* leave a message in the log */ + fprintf(stderr, "%s, cannot handle client!\n", errmsg); + /* stop here, instead of printing the exception below to the + * client in an endless loop */ + c->mode = FINISHING; + return errmsg; + } + + c->curprg->def->errors = 0; + oldvtop = c->curprg->def->vtop; + oldstop = c->curprg->def->stop; + j->vtop = oldvtop; + j->explain = 0; + j->buf = in->buf + in->pos; + + jaqlparse(j); + if (j->err[0] != '\0') { + in->pos = in->len; + c->yycur = 0; + /* tell the client */ + mnstr_printf(out, "!%s\n", j->err); + mnstr_flush(out); + throw(PARSE, "JAQLparser", "%s", j->err); + } + + /* now the parsing is done we should advance the stream */ + in->pos = in->len; + c->yycur = 0; + + if (j->p == NULL) { /* there was nothing to parse, EOF */ + c->mode = FINISHING; + return MAL_SUCCEED; + } + + if (j->explain < 2) { + Symbol prg = c->curprg; + (void)dumptree(j, c, prg->def, j->p); + pushEndInstruction(prg->def); + /* codegen could report an error */ + if (j->err[0] != '\0') { + MSresetInstructions(prg->def, oldstop); + freeVariables(c, prg->def, c->glb, oldvtop); + prg->def->errors = 0; + mnstr_printf(out, "!%s\n", j->err); + mnstr_flush(out); + throw(PARSE, "JAQLparse", "%s", j->err); + } + + chkTypes(out, c->nspace, prg->def, FALSE); + if (prg->def->errors) { + /* this is bad already, so let's try to make it debuggable */ + mnstr_printf(out, "!jaqlgencode: generated program contains errors\n"); + printFunction(out, c->curprg->def, 0, LIST_MAPI); + mnstr_flush(out); + + /* restore the state */ + MSresetInstructions(prg->def, oldstop); + freeVariables(c, prg->def, c->glb, oldvtop); + prg->def->errors = 0; + throw(SYNTAX, "JAQLparser", "typing errors"); + } _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list