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