Changeset: d4debd62a329 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d4debd62a329 Modified Files: monetdb5/extras/jaql/Tests/variable00.mal monetdb5/extras/jaql/Tests/variable00.stable.out monetdb5/extras/jaql/jaql.c monetdb5/extras/jaql/jaqlgencode.c Branch: jacqueline Log Message:
jaql: allow array indirections Traverse arrays on request, and return their members as expected. Since this introduces the possibility to return more than one item for a single element, special care had to be taken to preserve the order as found in the arrays when returning all of their elements (x[*]). diffs (truncated from 443 to 300 lines): diff --git a/monetdb5/extras/jaql/Tests/variable00.mal b/monetdb5/extras/jaql/Tests/variable00.mal --- a/monetdb5/extras/jaql/Tests/variable00.mal +++ b/monetdb5/extras/jaql/Tests/variable00.mal @@ -4,3 +4,11 @@ jaql.x("A -> filter $ <= 2;"); jaql.x("A -> filter each v v.a >= 5;"); jaql.x("n = [ [3,65,8,72], [5,98,2,65] ];"); jaql.x("n -> expand -> transform each n (n * 2);"); +jaql.x("n -> transform each n (n[2]);"); +jaql.x("n -> transform each n (n[8]);"); +jaql.x("n -> transform each n (n[*]);"); +jaql.x("m = [ {\"a\":[3,65,{\"b\":8},72]}, {\"a\":[5,{\"b\":98},2,65]} ];"); +jaql.x("m -> transform each n (n.a[1]);"); +jaql.x("m -> transform each n (n.a[*]);"); +jaql.x("m -> transform each n (n.a[*].b);"); +jaql.x("m -> transform each n (n.a[2].b);"); diff --git a/monetdb5/extras/jaql/Tests/variable00.stable.out b/monetdb5/extras/jaql/Tests/variable00.stable.out --- a/monetdb5/extras/jaql/Tests/variable00.stable.out +++ b/monetdb5/extras/jaql/Tests/variable00.stable.out @@ -23,11 +23,26 @@ function user.main():void; jaql.x("A -> filter each v v.a >= 5;"); jaql.x("n = [ [3,65,8,72], [5,98,2,65] ];"); jaql.x("n -> expand -> transform each n (n * 2);"); + jaql.x("n -> transform each n (n[2]);"); + jaql.x("n -> transform each n (n[8]);"); + jaql.x("n -> transform each n (n[*]);"); + jaql.x("m = [ {\"a\":[3,65,{\"b\":8},72]}, {\"a\":[5,{\"b\":98},2,65]} ];"); + jaql.x("m -> transform each n (n.a[1]);"); + jaql.x("m -> transform each n (n.a[*]);"); + jaql.x("m -> transform each n (n.a[*].b);"); + jaql.x("m -> transform each n (n.a[2].b);"); end main; [ 1, 2, 4, { "a": 5 } ] [ 1, 2 ] [ { "a": 5 } ] [ 6, 130, 16, 144, 10, 196, 4, 130 ] +[ 8, 2 ] +[ null, null ] +[ 3, 65, 8, 72, 5, 98, 2, 65 ] +[ 65, { "b": 98 } ] +[ 3, 65, { "b": 8 }, 72, 5, { "b": 98 }, 2, 65 ] +[ 8, 98 ] +[ 8, null ] # 21:12:04 > # 21:12:04 > "Done." 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 @@ -218,7 +218,7 @@ make_jaql_transform(tree *var, tree *tmp return res; } - if (tmpl->type == j_var && tmpl->tval1 == NULL) { + if (tmpl->type == j_var && tmpl->tval1 == NULL && tmpl->tval2 == NULL) { /* simple variable, hence not performing any change, so null-op */ freetree(var); freetree(tmpl); 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 @@ -95,17 +95,157 @@ dumpwalkvar(MalBlkPtr mb, int j1, int j5 return a; } +/* dumps the indirection of the array lookup notation [x] or [*], + * returns a BAT with matching ids in head, and their elems id in tail */ +static int +dumparrrefvar(MalBlkPtr mb, tree *t, int elems, int j5) +{ + InstrPtr q; + int a, b, c, d; + + /* array indirection, entries must be arrays */ + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, uselectRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, elems); + q = pushBte(mb, q, 'a'); /* deref requires array */ + a = getArg(q, 0); + pushInstruction(mb, q); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, semijoinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, j5); + q = pushArgument(mb, q, a); + a = getArg(q, 0); + pushInstruction(mb, q); + + if (t->nval == -1) { + /* all array members (like expand) */ + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, batRef); + setFunctionId(q, reverseRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, a); + b = getArg(q, 0); + pushInstruction(mb, q); + } else { + /* xth array member */ + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, batRef); + setFunctionId(q, reverseRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, a); + b = getArg(q, 0); + pushInstruction(mb, q); + 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); + c = getArg(q, 0); + pushInstruction(mb, q); + + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, kuniqueRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, a); + d = getArg(q, 0); + pushInstruction(mb, q); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, putName("mark_grp", 8)); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, c); + q = pushArgument(mb, q, d); + q = pushOid(mb, q, 0); + b = getArg(q, 0); + pushInstruction(mb, q); + + 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); + d = getArg(q, 0); + pushInstruction(mb, q); + + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, selectRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, b); + q = pushOid(mb, q, (oid)t->nval); + q = pushOid(mb, q, (oid)t->nval); + b = getArg(q, 0); + pushInstruction(mb, q); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, semijoinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, c); + q = pushArgument(mb, q, b); + c = getArg(q, 0); + pushInstruction(mb, q); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, semijoinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, d); + q = pushArgument(mb, q, b); + d = getArg(q, 0); + pushInstruction(mb, q); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, batRef); + setFunctionId(q, reverseRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, d); + d = getArg(q, 0); + pushInstruction(mb, q); + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, joinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, d); + q = pushArgument(mb, q, c); + b = getArg(q, 0); + pushInstruction(mb, q); + } + + return b; +} + /* returns a bat with in the head the oid of the values (kind bat), and * in the tail, the oid of the corresponding element from elems * (typically array bat, head oid 0@0) */ static int -dumprefvar(MalBlkPtr mb, tree *t, int elems, int j1, int j6, int j7) +dumprefvar(MalBlkPtr mb, tree *t, int elems, int j1, int j5, int j6, int j7) { InstrPtr q; - int a, b; + int a, b, c; assert(t && t->type == j_var); + if (t->tval1 == NULL) { + if (t->tval2 != NULL) { + b = dumparrrefvar(mb, t->tval2, elems, j5); + } else { + /* just var, has no derefs or anything, so all */ + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, batRef); + setFunctionId(q, mirrorRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, elems); + b = getArg(q, 0); + pushInstruction(mb, q); + } + return b; + } + q = newInstruction(mb, ASSIGNsymbol); setModuleId(q, batRef); setFunctionId(q, mirrorRef); @@ -114,21 +254,8 @@ dumprefvar(MalBlkPtr mb, tree *t, int el b = getArg(q, 0); pushInstruction(mb, q); - if (t->tval1 == NULL) /* just var, has no derefs, so all */ - return b; - a = elems; for (t = t->tval1; t != NULL; t = t->tval1) { - if (a != elems) { /* retrieve kinds on multiple indirections */ - q = newInstruction(mb, ASSIGNsymbol); - setModuleId(q, algebraRef); - setFunctionId(q, semijoinRef); - q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); - q = pushArgument(mb, q, j1); - q = pushArgument(mb, q, b); - a = getArg(q, 0); - pushInstruction(mb, q); - } q = newInstruction(mb, ASSIGNsymbol); setModuleId(q, algebraRef); setFunctionId(q, uselectRef); @@ -184,6 +311,37 @@ dumprefvar(MalBlkPtr mb, tree *t, int el q = pushArgument(mb, q, a); b = getArg(q, 0); pushInstruction(mb, q); + /* retrieve kinds on multiple indirections */ + if (a != elems && (t->tval1 != NULL || t->tval2 != NULL)) { + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, semijoinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, j1); + q = pushArgument(mb, q, b); + a = getArg(q, 0); + pushInstruction(mb, q); + } + if (t->tval2 != NULL) { + c = dumparrrefvar(mb, t->tval2, a, j5); + 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); + /* re-retrieve kinds now we've updated again */ + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, semijoinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, j1); + q = pushArgument(mb, q, b); + a = getArg(q, 0); + pushInstruction(mb, q); + } } return b; } @@ -207,7 +365,7 @@ dumpcomp(MalBlkPtr mb, tree *t, int elem a = dumpvariabletransformation(mb, t->tval1, elems, j1, j2, j3, j4, j5, j6, j7); } else { - a = dumprefvar(mb, t->tval1, elems, *j1, *j6, *j7); + a = dumprefvar(mb, t->tval1, elems, *j1, *j5, *j6, *j7); } if (t->tval3->type != j_var && t->tval3->type != j_operation) { @@ -222,7 +380,7 @@ 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, *j5, *j6, *j7); c = -1; break; case j_operation: @@ -816,7 +974,7 @@ dumppredjoin(MalBlkPtr mb, json_var *js, } _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list