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

Reply via email to