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

unwrap: handle subarrays as groups

When the input consists of solely arrays, perform on all of those
arrays, instead of the input array.  For the real unwrap operation,
return in the head the oid of the element number (the array) being
unwrapped, such that the output can be given to the groupable functions
of jaqlfunc.


diffs (truncated from 412 to 300 lines):

diff --git a/monetdb5/extras/jaql/Tests/json05.mal 
b/monetdb5/extras/jaql/Tests/json05.mal
--- a/monetdb5/extras/jaql/Tests/json05.mal
+++ b/monetdb5/extras/jaql/Tests/json05.mal
@@ -17,3 +17,15 @@ t := json.unwraptype(j1,j2,j3,j4,j5,j6,j
 io.print(t);
 c := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0@0,"":str);
 io.print(c);
+
+(j1,j2,j3,j4,j5,j6,j7) := json.shred("[[1,2,3],[3,4,5],[4,5,6]]");
+t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7,0@0);
+io.print(t);
+a := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0@0,0:lng);
+io.print(a);
+
+(j1,j2,j3,j4,j5,j6,j7) := json.shred("[[1,2.3],[3,4,5],[4,5,6]]");
+t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7,0@0);
+io.print(t);
+b := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0@0,0:dbl);
+io.print(b);
diff --git a/monetdb5/extras/jaql/Tests/json05.stable.out 
b/monetdb5/extras/jaql/Tests/json05.stable.out
--- a/monetdb5/extras/jaql/Tests/json05.stable.out
+++ b/monetdb5/extras/jaql/Tests/json05.stable.out
@@ -32,6 +32,16 @@ function user.main():void;
     io.print(t);
     c := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0@0,"":str);
     io.print(c);
+    (j1,j2,j3,j4,j5,j6,j7) := json.shred("[[1,2,3],[3,4,5],[4,5,6]]");
+    t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7,0@0);
+    io.print(t);
+    a := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0@0,0:lng);
+    io.print(a);
+    (j1,j2,j3,j4,j5,j6,j7) := json.shred("[[1,2.3],[3,4,5],[4,5,6]]");
+    t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7,0@0);
+    io.print(t);
+    b := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0@0,0:dbl);
+    io.print(b);
 end main;
 [ "lng" ]
 #-----------------#
@@ -64,6 +74,33 @@ end main;
 [ 0@0,   "long('4')"             ]
 [ 0@0,   "4"                     ]
 [ 0@0,   "bool('true')"          ]
+[ "lng" ]
+#-----------------#
+# h    t         # name
+# oid  lng       # type
+#-----------------#
+[ 1@0,   1       ]
+[ 1@0,   2       ]
+[ 1@0,   3       ]
+[ 5@0,   3       ]
+[ 5@0,   4       ]
+[ 5@0,   5       ]
+[ 9@0,   4       ]
+[ 9@0,   5       ]
+[ 9@0,   6       ]
+[ "dbl" ]
+#---------------------------------#
+# h    t                         # name
+# oid  dbl                       # type
+#---------------------------------#
+[ 1@0,   1                       ]
+[ 1@0,   2.2999999999999998      ]
+[ 4@0,   3                       ]
+[ 4@0,   4                       ]
+[ 4@0,   5                       ]
+[ 8@0,   4                       ]
+[ 8@0,   5                       ]
+[ 8@0,   6                       ]
 
 # 14:25:21 >  
 # 14:25:21 >  "Done."
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
@@ -994,9 +994,9 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
        oid *arrid = (oid *)getArgReference(stk, pci, 8);
        ValPtr tpe;
        jsonbat jb;
-       BATiter bi, bis, bii, bid;
-       BAT *b, *r;
-       BUN p, q;
+       BATiter bi, bis, bii, bid, ci;
+       BAT *b, *c, *r = NULL;
+       BUN p, q, t, u;
        oid v = 0, x;
        lng l;
        dbl d;
@@ -1024,46 +1024,172 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
 
        loadbats();
 
-       /* find types of outermost array */
+       /* find types of referenced array */
        bi = bat_iterator(jb.kind);
        BUNfndOID(p, bi, arrid);
        if (*(bte *)BUNtail(bi, p) != 'a') {
                unloadbats();
-               throw(MAL, "json.unwrap", "JSON value must be an array");
+               throw(MAL, isUnwrap ? "json.unwrap" : "json.unwraptype",
+                               "JSON value must be an array");
        }
-       b = BATselect(BATmirror(jb.array), BUNhead(bi, p), BUNhead(bi, p));
+       b = BATselect(BATmirror(jb.array), BUNhead(bi, p), NULL);
        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));
+       c = BATantiuselect_(b, "a", NULL, TRUE, TRUE);
+       if (BATcount(c) != 0) {
+               c = BATmirror(BATselect(BATmirror(jb.kind), arrid, NULL));
+       } else {
+               c = b;
+       }
+       ci = bat_iterator(c);
+
+       BATloop(c, t, u) {
+               v = *(oid *)BUNhead(ci, t);
+               b = BATselect(BATmirror(jb.array), &v, NULL);
                b = BATsemijoin(jb.kind, b);
                bi = bat_iterator(b);
-       }
 
-       if (!isUnwrap) {
-               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) */
+               if (!isUnwrap) {
+                       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;
+                               }
+                       }
+               } else {
+                       bis = bat_iterator(jb.string);
+                       bii = bat_iterator(jb.integer);
+                       bid = bat_iterator(jb.doble);
+                       switch (tpe->vtype) {
+                               case TYPE_str:
+                                       if (r == NULL)
+                                               r = BATnew(TYPE_oid, TYPE_str, 
BATcount(b));
+                                       BATloop(b, p, q) {
+                                               switch (*(bte *)BUNtail(bi, p)) 
{
+                                                       case 's':
+                                                               BUNfndOID(x, 
bis, BUNhead(bi, p));
+                                                               BUNins(r, &v, 
BUNtail(bis, x), FALSE);
+                                                               break;
+                                                       case 'i':
+                                                               BUNfndOID(x, 
bii, BUNhead(bi, p));
+                                                               snprintf(buf, 
sizeof(buf), "long('%lld')",
+                                                                               
*(lng *)BUNtail(bii, x));
+                                                               BUNins(r, &v, 
buf, FALSE);
+                                                               break;
+                                                       case 'd':
+                                                               BUNfndOID(x, 
bid, BUNhead(bi, p));
+                                                               snprintf(buf, 
sizeof(buf), "double('%f')",
+                                                                               
*(dbl *)BUNtail(bid, x));
+                                                               BUNins(r, &v, 
buf, FALSE);
+                                                               break;
+                                                       case 't':
+                                                               snprintf(buf, 
sizeof(buf), "bool('true')");
+                                                               BUNins(r, &v, 
buf, FALSE);
+                                                               break;
+                                                       case 'f':
+                                                               snprintf(buf, 
sizeof(buf), "bool('false')");
+                                                               BUNins(r, &v, 
buf, FALSE);
+                                                               break;
+                                                       case 'n':
+                                                               BUNins(r, &v, 
(ptr)str_nil, FALSE);
+                                                               break;
+                                                       default:
+                                                               /* JSON piece 
(object/array), serialise */
+                                                               (void)s;
+                                                               /* TODO: 
implement right call */;
+                                                               BUNins(r, &v, 
(ptr)str_nil, FALSE);
+                                                               break;
+                                               }
+                                       }
                                        break;
-                               case 'd':
-                                       if (totype < tdbl)
-                                               totype = tdbl;
+                               case TYPE_dbl:
+                                       if (r == NULL)
+                                               r = BATnew(TYPE_oid, TYPE_dbl, 
BATcount(b));
+                                       BATloop(b, p, q) {
+                                               switch (*(bte *)BUNtail(bi, p)) 
{
+                                                       case 's':
+                                                               BUNfndOID(x, 
bis, BUNhead(bi, p));
+                                                               d = 
atof((str)BUNtail(bis, x));
+                                                               BUNins(r, &v, 
&d, FALSE);
+                                                               break;
+                                                       case 'i':
+                                                               BUNfndOID(x, 
bii, BUNhead(bi, p));
+                                                               d = (dbl)*(lng 
*)BUNtail(bii, x);
+                                                               BUNins(r, &v, 
&d, FALSE);
+                                                               break;
+                                                       case 'd':
+                                                               BUNfndOID(x, 
bid, BUNhead(bi, p));
+                                                               BUNins(r, &v, 
BUNtail(bid, x), FALSE);
+                                                               break;
+                                                       case 't':
+                                                               d = 1.0;
+                                                               BUNins(r, &v, 
&d, FALSE);
+                                                               break;
+                                                       case 'f':
+                                                               d = 0.0;
+                                                               BUNins(r, &v, 
&d, FALSE);
+                                                               break;
+                                                       case 'n':
+                                                               d = dbl_nil;
+                                                               BUNins(r, &v, 
&d, FALSE);
+                                                               break;
+                                               }
+                                       }
                                        break;
-                               default:
-                                       totype = tstr;
+                               case TYPE_lng:
+                                       if (r == NULL)
+                                               r = BATnew(TYPE_oid, TYPE_lng, 
BATcount(b));
+                                       BATloop(b, p, q) {
+                                               switch (*(bte *)BUNtail(bi, p)) 
{
+                                                       case 's':
+                                                               BUNfndOID(x, 
bis, BUNhead(bi, p));
+                                                               l = 
atoi((str)BUNtail(bis, x));
+                                                               BUNins(r, &v, 
&l, FALSE);
+                                                               break;
+                                                       case 'd':
+                                                               BUNfndOID(x, 
bid, BUNhead(bi, p));
+                                                               l = (lng)*(dbl 
*)BUNtail(bis, x);
+                                                               BUNins(r, &v, 
&l, FALSE);
+                                                               break;
+                                                       case 'i':
+                                                               BUNfndOID(x, 
bii, BUNhead(bi, p));
+                                                               BUNins(r, &v, 
BUNtail(bii, x), FALSE);
+                                                               break;
+                                                       case 't':
+                                                               l = 1;
+                                                               BUNins(r, &v, 
&l, FALSE);
+                                                               break;
+                                                       case 'f':
+                                                               l = 0;
+                                                               BUNins(r, &v, 
&l, FALSE);
+                                                               break;
+                                                       case 'n':
+                                                               l = lng_nil;
+                                                               BUNins(r, &v, 
&l, FALSE);
+                                                               break;
+                                               }
+                                       }
                                        break;
                        }
                }
+       }
 
-               unloadbats();
+       unloadbats();
 
+       if (!isUnwrap) {
                if (totype == tlng) {
                        *rets = GDKstrdup("lng");
                } else if (totype == tdbl) {
@@ -1071,124 +1197,11 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
                } else {
                        *rets = GDKstrdup("str");
                }
-               return MAL_SUCCEED;
+       } else {
+               assert(r != NULL);
+               BBPkeepref(r->batCacheid);
+               *ret = r->batCacheid;
        }
 
-       bis = bat_iterator(jb.string);
-       bii = bat_iterator(jb.integer);
-       bid = bat_iterator(jb.doble);
-       switch (tpe->vtype) {
-               case TYPE_str:
-                       r = BATnew(TYPE_oid, TYPE_str, BATcount(b));
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to