Changeset: fb2c7ba018bf for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fb2c7ba018bf
Modified Files:
        monetdb5/extras/jaql/jaqlfunc.mal
        monetdb5/extras/jaql/jaqlgencode.c
Branch: jacqueline
Log Message:

funcs: check MAL function signature to match JAQL call

prepare for calling non-native functions by allowing to wrap


diffs (truncated from 314 to 300 lines):

diff --git a/monetdb5/extras/jaql/jaqlfunc.mal 
b/monetdb5/extras/jaql/jaqlfunc.mal
--- a/monetdb5/extras/jaql/jaqlfunc.mal
+++ b/monetdb5/extras/jaql/jaqlfunc.mal
@@ -115,40 +115,25 @@ function arrayToRecord(kindn:bat[:oid,:b
        return (r1,r2,r3,r4,r5,r6,r7);
 end arrayToRecord;
 
+# these are groupable functions, they receive their input as :oid,:any_1
+# and return the per :oid group result as :oid,:any_2
+
 # perform sum over the input array
-function 
sum(kindn:bat[:oid,:bte],stringn:bat[:oid,:str],integern:bat[:oid,:lng],doublen:bat[:oid,:dbl],arrayn:bat[:oid,:oid],objectn:bat[:oid,:oid],namen:bat[:oid,:str])(kind:bat[:oid,:bte],string:bat[:oid,:str],integer:bat[:oid,:lng],double:bat[:oid,:dbl],array:bat[:oid,:oid],object:bat[:oid,:oid],name:bat[:oid,:str]);
-       # expect an array of ints or dbls
-       e1 := algebra.selectH(arrayn, 0@0);
-       e2 := bat.reverse(e1);
+function sum(v:bat[:oid,:lng]):bat[:oid,:lng];
+       k := algebra.kunique(v);
+       r:bat[:oid,:lng] := aggr.sum(v, k);
+       return r;
+end sum;
+function sum(v:bat[:oid,:dbl]):bat[:oid,:dbl];
+       k := algebra.kunique(v);
+       r:bat[:oid,:dbl] := aggr.sum(v, k);
+       return r;
+end sum;
 
-       i1 := algebra.semijoin(kindn, e2);
-       i2 := algebra.select(i1, 105:bte); # i
-       i3 := algebra.semijoin(integern, i2);
-
-       d2 := algebra.select(i1, 100:bte); # d
-       d3 := algebra.semijoin(doublen, d2);
-       d4 := aggr.count(d3);
-
-       r1 := bat.new(:oid,:bte);
-       r2 := bat.new(:oid,:str);
-       r3 := bat.new(:oid,:lng);
-       r4 := bat.new(:oid,:dbl);
-       r5 := bat.new(:oid,:oid);
-       r6 := bat.new(:oid,:oid);
-       r7 := bat.new(:oid,:str);
-
-       s1 := aggr.sum(i3);
-       barrier hd := calc.>(d4, 0);
-               s2 := aggr.sum(d3);
-               s4 := calc.+(s1, s2);
-               r1 := bat.insert(r1, 0@0, 100:bte); # d
-               r4 := bat.insert(r4, 0@0, s4);
-       exit hd;
-       barrier nd := calc.==(d4, 0);
-               s3 := calc.lng(s1);
-               r1 := bat.insert(r1, 0@0, 105:bte); # i
-               r3 := bat.insert(r3, 0@0, s3);
-       exit nd;
-
-       return (r1,r2,r3,r4,r5,r6,r7);
-end sum;
+# perform count over the input array
+function count(v:bat[:oid,:any]):bat[:oid,:lng];
+       k := algebra.kunique(v);
+       x := aggr.count(v, k, false);
+       r := batcalc.lng(x);
+       return r;
+end count;
diff --git a/monetdb5/extras/jaql/jaqlgencode.c 
b/monetdb5/extras/jaql/jaqlgencode.c
--- a/monetdb5/extras/jaql/jaqlgencode.c
+++ b/monetdb5/extras/jaql/jaqlgencode.c
@@ -4081,6 +4081,11 @@ dumptree(jc *j, Client cntxt, MalBlkPtr 
                        case j_func: {
                                tree *w;
                                Symbol s;
+                               InstrPtr f;
+#define MAXJAQLARG 23
+                               enum treetype coltypes[MAXJAQLARG + 1];
+                               int coltpos = 0;
+                               int i;
 
                                /* lookup the function we need */
                                s = findSymbol(cntxt->nspace,
@@ -4092,10 +4097,113 @@ dumptree(jc *j, Client cntxt, MalBlkPtr 
                                        break;
                                }
 
+                               if (j1 != 0) {
+                                       /* treat pipe as first input of type 
json array */
+                                       coltypes[coltpos++] = j_json_arr;
+                               }
+                               /* check what arguments were provided */
+                               for (w = t->tval1; w != NULL; w = w->next) {
+                                       assert(w->type == j_func_arg);
+                                       assert(w->tval1 != NULL);
+
+                                       if (coltpos > MAXJAQLARG) {
+                                               snprintf(j->err, 
sizeof(j->err), "too many arguments");
+                                               break;
+                                       }
+
+                                       switch (w->tval1->type) {
+                                               case j_str:
+                                               case j_num:
+                                               case j_dbl:
+                                               case j_bool:
+                                               case j_var:
+                                                       coltypes[coltpos++] = 
w->tval1->type;
+                                                       break;
+                                               case j_json:
+                                                       if (*w->tval1->sval == 
'[') {
+                                                               
coltypes[coltpos++] = j_json;
+                                                       } else { /* must be '{' 
*/
+                                                               
coltypes[coltpos++] = j_str;
+                                                       }
+                                                       break;
+                                               default:
+                                                       snprintf(j->err, 
sizeof(j->err),
+                                                                       
"unhandled argument type (1)");
+                                                       break;
+                                       }
+                               }
+                               if (j->err[0] != '\0')
+                                       break;
+
                                do {
                                        if (idcmp(s->name, t->sval) == 0) {
-                                               InstrPtr f = getSignature(s);
-                                               if (f->retc == 7)
+                                               char match = 0;
+                                               int itype;
+                                               int argoff = 0;
+
+                                               /* Function resolution is done 
based on the
+                                                * input arguments only; we 
cannot consider the
+                                                * return type, because we 
don't know what is
+                                                * expected from us.  We go by 
the assumption
+                                                * here that functions are 
constructed in such a
+                                                * way that their return value 
is not considered
+                                                * while looking for their 
uniqueness (like in
+                                                * Java). */
+                                               f = getSignature(s);
+                                               for (i = 0; i < coltpos; i++) {
+                                                       match = 0;
+                                                       if (f->argc - f->retc - 
argoff < 1)
+                                                               break;
+                                                       itype = 
getArgType(s->def, f, f->retc + argoff);
+                                                       if (!isaBatType(itype) 
||
+                                                                       
getHeadType(itype) != TYPE_oid)
+                                                               break;
+                                                       switch (coltypes[i]) {
+                                                               case j_json:
+                                                               case j_json_arr:
+                                                                       if 
(f->argc - f->retc - argoff < 7)
+                                                                               
break;
+                                                                       /* out 
of laziness, we only check
+                                                                        * the 
first argument to be a bat,
+                                                                        * and 
of the right type */
+                                                                       if 
(getTailType(itype) != TYPE_bte)
+                                                                               
break;
+                                                                       match = 
1;
+                                                                       argoff 
+= 7;
+                                                                       break;
+                                                               case j_str:
+                                                                       if 
(getTailType(itype) == TYPE_str)
+                                                                               
match = 1;
+                                                                       argoff 
+= 1;
+                                                                       break;
+                                                               case j_num:
+                                                                       if 
(getTailType(itype) == TYPE_lng)
+                                                                               
match = 1;
+                                                                       argoff 
+= 1;
+                                                                       break;
+                                                               case j_dbl:
+                                                                       if 
(getTailType(itype) == TYPE_dbl)
+                                                                               
match = 1;
+                                                                       argoff 
+= 1;
+                                                                       break;
+                                                               case j_bool:
+                                                                       if 
(getTailType(itype) == TYPE_bit)
+                                                                               
match = 1;
+                                                                       argoff 
+= 1;
+                                                                       break;
+                                                               case j_var:
+                                                                       /* 
assume ok, since we found a BAT
+                                                                        * 
argument in place already */
+                                                                       match = 
1;
+                                                                       argoff 
+= 1;
+                                                                       break;
+                                                               default:
+                                                                       
assert(0);
+                                                       }
+                                                       if (match == 0)
+                                                               break;
+                                               }
+                                               if (match == 1 && f->argc - 
f->retc - argoff == 0)
                                                        break;
                                        }
                                        s = s->peer;
@@ -4109,15 +4217,24 @@ dumptree(jc *j, Client cntxt, MalBlkPtr 
                                q = newInstruction(mb, ASSIGNsymbol);
                                setModuleId(q, putName("jaqlfunc", 8));
                                setFunctionId(q, putName(t->sval, 
strlen(t->sval)));
-                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
+                               if (f->retc == 7) {
+                                       q = pushReturn(mb, q, 
newTmpVariable(mb, TYPE_any));
+                                       q = pushReturn(mb, q, 
newTmpVariable(mb, TYPE_any));
+                                       q = pushReturn(mb, q, 
newTmpVariable(mb, TYPE_any));
+                                       q = pushReturn(mb, q, 
newTmpVariable(mb, TYPE_any));
+                                       q = pushReturn(mb, q, 
newTmpVariable(mb, TYPE_any));
+                                       q = pushReturn(mb, q, 
newTmpVariable(mb, TYPE_any));
+                                       q = pushReturn(mb, q, 
newTmpVariable(mb, TYPE_any));
+                               } else if (f->retc == 1 && 
isaBatType(getArgType(s->def, f, 0))) {
+                                       q = pushReturn(mb, q, 
newTmpVariable(mb, TYPE_any));
+                               } else {
+                                       snprintf(j->err, sizeof(j->err), " 
function return type"
+                                                       "unhandled for: %s", 
t->sval);
+                                       break;
+                               }
                                if (j1 != 0) {
-                                       /* treat pipe as first input */
+                                       /* treat pipe as first input, signature 
check above
+                                        * should guarantee this is ok */
                                        q = pushArgument(mb, q, j1);
                                        q = pushArgument(mb, q, j2);
                                        q = pushArgument(mb, q, j3);
@@ -4128,7 +4245,6 @@ dumptree(jc *j, Client cntxt, MalBlkPtr 
                                }
                                for (w = t->tval1; w != NULL; w = w->next) {
                                        int a1, a2, a3, a4, a5, a6, a7;
-                                       char buf[64];
 
                                        assert(w->type == j_func_arg);
                                        assert(w->tval1 != NULL);
@@ -4136,49 +4252,51 @@ dumptree(jc *j, Client cntxt, MalBlkPtr 
                                        /* transform the argument in a json 
struct (7 BATs)
                                         * if not already */
                                        switch (w->tval1->type) {
-                                               case j_str:
                                                case j_json:
                                                        dumpjsonshred(mb, 
w->tval1->sval,
                                                                        &a1, 
&a2, &a3, &a4, &a5, &a6, &a7);
+                                                       q = pushArgument(mb, q, 
a1);
+                                                       q = pushArgument(mb, q, 
a2);
+                                                       q = pushArgument(mb, q, 
a3);
+                                                       q = pushArgument(mb, q, 
a4);
+                                                       q = pushArgument(mb, q, 
a5);
+                                                       q = pushArgument(mb, q, 
a6);
+                                                       q = pushArgument(mb, q, 
a7);
+                                                       break;
+                                               case j_str:
+                                                       q = pushStr(mb, q, 
w->tval1->sval);
                                                        break;
                                                case j_num:
-                                                       snprintf(buf, 
sizeof(buf), "%lld", w->tval1->nval);
-                                                       dumpjsonshred(mb, buf,
-                                                                       &a1, 
&a2, &a3, &a4, &a5, &a6, &a7);
+                                                       q = pushLng(mb, q, 
w->tval1->nval);
                                                        break;
                                                case j_dbl:
-                                                       snprintf(buf, 
sizeof(buf), "%f", w->tval1->dval);
-                                                       dumpjsonshred(mb, buf,
-                                                                       &a1, 
&a2, &a3, &a4, &a5, &a6, &a7);
+                                                       q = pushDbl(mb, q, 
w->tval1->dval);
                                                        break;
                                                case j_bool:
-                                                       snprintf(buf, 
sizeof(buf), "%s",
-                                                                       
w->tval1->nval == 1 ? "true" : "false");
-                                                       dumpjsonshred(mb, buf,
-                                                                       &a1, 
&a2, &a3, &a4, &a5, &a6, &a7);
+                                                       q = pushBit(mb, q, 
w->tval1->nval == 1);
                                                        break;
                                                case j_var: /* TODO */
+                                                       /* j_var is actually 
impossible at this level */
                                                default:
                                                        snprintf(j->err, 
sizeof(j->err),
                                                                        
"unhandled argument type (1)");
                                                        return -1;
                                        }
-
-                                       q = pushArgument(mb, q, a1);
-                                       q = pushArgument(mb, q, a2);
-                                       q = pushArgument(mb, q, a3);
-                                       q = pushArgument(mb, q, a4);
-                                       q = pushArgument(mb, q, a5);
-                                       q = pushArgument(mb, q, a6);
-                                       q = pushArgument(mb, q, a7);
                                }
-                               j1 = getArg(q, 0);
-                               j2 = getArg(q, 1);
-                               j3 = getArg(q, 2);
-                               j4 = getArg(q, 3);
-                               j5 = getArg(q, 4);
-                               j6 = getArg(q, 5);
-                               j7 = getArg(q, 6);
+                               if (f->retc == 7) {
+                                       j1 = getArg(q, 0);
+                                       j2 = getArg(q, 1);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to