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

json: unwrap(): produce a single BAT for a JSON array

First shot at JSONunwrap which turns a JSON array into a BAT with oid
head and tail of highest type necessary to represent the array (being
str).  The minimal type is lng, the currently only intermediate type is
dbl.

This functionality should allow for runtime handling for functions that
can deal with multiple types, such as e.g. compare, or sum, where it is
undesirable to always upcast to the "largest" type (str).


diffs (truncated from 320 to 300 lines):

diff --git a/monetdb5/extras/jaql/Tests/All b/monetdb5/extras/jaql/Tests/All
--- a/monetdb5/extras/jaql/Tests/All
+++ b/monetdb5/extras/jaql/Tests/All
@@ -3,6 +3,7 @@ json01
 json02
 json03
 json04
+json05
 
 expand00
 filter00
diff --git a/monetdb5/extras/jaql/Tests/json05.mal 
b/monetdb5/extras/jaql/Tests/json05.mal
new file mode 100644
--- /dev/null
+++ b/monetdb5/extras/jaql/Tests/json05.mal
@@ -0,0 +1,13 @@
+# Test the unwrapping of JSON arrays
+
+(j1,j2,j3,j4,j5,j6,j7) := json.shred("[false,1,2,null,4]");
+a := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+io.print(a);
+
+(j1,j2,j3,j4,j5,j6,j7) := json.shred("[1,true,2.3,null,4]");
+b := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+io.print(b);
+
+(j1,j2,j3,j4,j5,j6,j7) := json.shred("[1,2.3,null,4,\"4\",true]");
+c := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+io.print(c);
diff --git a/monetdb5/extras/jaql/Tests/json05.stable.err 
b/monetdb5/extras/jaql/Tests/json05.stable.err
new file mode 100644
--- /dev/null
+++ b/monetdb5/extras/jaql/Tests/json05.stable.err
@@ -0,0 +1,31 @@
+stderr of test 'json05` in directory 'extras/jaql` itself:
+
+
+# 14:25:21 >  
+# 14:25:21 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"gdk_dbfarm=/net/sofia.ins.cwi.nl/export/scratch1/fabian/tmp/mtest-jacqueline-sofia.ins.cwi.nl/five/dbfarm"
 "--set" "mapi_open=true" "--set" "mapi_port=34265" "--set" "monet_prompt=" 
"--trace" "--forcemito" "--set" "mal_listing=2" "--dbname=mTests_extras_jaql" 
"json05.mal"
+# 14:25:21 >  
+
+# builtin opt  gdk_dbname = demo
+# builtin opt  gdk_dbfarm = 
/ufs/fabian/scratch/ssd/monetdb/jacqueline/program-x86_64/var/lib/monetdb5/dbfarm
+# builtin opt  gdk_debug = 0
+# builtin opt  gdk_alloc_map = no
+# builtin opt  gdk_vmtrim = yes
+# builtin opt  monet_prompt = >
+# builtin opt  monet_daemon = no
+# builtin opt  mapi_port = 50000
+# builtin opt  mapi_open = false
+# builtin opt  mapi_autosense = false
+# builtin opt  sql_optimizer = default_pipe
+# builtin opt  sql_debug = 0
+# cmdline opt  gdk_nr_threads = 0
+# cmdline opt  gdk_dbfarm = 
/net/sofia.ins.cwi.nl/export/scratch1/fabian/tmp/mtest-jacqueline-sofia.ins.cwi.nl/five/dbfarm
+# cmdline opt  mapi_open = true
+# cmdline opt  mapi_port = 34265
+# cmdline opt  monet_prompt = 
+# cmdline opt  mal_listing = 2
+# cmdline opt  gdk_dbname = mTests_extras_jaql
+
+# 14:25:21 >  
+# 14:25:21 >  "Done."
+# 14:25:21 >  
+
diff --git a/monetdb5/extras/jaql/Tests/json05.stable.out 
b/monetdb5/extras/jaql/Tests/json05.stable.out
new file mode 100644
--- /dev/null
+++ b/monetdb5/extras/jaql/Tests/json05.stable.out
@@ -0,0 +1,62 @@
+stdout of test 'json05` in directory 'extras/jaql` itself:
+
+
+# 14:25:21 >  
+# 14:25:21 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"gdk_dbfarm=/net/sofia.ins.cwi.nl/export/scratch1/fabian/tmp/mtest-jacqueline-sofia.ins.cwi.nl/five/dbfarm"
 "--set" "mapi_open=true" "--set" "mapi_port=34265" "--set" "monet_prompt=" 
"--trace" "--forcemito" "--set" "mal_listing=2" "--dbname=mTests_extras_jaql" 
"json05.mal"
+# 14:25:21 >  
+
+# MonetDB 5 server v11.8.0 "jacqueline-461699c362de"
+# Serving database 'mTests_extras_jaql', using 8 threads
+# Compiled for x86_64-pc-linux-gnu/64bit with 64bit OIDs dynamically linked
+# Found 15.630 GiB available main-memory.
+# Copyright (c) 1993-July 2008 CWI.
+# Copyright (c) August 2008-2012 MonetDB B.V., all rights reserved
+# Visit http://www.monetdb.org/ for further information
+# Listening for connection requests on mapi:monetdb://sofia.ins.cwi.nl:34265/
+# MonetDB/GIS module loaded
+# MonetDB/SQL module loaded
+function user.main():void;
+# Test the unwrapping of JSON arrays 
+    (j1,j2,j3,j4,j5,j6,j7) := json.shred("[false,1,2,null,4]");
+    a := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+    io.print(a);
+    (j1,j2,j3,j4,j5,j6,j7) := json.shred("[1,true,2.3,null,4]");
+    b := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+    io.print(b);
+    (j1,j2,j3,j4,j5,j6,j7) := json.shred("[1,2.3,null,4,\"4\",true]");
+    c := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+    io.print(c);
+end main;
+#-----------------#
+# h    t         # name
+# oid  lng       # type
+#-----------------#
+[ 0@0,   0       ]
+[ 0@0,   1       ]
+[ 0@0,   2       ]
+[ 0@0,   nil     ]
+[ 0@0,   4       ]
+#---------------------------------#
+# h    t                         # name
+# oid  dbl                       # type
+#---------------------------------#
+[ 0@0,   1                       ]
+[ 0@0,   1                       ]
+[ 0@0,   2.2999999999999998      ]
+[ 0@0,   nil                     ]
+[ 0@0,   4                       ]
+#---------------------------------#
+# h    t                         # name
+# oid  str                       # type
+#---------------------------------#
+[ 0@0,   "long('1')"             ]
+[ 0@0,   "double('2.300000')"    ]
+[ 0@0,   nil                     ]
+[ 0@0,   "long('4')"             ]
+[ 0@0,   "4"                     ]
+[ 0@0,   "bool('true')"          ]
+
+# 14:25:21 >  
+# 14:25:21 >  "Done."
+# 14:25:21 >  
+
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
@@ -979,3 +979,162 @@ JSONwrap(int *rkind, int *rstring, int *
        return MAL_SUCCEED;
 }
 
+str
+JSONunwrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+       int *ret = (int *)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);
+       int *doble = (int *)getArgReference(stk, pci, 4);
+       int *array = (int *)getArgReference(stk, pci, 5);
+       int *object = (int *)getArgReference(stk, pci, 6);
+       int *name = (int *)getArgReference(stk, pci, 7);
+       jsonbat jb;
+       BATiter bi, bis, bii, bid;
+       BAT *b, *r;
+       BUN p, q;
+       oid v = 0, x;
+       lng l;
+       dbl d;
+       str s;
+       char buf[24];
+       enum typeorder {tlng, tdbl, tstr} totype = tlng;
+
+       (void)mb;
+       (void)cntxt;
+
+       loadbats();
+
+       /* find types of outermost array */
+       bi = bat_iterator(jb.kind);
+       if (*(bte *)BUNtail(bi, BUNfirst(jb.kind)) != 'a') {
+               unloadbats();
+               throw(MAL, "json.unwrap", "JSON value must be an array");
+       }
+       b = BATselect(BATmirror(jb.array),
+                                       BUNhead(bi, BUNfirst(jb.kind)),
+                                       BUNhead(bi, BUNfirst(jb.kind)));
+       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;
+               }
+       }
+       
+       bis = bat_iterator(jb.string);
+       bii = bat_iterator(jb.integer);
+       bid = bat_iterator(jb.doble);
+       switch (totype) {
+               case tstr:
+                       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 tdbl:
+                       r = BATnew(TYPE_oid, TYPE_dbl, BATcount(b));
+                       BATloop(b, p, q) {
+                               switch (*(bte *)BUNtail(bi, p)) {
+                                       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;
+               case tlng:
+                       r = BATnew(TYPE_oid, TYPE_lng, BATcount(b));
+                       BATloop(b, p, q) {
+                               switch (*(bte *)BUNtail(bi, p)) {
+                                       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();
+
+       BBPkeepref(r->batCacheid);
+       *ret = r->batCacheid;
+       return MAL_SUCCEED;
+}
diff --git a/monetdb5/extras/jaql/json.h b/monetdb5/extras/jaql/json.h
--- a/monetdb5/extras/jaql/json.h
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to