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

join: implemented preserve

Use outerjoins to keep original elements from input vars to implement
the preserve clause.


diffs (truncated from 349 to 300 lines):

diff --git a/monetdb5/extras/jaql/Tests/join00.mal 
b/monetdb5/extras/jaql/Tests/join00.mal
--- a/monetdb5/extras/jaql/Tests/join00.mal
+++ b/monetdb5/extras/jaql/Tests/join00.mal
@@ -3,6 +3,5 @@ jaql.x("pages = [ {\"userid\": 1, \"url\
 
 jaql.x("join users, pages where users.id == pages.userid into {users.name, 
pages.url};");
 jaql.x("join u in users, p in pages where u.id == p.userid into {u.name, 
p.url};");
-# TODO: preserve
-#jaql.x("join preserve u in users, p in pages where u.id == p.userid into 
{u.name, p.url};");
+jaql.x("join preserve u in users, p in pages where u.id == p.userid into 
{u.name, p.url};");
 
diff --git a/monetdb5/extras/jaql/Tests/join00.stable.out 
b/monetdb5/extras/jaql/Tests/join00.stable.out
--- a/monetdb5/extras/jaql/Tests/join00.stable.out
+++ b/monetdb5/extras/jaql/Tests/join00.stable.out
@@ -21,11 +21,11 @@ function user.main():void;
     jaql.x("pages = [ {\"userid\": 1, \"url\":\"code.google.com/p/jaql/\"}, 
{\"userid\": 2, \"url\":\"www.cnn.com\"}, {\"userid\": 1, 
\"url\":\"java.sun.com/javase/6/docs/api/\"} ];");
     jaql.x("join users, pages where users.id == pages.userid into {users.name, 
pages.url};");
     jaql.x("join u in users, p in pages where u.id == p.userid into {u.name, 
p.url};");
-# TODO: preserve 
-#jaql.x("join preserve u in users, p in pages where u.id == p.userid into 
{u.name, p.url};"); 
+    jaql.x("join preserve u in users, p in pages where u.id == p.userid into 
{u.name, p.url};");
 end main;
 [ { "name": "Jon Doe", "url": "java.sun.com/javase/6/docs/api/" }, { "name": 
"Jon Doe", "url": "code.google.com/p/jaql/" }, { "name": "Jane Doe", "url": 
"www.cnn.com" } ]
 [ { "name": "Jon Doe", "url": "java.sun.com/javase/6/docs/api/" }, { "name": 
"Jon Doe", "url": "code.google.com/p/jaql/" }, { "name": "Jane Doe", "url": 
"www.cnn.com" } ]
+[ { "name": "Jon Doe", "url": "java.sun.com/javase/6/docs/api/" }, { "name": 
"Jon Doe", "url": "code.google.com/p/jaql/" }, { "name": "Jane Doe", "url": 
"www.cnn.com" }, { "name": "Max Mustermann" } ]
 
 # 17:33:31 >  
 # 17:33:31 >  "Done."
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
@@ -899,8 +899,64 @@ dumppredjoin(MalBlkPtr mb, json_var *js,
                q = pushArgument(mb, q, b);
                a = getArg(q, 0);
                pushInstruction(mb, q);
+               /* a now contains matching oids in head l, in tail r */
 
-               /* a now contains matching oids in head l, in tail r */
+               if (ljv->preserve == 1) {
+                       q = newInstruction(mb, ASSIGNsymbol);
+                       setModuleId(q, batRef);
+                       setFunctionId(q, mirrorRef);
+                       q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
+                       q = pushArgument(mb, q, d);
+                       l = getArg(q, 0);
+                       pushInstruction(mb, q);
+                       q = newInstruction(mb, ASSIGNsymbol);
+                       setModuleId(q, algebraRef);
+                       setFunctionId(q, putName("outerjoin", 9));
+                       q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
+                       q = pushArgument(mb, q, l);
+                       q = pushArgument(mb, q, a);
+                       a = getArg(q, 0);
+                       pushInstruction(mb, q);
+               }
+               if (rjv->preserve == 1) {
+                       q = newInstruction(mb, ASSIGNsymbol);
+                       setModuleId(q, batRef);
+                       setFunctionId(q, reverseRef);
+                       q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
+                       q = pushArgument(mb, q, r);
+                       r = getArg(q, 0);
+                       pushInstruction(mb, q);
+                       q = newInstruction(mb, ASSIGNsymbol);
+                       setModuleId(q, batRef);
+                       setFunctionId(q, mirrorRef);
+                       q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
+                       q = pushArgument(mb, q, r);
+                       r = 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, a);
+                       a = getArg(q, 0);
+                       pushInstruction(mb, q);
+                       q = newInstruction(mb, ASSIGNsymbol);
+                       setModuleId(q, algebraRef);
+                       setFunctionId(q, putName("outerjoin", 9));
+                       q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
+                       q = pushArgument(mb, q, r);
+                       q = pushArgument(mb, q, a);
+                       a = 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, a);
+                       a = getArg(q, 0);
+                       pushInstruction(mb, q);
+               }
+
                if (jrs == NULL) {
                        jrw = jrs = GDKzalloc(sizeof(join_result));
                } else {
@@ -914,141 +970,157 @@ dumppredjoin(MalBlkPtr mb, json_var *js,
        /* intersect the joins */
        for (jrw = jrs; jrw != NULL; jrw = jrw->next) {
                join_result *jrv;
+               char pw = jrw->headvar->preserve | jrw->tailvar->preserve;
+               char pv;
+               char revw;
+               char revv;
                for (jrv = jrw->next; jrv != NULL; jrv = jrv->next) {
+                       pv = jrv->headvar->preserve | jrv->tailvar->preserve;
                        if (jrw->headvar == jrv->headvar) {
                                /* head-on-head */
+                               revw = revv = 0;
+                       } else if (jrw->headvar == jrv->tailvar) {
+                               /* head-on-tail */
+                               revw = 0;
+                               revv = 1;
+                       } else if (jrw->tailvar == jrv->headvar) {
+                               /* tail-on-head */
+                               revw = 1;
+                               revv = 0;
+                       } else if (jrw->tailvar == jrv->tailvar) {
+                               /* tail-on-tail */
+                               revw = revv = 1;
+                       }
+
+                       if (revw == 1) {
+                               q = newInstruction(mb, ASSIGNsymbol);
+                               setModuleId(q, batRef);
+                               setFunctionId(q, reverseRef);
+                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
+                               q = pushArgument(mb, q, jrw->bat);
+                               l = getArg(q, 0);
+                               pushInstruction(mb, q);
+                       } else {
+                               l = jrw->bat;
+                       }
+                       if (revv == 1) {
+                               q = newInstruction(mb, ASSIGNsymbol);
+                               setModuleId(q, batRef);
+                               setFunctionId(q, reverseRef);
+                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
+                               q = pushArgument(mb, q, jrv->bat);
+                               r = getArg(q, 0);
+                               pushInstruction(mb, q);
+                       } else {
+                               r = jrv->bat;
+                       }
+
+                       if (pw == 0 && pv == 0) {
+                               /* simple semi-join (kintersect) is sufficient 
*/
                                q = newInstruction(mb, ASSIGNsymbol);
                                setModuleId(q, algebraRef);
                                setFunctionId(q, semijoinRef);
                                q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushArgument(mb, q, jrw->bat);
-                               q = pushArgument(mb, q, jrv->bat);
-                               jrw->bat = getArg(q, 0);
+                               q = pushArgument(mb, q, l);
+                               q = pushArgument(mb, q, r);
+                               l = 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, jrv->bat);
-                               q = pushArgument(mb, q, jrw->bat);
-                               jrv->bat = getArg(q, 0);
+                               q = pushArgument(mb, q, r);
+                               q = pushArgument(mb, q, l);
+                               r = getArg(q, 0);
                                pushInstruction(mb, q);
-                       } else if (jrw->headvar == jrv->tailvar) {
-                               /* head-on-tail */
+                       } else if (pw == 1 && pv == 0) {
                                q = newInstruction(mb, ASSIGNsymbol);
                                setModuleId(q, batRef);
-                               setFunctionId(q, reverseRef);
+                               setFunctionId(q, mirrorRef);
                                q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushArgument(mb, q, jrv->bat);
+                               q = pushArgument(mb, q, l);
+                               b = getArg(q, 0);
+                               pushInstruction(mb, q);
+                               q = newInstruction(mb, ASSIGNsymbol);
+                               setModuleId(q, algebraRef);
+                               setFunctionId(q, putName("outerjoin", 9));
+                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
+                               q = pushArgument(mb, q, b);
+                               q = pushArgument(mb, q, r);
+                               r = getArg(q, 0);
+                               pushInstruction(mb, q);
+                       } else if (pw == 0 && pv == 1) {
+                               q = newInstruction(mb, ASSIGNsymbol);
+                               setModuleId(q, batRef);
+                               setFunctionId(q, mirrorRef);
+                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
+                               q = pushArgument(mb, q, r);
+                               b = getArg(q, 0);
+                               pushInstruction(mb, q);
+                               q = newInstruction(mb, ASSIGNsymbol);
+                               setModuleId(q, algebraRef);
+                               setFunctionId(q, putName("outerjoin", 9));
+                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
+                               q = pushArgument(mb, q, b);
+                               q = pushArgument(mb, q, l);
+                               l = getArg(q, 0);
+                               pushInstruction(mb, q);
+                       } else if (pw == 1 && pv == 1) {
+                               q = newInstruction(mb, ASSIGNsymbol);
+                               setModuleId(q, batRef);
+                               setFunctionId(q, mirrorRef);
+                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
+                               q = pushArgument(mb, q, l);
+                               b = getArg(q, 0);
+                               pushInstruction(mb, q);
+                               q = newInstruction(mb, ASSIGNsymbol);
+                               setModuleId(q, algebraRef);
+                               setFunctionId(q, putName("outerjoin", 9));
+                               q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
+                               q = pushArgument(mb, q, b);
+                               q = pushArgument(mb, q, r);
                                b = getArg(q, 0);
                                pushInstruction(mb, q);
 
                                q = newInstruction(mb, ASSIGNsymbol);
                                setModuleId(q, algebraRef);
-                               setFunctionId(q, semijoinRef);
+                               setFunctionId(q, putName("sdifference", 11));
                                q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushArgument(mb, q, jrw->bat);
+                               q = pushArgument(mb, q, r);
                                q = pushArgument(mb, q, b);
-                               jrw->bat = getArg(q, 0);
+                               c = getArg(q, 0);
                                pushInstruction(mb, q);
                                q = newInstruction(mb, ASSIGNsymbol);
                                setModuleId(q, algebraRef);
-                               setFunctionId(q, semijoinRef);
+                               setFunctionId(q, putName("sunion", 6));
                                q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
                                q = pushArgument(mb, q, b);
-                               q = pushArgument(mb, q, jrw->bat);
-                               b = getArg(q, 0);
+                               q = pushArgument(mb, q, c);
+                               r = getArg(q, 0);
                                pushInstruction(mb, q);
+                       }
 
+                       if (revw == 1) {
                                q = newInstruction(mb, ASSIGNsymbol);
                                setModuleId(q, batRef);
                                setFunctionId(q, reverseRef);
                                q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushArgument(mb, q, b);
-                               jrv->bat = getArg(q, 0);
+                               q = pushArgument(mb, q, l);
+                               jrw->bat = getArg(q, 0);
                                pushInstruction(mb, q);
-                       } else if (jrw->tailvar == jrv->headvar) {
-                               /* tail-on-head */
+                       } else {
+                               jrw->bat = l;
+                       }
+                       if (revv == 1) {
                                q = newInstruction(mb, ASSIGNsymbol);
                                setModuleId(q, batRef);
                                setFunctionId(q, reverseRef);
                                q = pushReturn(mb, q, newTmpVariable(mb, 
TYPE_any));
-                               q = pushArgument(mb, q, jrw->bat);
-                               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, b);
-                               q = pushArgument(mb, q, jrv->bat);
-                               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, jrv->bat);
-                               q = pushArgument(mb, q, b);
+                               q = pushArgument(mb, q, r);
                                jrv->bat = 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, b);
-                               jrw->bat = getArg(q, 0);
-                               pushInstruction(mb, q);
-                       } else if (jrw->tailvar == jrv->tailvar) {
-                               /* tail-on-tail */
-                               q = newInstruction(mb, ASSIGNsymbol);
-                               setModuleId(q, batRef);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to