Changeset: 978965bc06b6 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=978965bc06b6 Modified Files: monetdb5/extras/jaql/Tests/filter00.mal monetdb5/extras/jaql/Tests/filter00.stable.out monetdb5/extras/jaql/Tests/transform00.mal monetdb5/extras/jaql/Tests/transform00.stable.out monetdb5/extras/jaql/jaqlgencode.c monetdb5/extras/jaql/parser/jaql.y Branch: jacqueline Log Message:
filter: allow calculated values to be used in predicates A bit of reworking on the parser to more flexibly allow parenthesis and mixing of predicates with operations. diffs (truncated from 348 to 300 lines): diff --git a/monetdb5/extras/jaql/Tests/filter00.mal b/monetdb5/extras/jaql/Tests/filter00.mal --- a/monetdb5/extras/jaql/Tests/filter00.mal +++ b/monetdb5/extras/jaql/Tests/filter00.mal @@ -8,3 +8,4 @@ jaql.x("[ {\"id\":1, \"dept\":2, \"incom jaql.x("[1,2,4]->filter $ > 2;"); jaql.x("[ {\"id\":1, \"dept\":2, \"income\":12000},4,5 ] -> filter $.dept == 2;"); jaql.x("[ {\"id\":1, \"dept\":2, \"income\":12000},4,5 ] -> filter $ >= 2;"); +jaql.x("[ {\"id\":1, \"dept\":2, \"income\":12000},{\"id\":2, \"dept\":2, \"income\":13000} ] -> filter $.dept + $.id > 3;"); diff --git a/monetdb5/extras/jaql/Tests/filter00.stable.out b/monetdb5/extras/jaql/Tests/filter00.stable.out --- a/monetdb5/extras/jaql/Tests/filter00.stable.out +++ b/monetdb5/extras/jaql/Tests/filter00.stable.out @@ -27,6 +27,7 @@ function user.main():void; jaql.x("[1,2,4]->filter $ > 2;"); jaql.x("[ {\"id\":1, \"dept\":2, \"income\":12000},4,5 ] -> filter $.dept == 2;"); jaql.x("[ {\"id\":1, \"dept\":2, \"income\":12000},4,5 ] -> filter $ >= 2;"); + jaql.x("[ {\"id\":1, \"dept\":2, \"income\":12000},{\"id\":2, \"dept\":2, \"income\":13000} ] -> filter $.dept + $.id > 3;"); end main; [ { "id": 1, "dept": 1, "income": 12000 } ] [ { "id": 1, "dept": 1, "income": 12000 } ] @@ -38,6 +39,7 @@ end main; [ 4 ] [ { "id": 1, "dept": 2, "income": 12000 } ] [ 4, 5 ] +[ { "id": 2, "dept": 2, "income": 13000 } ] # 21:51:22 > diff --git a/monetdb5/extras/jaql/Tests/transform00.mal b/monetdb5/extras/jaql/Tests/transform00.mal --- a/monetdb5/extras/jaql/Tests/transform00.mal +++ b/monetdb5/extras/jaql/Tests/transform00.mal @@ -1,4 +1,5 @@ jaql.x("[1,2,3] -> transform 2 * 2;"); +jaql.x("[1,2,3] -> transform {\"value\":2 + 2};"); jaql.x("[{\"a\": 1}, {\"a\": 2.6}] -> transform $.a;"); jaql.x("[1,2.2,3] -> transform 2 * $;"); jaql.x("[{\"a\": 1}, {\"a\": 2.5}] -> transform $.a + $.a;"); diff --git a/monetdb5/extras/jaql/Tests/transform00.stable.out b/monetdb5/extras/jaql/Tests/transform00.stable.out --- a/monetdb5/extras/jaql/Tests/transform00.stable.out +++ b/monetdb5/extras/jaql/Tests/transform00.stable.out @@ -18,6 +18,7 @@ stdout of test 'transform00` in director # MonetDB/DataCell module not loaded: MALException:jaql.context:JAQL environment not found function user.main():void; jaql.x("[1,2,3] -> transform 2 * 2;"); + jaql.x("[1,2,3] -> transform {\"value\":2 + 2};"); jaql.x("[{\"a\": 1}, {\"a\": 2.6}] -> transform $.a;"); jaql.x("[1,2.2,3] -> transform 2 * $;"); jaql.x("[{\"a\": 1}, {\"a\": 2.5}] -> transform $.a + $.a;"); @@ -30,6 +31,7 @@ function user.main():void; jaql.x("[1,2,3] -> transform {\"value\":$ + $};"); end main; [ 4, 4, 4 ] +[ { "value": 4 }, { "value": 4 }, { "value": 4 } ] [ 1, 2.600000 ] [ 2, 4.400000, 6 ] [ 2, 5.000000 ] 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 @@ -21,6 +21,8 @@ #include "jaqlgencode.h" #include "opt_prelude.h" +static int dumpvariabletransformation(MalBlkPtr mb, tree *t, int elems, int *j1, int *j2, int *j3, int *j4, int *j5, int *j6, int *j7); + /* returns a bat with subset from kind bat (:oid,:chr) which are * referenced by the first array of the JSON structure (oid 0@0 of kind * bat, pointing to array, so all oids from array bat that have head oid @@ -161,20 +163,60 @@ dumprefvar(MalBlkPtr mb, tree *t, int el /* returns bat with in the head the oids from elems that match the * comparison */ static int -dumpcomp(MalBlkPtr mb, tree *t, int elems, int j1, int j2, int j3, int j4, int j6, int j7) +dumpcomp(MalBlkPtr mb, tree *t, int elems, int *j1, int *j2, int *j3, int *j4, int *j5, int *j6, int *j7) { InstrPtr q; int a, b, c, d, e, f, g; assert(t != NULL); - assert(t->tval1->type == j_var); + assert(t->tval1->type == j_var || t->tval1->type == j_operation); assert(t->tval2->type == j_comp); - assert(t->tval3->type == j_var + assert(t->tval3->type == j_var || t->tval3->type == j_operation || t->tval3->type == j_num || t->tval3->type == j_dbl || t->tval3->type == j_str || t->tval3->type == j_bool); - a = dumprefvar(mb, t->tval1, elems, j1, j6, j7); - if (t->tval3->type != j_var) { + if (t->tval1->type == j_operation) { + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, batRef); + setFunctionId(q, reverseRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, elems); + a = getArg(q, 0); + pushInstruction(mb, q); + b = dumpvariabletransformation(mb, t->tval1, a, + j1, j2, j3, j4, j5, j6, j7); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, markHRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, a); + q = pushOid(mb, q, 0); + a = getArg(q, 0); + pushInstruction(mb, q); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, markTRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, b); + q = pushOid(mb, q, 0); + b = getArg(q, 0); + pushInstruction(mb, q); + /* because transformations must leave the original count in + * tact, all elems from b originate straight from a, be it that + * they may be null now */ + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, joinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, b); + q = pushArgument(mb, q, a); + a = getArg(q, 0); + pushInstruction(mb, q); + } else { + a = dumprefvar(mb, t->tval1, elems, *j1, *j6, *j7); + } + + if (t->tval3->type != j_var && t->tval3->type != j_operation) { q = newInstruction(mb, ASSIGNsymbol); setModuleId(q, batRef); setFunctionId(q, reverseRef); @@ -186,7 +228,46 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem switch (t->tval3->type) { case j_var: - b = dumprefvar(mb, t->tval3, elems, j1, j6, j7); + b = dumprefvar(mb, t->tval3, elems, *j1, *j6, *j7); + c = -1; + break; + case j_operation: + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, batRef); + setFunctionId(q, reverseRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, elems); + b = getArg(q, 0); + pushInstruction(mb, q); + c = dumpvariabletransformation(mb, t->tval1, b, + j1, j2, j3, j4, j5, j6, j7); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, markHRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, b); + q = pushOid(mb, q, 0); + b = getArg(q, 0); + pushInstruction(mb, q); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, markTRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, c); + q = pushOid(mb, q, 0); + c = getArg(q, 0); + pushInstruction(mb, q); + /* because transformations must leave the original count in + * tact, all elems from c originate straight from b, be it that + * they may be null now */ + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, joinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, c); + q = pushArgument(mb, q, b); + b = getArg(q, 0); + pushInstruction(mb, q); c = -1; break; case j_num: @@ -195,7 +276,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem setFunctionId(q, joinRef); q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); q = pushArgument(mb, q, a); - q = pushArgument(mb, q, j3); + q = pushArgument(mb, q, *j3); b = getArg(q, 0); pushInstruction(mb, q); q = newInstruction(mb, ASSIGNsymbol); @@ -210,7 +291,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem setFunctionId(q, joinRef); q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); q = pushArgument(mb, q, a); - q = pushArgument(mb, q, j4); + q = pushArgument(mb, q, *j4); b = getArg(q, 0); pushInstruction(mb, q); q = newInstruction(mb, ASSIGNsymbol); @@ -225,7 +306,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem setFunctionId(q, joinRef); q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); q = pushArgument(mb, q, a); - q = pushArgument(mb, q, j2); + q = pushArgument(mb, q, *j2); b = getArg(q, 0); pushInstruction(mb, q); q = newInstruction(mb, ASSIGNsymbol); @@ -240,7 +321,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem setFunctionId(q, joinRef); q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); q = pushArgument(mb, q, a); - q = pushArgument(mb, q, j1); + q = pushArgument(mb, q, *j1); b = getArg(q, 0); pushInstruction(mb, q); q = newInstruction(mb, ASSIGNsymbol); @@ -338,7 +419,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem assert(0); } } else { /* var <cmp> var */ - int lv[4] = {j2, j3, j4, 0}, *lp = lv; + int lv[4] = {*j2, *j3, *j4, 0}, *lp = lv; /* FIXME: we need to check that a and b have at most one value * per elem here, further code assumes that, because its * semantically unclear what one should do with multiple values @@ -372,7 +453,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem setModuleId(q, algebraRef); setFunctionId(q, semijoinRef); q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); - q = pushArgument(mb, q, j1); + q = pushArgument(mb, q, *j1); q = pushArgument(mb, q, c); c = getArg(q, 0); pushInstruction(mb, q); @@ -396,7 +477,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem setModuleId(q, algebraRef); setFunctionId(q, semijoinRef); q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); - q = pushArgument(mb, q, j1); + q = pushArgument(mb, q, *j1); q = pushArgument(mb, q, d); d = getArg(q, 0); pushInstruction(mb, q); @@ -664,7 +745,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem } static int -dumppred(MalBlkPtr mb, tree *t, int elems, int j1, int j2, int j3, int j4, int j6, int j7) +dumppred(MalBlkPtr mb, tree *t, int elems, int *j1, int *j2, int *j3, int *j4, int *j5, int *j6, int *j7) { int a, l, r; InstrPtr q; @@ -674,14 +755,14 @@ dumppred(MalBlkPtr mb, tree *t, int elem /* comparisons only take place between tval1 = var and tval3 = val/var * for the rest, only boolean logic is applied */ if (t->tval2->cval != j_and && t->tval2->cval != j_or) - return dumpcomp(mb, t, elems, j1, j2, j3, j4, j6, j7); + return dumpcomp(mb, t, elems, j1, j2, j3, j4, j5, j6, j7); assert(t->tval1->type == j_pred); assert(t->tval2->cval == j_and || t->tval2->cval == j_or); assert(t->tval3->type == j_pred); - l = dumppred(mb, t->tval1, elems, j1, j2, j3, j4, j6, j7); - r = dumppred(mb, t->tval3, elems, j1, j2, j3, j4, j6, j7); + l = dumppred(mb, t->tval1, elems, j1, j2, j3, j4, j5, j6, j7); + r = dumppred(mb, t->tval3, elems, j1, j2, j3, j4, j5, j6, j7); /* l,r = oid from elems that match in head */ if (t->tval2->cval == j_and) { @@ -753,7 +834,7 @@ dumpnextid(MalBlkPtr mb, int j1) return a; } -/* returns a BAT which is the subset of j1 that refer to the values +/* returns a BAT which is the subset of j1 that refers to the values * returned from the variable and its optional calculation applied to it * the j{1..7} variables are updated to point to the updated BATs as * insertions of new values (the serialised versions of the variable) */ @@ -844,7 +925,7 @@ dumpvariabletransformation(MalBlkPtr mb, pushInstruction(mb, q); return c; - case j_var: { + case j_var: q = newInstruction(mb, ASSIGNsymbol); setModuleId(q, batRef); setFunctionId(q, reverseRef); @@ -872,7 +953,6 @@ dumpvariabletransformation(MalBlkPtr mb, pushInstruction(mb, q); return c; - } case j_operation: { int r, s; int u, v; @@ -1754,7 +1834,7 @@ dumptree(jc *j, MalBlkPtr mb, tree *t) break; case j_filter: _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list