Changeset: 16a1c6090fa0 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=16a1c6090fa0
Modified Files:
        sql/backends/monet5/datacell/50_datacell.sql
        sql/backends/monet5/datacell/Tests/scenario06.sql
        sql/backends/monet5/datacell/datacell.mx
        sql/backends/monet5/datacell/opt_datacell.mx
        sql/backends/monet5/datacell/petrinet.mx
Branch: default
Log Message:

Add procedural continuous queries
Any SQL procedure can be compiled for continous execution.
Scenario06 shows how this can be used to both pass events
to an emitter and to keep a statistics log in an ordinary table,
i.e. mixing baskets and tables in a multi-query setting.
Overall performance is as predicted, i.e. high.


diffs (276 lines):

diff --git a/sql/backends/monet5/datacell/50_datacell.sql 
b/sql/backends/monet5/datacell/50_datacell.sql
--- a/sql/backends/monet5/datacell/50_datacell.sql
+++ b/sql/backends/monet5/datacell/50_datacell.sql
@@ -41,6 +41,9 @@
 create procedure datacell.query(proc string, def string)
        external name datacell.query;
 
+create procedure datacell.query(proc string)
+       external name datacell.query;
+
 create procedure datacell.remove (obj string)
     external name datacell.remove;
 
diff --git a/sql/backends/monet5/datacell/Tests/scenario06.sql 
b/sql/backends/monet5/datacell/Tests/scenario06.sql
new file mode 100644
--- /dev/null
+++ b/sql/backends/monet5/datacell/Tests/scenario06.sql
@@ -0,0 +1,41 @@
+-- Scenario to exercise the datacell implementation
+-- using a single receptor and emitter
+-- use a compound query to deliver the events to both emitter
+-- and store aggregated information in a log
+
+create schema datacell;
+set optimizer='datacell_pipe';
+
+create table datacell.barrelin(
+    id integer,
+    tag timestamp,
+    payload integer
+);
+create table datacell.barrelout (like datacell.barrelin);
+create table datacell.barrellog( ts timestamp, cnt integer);
+
+call datacell.receptor('datacell.barrelin','localhost',50500);
+
+call datacell.emitter('datacell.barrelout','localhost',50600);
+
+create procedure datacell.splitter()
+begin
+       insert into datacell.barrelout select * from datacell.barrelin;
+       insert into datacell.barrellog values (now(), (select count(*) from 
datacell.barrelin));
+end;
+call datacell.query('datacell.splitter');
+
+call datacell.resume();
+call datacell.dump();
+
+-- externally, activate the sensor 
+--sensor --host=localhost --port=50500 --events=100 --columns=3 --delay=1
+-- externally, activate the actuator server to listen
+-- actuator 
+
+
+-- wrapup
+call datacell.postlude();
+drop table datacell.barrelin;
+drop table datacell.barrelout;
+
diff --git a/sql/backends/monet5/datacell/datacell.mx 
b/sql/backends/monet5/datacell/datacell.mx
--- a/sql/backends/monet5/datacell/datacell.mx
+++ b/sql/backends/monet5/datacell/datacell.mx
@@ -60,6 +60,10 @@
 address DCquery
 comment "Add a new continuous query.";
 
+pattern query(name:str):void
+address DCquery
+comment "Add a new continuous query procedure.";
+
 pattern pause()
 address DCpauseScheduler
 comment "(Re)start the petrinet scheduler.";
@@ -148,6 +152,7 @@
 #include "datacell.h"
 #include "opt_datacell.h"
 #include "sql_optimizer.h"
+#include "sql_gencode.h"
 
 #ifdef WIN32
 #include "winsock2.h"
@@ -168,6 +173,33 @@
  * grab all tables in the datacell schema and turn them into baskets.
  * The same for all procedures, turn them into continuous queries.
 */
+static str
+DCprocedureStmt(Client cntxt, MalBlkPtr mb, str schema, str nme)
+{
+       mvc *m = NULL;
+       str msg = getContext(cntxt, mb, &m, NULL);
+       sql_schema  *s;
+       backend *be;
+       node *o;
+       sql_func *f;
+       sql_trans *tr;
+
+       if ( msg)
+               return msg;
+       s = mvc_bind_schema(m, schema);
+       if (s == NULL)
+               throw(SQL, "datacell.query", "Schema missing");
+       tr = m->session->tr;
+       for (o = s->funcs.set->h; o; o = o->next) {
+               f = o->data;
+               if ( strcmp(f->base.name, nme) == 0 ){
+                       be = (void *) backend_create(m, cntxt);
+                       backend_create_func(be, f);
+                       break;
+               }
+       }
+       return MAL_SUCCEED;
+}
 
 str
 DCprelude(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
@@ -334,34 +366,62 @@
 DCquery(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
        str nme = *(str*) getArgReference(stk,pci,1);
-       str *def = (str*) getArgReference(stk,pci,2);
-       Symbol s;
+       str def;
+       Symbol s = NULL;
+       MalBlkPtr qry;
        str msg;
        InstrPtr p;
        Module scope;
        lng clk = GDKusec();
-       char buf[BUFSIZ], *lsch, *ltbl;
+       char buf[BUFSIZ], *lsch, *lnme;
 
-       BSKTelements( nme, buf, &lsch, &ltbl);
+       BSKTelements( nme, buf, &lsch, &lnme);
        BSKTtolower(lsch);
-       BSKTtolower(ltbl);
+       BSKTtolower(lnme);
 
        (void) mb;
        /* check if the argument denotes a procedure name */
        /* if so, get its definition to be compiled */
 
-       msg = SQLstatementIntern(cntxt, def, ltbl, 0, 0);
-       if ( msg )
-               return msg;
+       /* check existing of the pre-compiled function */
        scope = findModule(cntxt->nspace,putName(lsch,strlen(lsch)));
-       s = newFunction(putName(lsch,strlen(lsch)), putName(ltbl, 
strlen(ltbl)),FUNCTIONsymbol);
+       if ( scope) 
+               s = findSymbolInModule(scope,putName(lnme,strlen(lnme)));
+       /* is it defined in module user */
+       if ( s == NULL)
+               s = 
findSymbolInModule(cntxt->nspace,putName(lnme,strlen(lnme)));
+
+       if (s == NULL){
+               if ( pci->argc == 3 ) {
+                       def = *(str*) getArgReference(stk,pci,2);
+                       msg = SQLstatementIntern(cntxt, &def, lnme, 0, 0);
+                       if ( msg )
+                               return msg;
+                       qry =cntxt->curprg->def;
+               } else {
+                       /* get definition from catalog */
+                       msg =DCprocedureStmt(cntxt, mb, lsch, lnme);
+                       if ( msg)
+                               return msg;
+                       s = 
findSymbolInModule(cntxt->nspace,putName(lnme,strlen(lnme)));
+                       if ( s == NULL)
+                               throw(SQL,"datacell.query","Definition 
missing");
+                       qry= s->def;
+               }
+       } else 
+               if ( pci->argc == 3)
+                       throw(SQL,"datacell.query","Query already defined");
+               else qry = s->def;
+
+       scope = findModule(cntxt->nspace,putName(lsch,strlen(lsch)));
+       s = newFunction(putName(lsch,strlen(lsch)), putName(lnme, 
strlen(lnme)),FUNCTIONsymbol);
        if ( s == NULL) 
                throw(SQL,"datacell.query","Procedure code does not exist");
     freeMalBlk(s->def);
-    s->def = copyMalBlk(cntxt->curprg->def);
+    s->def = copyMalBlk(qry);
        p= getInstrPtr(s->def,0);
        setModuleId(p, putName(lsch,strlen(lsch)));
-       setFunctionId(p, putName(ltbl,strlen(ltbl)));
+       setFunctionId(p, putName(lnme,strlen(lnme)));
     insertSymbol(scope,s);
        /* printFunction(cntxt->fdout, s->def, 0, LIST_MAL_STMT);*/
        /* optimize the code and register at scheduler */
diff --git a/sql/backends/monet5/datacell/opt_datacell.mx 
b/sql/backends/monet5/datacell/opt_datacell.mx
--- a/sql/backends/monet5/datacell/opt_datacell.mx
+++ b/sql/backends/monet5/datacell/opt_datacell.mx
@@ -58,7 +58,7 @@
 int
 OPTdatacellImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci)
 {
-       int actions = 0, fnd;
+       int actions = 0, fnd, mvc= 0;
     int bskt, i, j, k, limit, vlimit, slimit;
     InstrPtr r, p, *old;
        str  col;
@@ -141,6 +141,9 @@
                        freeInstruction(p);
                        continue;
                }
+
+               if ( getModuleId(p) == sqlRef && getFunctionId(p) == mvcRef)
+                       mvc= getArg(p,0);
                if ( getModuleId(p) == sqlRef  && (getFunctionId(p) == bindRef 
||getFunctionId(p) == binddbatRef)){
                        snprintf(buf,BUFSIZ,"%s.%s", getVarConstant(mb, 
getArg(p,2)).val.sval, getVarConstant(mb, getArg(p,3)).val.sval);
                        col = getVarConstant(mb, getArg(p,4)).val.sval;
@@ -156,6 +159,9 @@
                                        tables[m++]= GDKstrdup(buf);
                                        actions = 1;
                                }
+                       } else {
+                               pushInstruction(mb,p);
+                               continue;
                        }
 
                        fnd = 0;
@@ -228,6 +234,9 @@
                                        getArg(p, 1) = getArg(p, 5);
                                        p->argc = 2;
                                }
+                       } else {
+                               getArg(p,1) = mvc;
+                               mvc = getArg(p,0);
                        }
                }
                pushInstruction(mb, p);
@@ -235,6 +244,7 @@
        (void)stk;
        (void)pci;
 
+       printFunction(cntxt->fdout, mb, 0, LIST_MAL_STMT | LIST_MAPI);
        if (actions)
        {
                addPipeDefinition("datacell_pipe",
diff --git a/sql/backends/monet5/datacell/petrinet.mx 
b/sql/backends/monet5/datacell/petrinet.mx
--- a/sql/backends/monet5/datacell/petrinet.mx
+++ b/sql/backends/monet5/datacell/petrinet.mx
@@ -29,6 +29,11 @@
 @end example
 @mal
 module petrinet;
+pattern register(nme:str):void
+address PNregister
+comment "Add a continous query to the Petri net. It will analyse
+the MAL block to determine the input/output dependencies. ";
+
 pattern register(nme:str, def:str):void
 address PNregister
 comment "Add a continous query to the Petri net. It will analyse
@@ -192,7 +197,6 @@
        Symbol s = 0;
        int *ret = (int *)getArgReference(stk, pci, 0);
        str nme = *(str *)getArgReference(stk, pci, 1);
-       str def = *(str*) getArgReference(stk,pci,2);
        int i;
        char buf[BUFSIZ], *modnme, *fcnnme;
 
@@ -220,8 +224,11 @@
        if ( i != pnettop)
                        throw(MAL, "petrinet.register", "Duplicate definition 
of transition");
        pnet[pnettop].name = GDKstrdup(nme);
-       pnet[pnettop].def = GDKstrdup(def);;
-       pnet[pnettop].mb = s->def;
+       if ( pci->argc == 3)
+               pnet[pnettop].def = GDKstrdup(*(str*) 
getArgReference(stk,pci,2));
+       else
+               pnet[pnettop].def = GDKstrdup("");
+
        pnet[pnettop].status = PNwaiting;
        pnet[pnettop].cycles = 0;
        /* all the rest is zero */
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to