Changeset: 25cab92cea19 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=25cab92cea19 Modified Files: monetdb5/extras/jaql/jaqlgencode.c monetdb5/extras/jaql/json.c monetdb5/extras/jaql/json.mal Branch: jacqueline Log Message:
unwraptype: merge with unwrap
The code of unwraptype and unwrap is too similar, and will get more
complex in the future, so reuse is desired. Merge both into one
function, with the help of some (MAL) pattern tricks.
diffs (truncated from 348 to 300 lines):
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
@@ -3212,7 +3212,57 @@ dumpvariabletransformation(jc *j, Client
dynaarg[i][6] =
getArg(q, 6);
pushInstruction(mb, q);
break;
- case j_sort_arg:
+ case j_sort_arg: /*
bat[:oid,:num] */
+ /* check that b
consists of arrays */
+ 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);
+ c = getArg(q,
0);
+
pushInstruction(mb, q);
+ q =
newInstruction(mb, ASSIGNsymbol);
+ setModuleId(q,
algebraRef);
+
setFunctionId(q, putName("antiuselect", 11));
+ q =
pushReturn(mb, q,
+
newTmpVariable(mb, TYPE_any));
+ q =
pushArgument(mb, q, c);
+ q = pushBte(mb,
q, 'a');
+ c = getArg(q,
0);
+
pushInstruction(mb, q);
+ q =
newInstruction(mb, ASSIGNsymbol);
+ setModuleId(q,
aggrRef);
+
setFunctionId(q, countRef);
+ q =
pushReturn(mb, q,
+
newTmpVariable(mb, TYPE_any));
+ q =
pushArgument(mb, q, c);
+ c = getArg(q,
0);
+
pushInstruction(mb, q);
+ q =
newInstruction(mb, ASSIGNsymbol);
+ setModuleId(q,
calcRef);
+
setFunctionId(q, putName("!=", 2));
+ q->barrier =
BARRIERsymbol;
+ q =
pushReturn(mb, q,
+
newTmpVariable(mb, TYPE_any));
+ q =
pushArgument(mb, q, c);
+ q = pushWrd(mb,
q, 0);
+ c = getArg(q,
0);
+
pushInstruction(mb, q);
+ q =
newInstruction(mb, ASSIGNsymbol);
+ setModuleId(q,
languageRef);
+
setFunctionId(q, putName("raise", 5));
+ q =
pushReturn(mb, q,
+
newTmpVariable(mb, TYPE_any));
+ q = pushStr(mb,
q,
+
"function requires array argument");
+
pushInstruction(mb, q);
+ q =
newAssignment(mb);
+ getArg(q, 0) =
c;
+ q->argc =
q->retc = 1;
+ q->barrier =
EXITsymbol;
+
q =
newInstruction(mb, ASSIGNsymbol);
setModuleId(q,
batRef);
setFunctionId(q, newRef);
@@ -5071,7 +5121,77 @@ dumptree(jc *j, Client cntxt, MalBlkPtr
assert(t->tval1 == NULL ||
(t->tval1->next == NULL
&& t->tval1->tval1 == NULL));
w = t->tval1;
- if (w == NULL) { /* simple "into" query
*/
+ if (w == NULL) {
+ /* simple "into" query:
equivalent of a single group */
+ q = newInstruction(mb,
ASSIGNsymbol);
+ setModuleId(q, algebraRef);
+ setFunctionId(q,
putName("selectH", 7));
+ q = pushReturn(mb, q,
newTmpVariable(mb, TYPE_any));
+ q = pushArgument(mb, q, j5);
+ q = pushOid(mb, q, (oid)0);
+ a = getArg(q, 0);
+ pushInstruction(mb, q);
+ q = newInstruction(mb,
ASSIGNsymbol);
+ setModuleId(q, algebraRef);
+ setFunctionId(q,
putName("kdifference", 11));
+ q = pushReturn(mb, q,
newTmpVariable(mb, TYPE_any));
+ q = pushArgument(mb, q, j5);
+ q = pushArgument(mb, q, a);
+ j5 = getArg(q, 0);
+ pushInstruction(mb, q);
+ b = dumpnextid(mb, j1);
+ q = newInstruction(mb,
ASSIGNsymbol);
+ setModuleId(q, algebraRef);
+ setFunctionId(q, projectRef);
+ q = pushReturn(mb, q,
newTmpVariable(mb, TYPE_any));
+ q = pushOid(mb, q, b);
+ q = pushArgument(mb, q, a);
+ a = getArg(q, 0);
+ pushInstruction(mb, q);
+ q = newInstruction(mb,
ASSIGNsymbol);
+ setModuleId(q, batRef);
+ setFunctionId(q, insertRef);
+ q = pushReturn(mb, q,
newTmpVariable(mb, TYPE_any));
+ q = pushArgument(mb, q, a);
+ q = pushOid(mb, q, (oid)0);
+ q = pushArgument(mb, q, b);
+ a = getArg(q, 0);
+ pushInstruction(mb, q);
+ q = newInstruction(mb,
ASSIGNsymbol);
+ setModuleId(q, batRef);
+ setFunctionId(q, insertRef);
+ q = pushReturn(mb, q,
newTmpVariable(mb, TYPE_any));
+ q = pushArgument(mb, q, a);
+ q = pushArgument(mb, q, j5);
+ j5 = getArg(q, 0);
+ pushInstruction(mb, q);
+
+ q = newInstruction(mb,
ASSIGNsymbol);
+ setModuleId(q, batRef);
+ setFunctionId(q, newRef);
+ q = pushReturn(mb, q,
newTmpVariable(mb, TYPE_any));
+ q = pushType(mb, q, TYPE_oid);
+ q = pushType(mb, q, TYPE_bte);
+ c = getArg(q, 0);
+ pushInstruction(mb, q);
+ q = newInstruction(mb,
ASSIGNsymbol);
+ setModuleId(q, batRef);
+ setFunctionId(q, insertRef);
+ q = pushReturn(mb, q,
newTmpVariable(mb, TYPE_any));
+ q = pushArgument(mb, q, c);
+ q = pushArgument(mb, q, j1);
+ j1 = getArg(q, 0);
+ pushInstruction(mb, q);
+ q = newInstruction(mb,
ASSIGNsymbol);
+ setModuleId(q, batRef);
+ setFunctionId(q, insertRef);
+ q = pushReturn(mb, q,
newTmpVariable(mb, TYPE_any));
+ q = pushArgument(mb, q, j1);
+ q = pushArgument(mb, q, b);
+ q = pushBte(mb, q, 'a');
+ j1 = getArg(q, 0);
+ pushInstruction(mb, q);
+
t->type = j_transform;
t->tval1 =
GDKzalloc(sizeof(tree));
t->tval1->type = j_var;
@@ -5221,16 +5341,17 @@ dumptree(jc *j, Client cntxt, MalBlkPtr
j1 = getArg(q, 0);
pushInstruction(mb, q);
}
+
+ /* because all groups are contained in
an array now, the
+ * groupkeyvar is represented by
"(sval)[0](tval2)",
+ * e.g. $[0].a if the walk alias is $
and the var to
+ * group on is $.a */
+ changetmplrefsgroup(t->tval2,
+ t->tval1->sval,
t->tval1->tval2);
} else {
/* co-group */
}
- /* because all groups are contained in an array
now, the
- * groupkeyvar is represented by
"(sval)[0](tval2)",
- * e.g. $[0].a if the walk alias is $ and the
var to
- * group on is $.a */
- changetmplrefsgroup(t->tval2, t->tval1->sval,
t->tval1->tval2);
-
/* transform this node into a transform one,
and force
* re-iteration so we simulate a pipe */
t->type = j_transform;
@@ -6022,9 +6143,10 @@ dumptree(jc *j, Client cntxt, MalBlkPtr
conditionalcall(&a, mb, t->tval1,
coltypes, dynaarg,
coltpos, q);
- /* this is for top-level (in a JAQL
pipe), so it should always
- * return a JSON struct, hence create
an array with values from the
- * BAT we have returned */
+ /* this is for top-level (in a JAQL
pipe), so it
+ * should always return a JSON struct,
hence create
+ * an array with values from the BAT we
have
+ * returned */
r = newInstruction(mb, ASSIGNsymbol);
setModuleId(r, putName("json", 4));
setFunctionId(r, putName("wrap", 4));
diff --git a/monetdb5/extras/jaql/json.c b/monetdb5/extras/jaql/json.c
--- a/monetdb5/extras/jaql/json.c
+++ b/monetdb5/extras/jaql/json.c
@@ -980,69 +980,10 @@ JSONwrap(int *rkind, int *rstring, int *
}
str
-JSONunwraptype(str *ret, int *kind, int *string, int *integer, int *doble, int
*array, int *object, int *name, oid *arrid)
-{
- jsonbat jb;
- BAT *b;
- BATiter bi;
- BUN p, q;
- enum typeorder {tlng, tdbl, tstr} totype = tlng;
-
- loadbats();
-
- /* find types of outermost array */
- bi = bat_iterator(jb.kind);
- BUNfndOID(p, bi, arrid);
- if (*(bte *)BUNtail(bi, p) != 'a') {
- unloadbats();
- throw(MAL, "json.unwraptype", "JSON value must be an array");
- }
- b = BATselect(BATmirror(jb.array), BUNhead(bi, p), BUNhead(bi, p));
- b = BATsemijoin(jb.kind, b);
- bi = bat_iterator(b);
-
- /* special case for when the argument is a single array */
- if (BATcount(b) == 1 && *(bte *)BUNtail(bi, BUNfirst(b)) == 'a') {
- p = BUNfirst(b);
- b = BATselect(BATmirror(jb.array), BUNhead(bi, p), BUNhead(bi,
p));
- b = BATsemijoin(jb.kind, b);
- bi = bat_iterator(b);
- }
-
- BATloop(b, p, q) {
- switch (*(bte *)BUNtail(bi, p)) {
- case 't':
- case 'f':
- case 'n':
- case 'i':
- /* lower than or equal to the minimum type
(lng) */
- break;
- case 'd':
- if (totype < tdbl)
- totype = tdbl;
- break;
- default:
- totype = tstr;
- break;
- }
- }
-
- unloadbats();
-
- if (totype == tlng) {
- *ret = GDKstrdup("lng");
- } else if (totype == tdbl) {
- *ret = GDKstrdup("dbl");
- } else {
- *ret = GDKstrdup("str");
- }
- return MAL_SUCCEED;
-}
-
-str
JSONunwrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
int *ret = (int *)getArgReference(stk, pci, 0);
+ str *rets = (str *)getArgReference(stk, pci, 0);
int *kind = (int *)getArgReference(stk, pci, 1);
int *string = (int *)getArgReference(stk, pci, 2);
int *integer = (int *)getArgReference(stk, pci, 3);
@@ -1051,7 +992,7 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
int *object = (int *)getArgReference(stk, pci, 6);
int *name = (int *)getArgReference(stk, pci, 7);
oid *arrid = (oid *)getArgReference(stk, pci, 8);
- ValPtr tpe = getArgReference(stk, pci, 9);
+ ValPtr tpe;
jsonbat jb;
BATiter bi, bis, bii, bid;
BAT *b, *r;
@@ -1061,19 +1002,24 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
dbl d;
str s;
char buf[24];
+ char isUnwrap = strcmp(pci->fcnname, "unwrap") == 0;
+ enum typeorder {tlng, tdbl, tstr} totype = tlng;
(void)mb;
(void)cntxt;
- switch (tpe->vtype) {
- case TYPE_str:
- case TYPE_dbl:
- case TYPE_lng:
- /* ok, can do these */
- break;
- default:
- throw(MAL, "json.unwrap", "can only unwrap to "
- "str, dbl and lng values");
+ if (isUnwrap) {
+ tpe = getArgReference(stk, pci, 9);
+ switch (tpe->vtype) {
+ case TYPE_str:
+ case TYPE_dbl:
+ case TYPE_lng:
+ /* ok, can do these */
+ break;
+ default:
+ throw(MAL, "json.unwrap", "can only unwrap to "
+ "str, dbl and lng values");
+ }
}
loadbats();
@@ -1097,6 +1043,37 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
bi = bat_iterator(b);
}
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list
