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

json: add extract functionality

extract produces a new JSON object with the given list of element ids
from the kind BAT of the given JSON object.

This is useful for cleaning up a JSON object after many modifications
(calculations, transforms, filters) using elem 0@0, or for
pre-extracting some elements with a different starting oid.  The join
operation for instance can use this to copy in the necessary bits into
another JSON object.


diffs (298 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
@@ -1,5 +1,6 @@
 json00
 json01
+json02
 
 expand00
 filter00
diff --git a/monetdb5/extras/jaql/Tests/json02.mal 
b/monetdb5/extras/jaql/Tests/json02.mal
new file mode 100644
--- /dev/null
+++ b/monetdb5/extras/jaql/Tests/json02.mal
@@ -0,0 +1,31 @@
+# test extraction (cleanup)
+
+s := io.stdout();
+
+(j1,j2,j3,j4,j5,j6,j7) := 
json.shred("[\"hello\",{\"world\":[0,2,true,null]}]");
+json.print(s, j1,j2,j3,j4,j5,j6,j7);
+
+elem0 := bat.new(:oid, :oid);
+elem0 := bat.insert(elem0, 0@0, 0@0);
+
+(k1,k2,k3,k4,k5,k6,k7) := json.extract(j1,j2,j3,j4,j5,j6,j7,elem0,0@0);
+json.print(s, k1,k2,k3,k4,k5,k6,k7);
+
+elem1 := bat.new(:oid, :oid);
+elem1 := bat.insert(elem1, 0@0, 1@0);
+
+(k1,k2,k3,k4,k5,k6,k7) := json.extract(j1,j2,j3,j4,j5,j6,j7,elem1,0@0);
+json.print(s, k1,k2,k3,k4,k5,k6,k7);
+
+elem2 := bat.new(:oid, :oid);
+elem2 := bat.insert(elem2, 0@0, 2@0);
+
+(k1,k2,k3,k4,k5,k6,k7) := json.extract(j1,j2,j3,j4,j5,j6,j7,elem2,0@0);
+json.print(s, k1,k2,k3,k4,k5,k6,k7);
+
+elem3 := bat.new(:oid, :oid);
+elem3 := bat.insert(elem3, 0@0, 1@0);
+elem3 := bat.insert(elem3, 0@0, 3@0);
+
+(k1,k2,k3,k4,k5,k6,k7) := json.extract(j1,j2,j3,j4,j5,j6,j7,elem3,0@0);
+json.print(s, k1,k2,k3,k4,k5,k6,k7);
diff --git a/monetdb5/extras/jaql/Tests/json02.stable.err 
b/monetdb5/extras/jaql/Tests/json02.stable.err
new file mode 100644
--- /dev/null
+++ b/monetdb5/extras/jaql/Tests/json02.stable.err
@@ -0,0 +1,31 @@
+stderr of test 'json02` in directory 'extras/jaql` itself:
+
+
+# 22:47:09 >  
+# 22:47:09 >  "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=33699" "--set" "monet_prompt=" 
"--trace" "--forcemito" "--set" "mal_listing=2" "--dbname=mTests_extras_jaql" 
"json02.mal"
+# 22:47:09 >  
+
+# 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 = 33699
+# cmdline opt  monet_prompt = 
+# cmdline opt  mal_listing = 2
+# cmdline opt  gdk_dbname = mTests_extras_jaql
+
+# 22:47:10 >  
+# 22:47:10 >  "Done."
+# 22:47:10 >  
+
diff --git a/monetdb5/extras/jaql/Tests/json02.stable.out 
b/monetdb5/extras/jaql/Tests/json02.stable.out
new file mode 100644
--- /dev/null
+++ b/monetdb5/extras/jaql/Tests/json02.stable.out
@@ -0,0 +1,51 @@
+stdout of test 'json02` in directory 'extras/jaql` itself:
+
+
+# 22:47:09 >  
+# 22:47:09 >  "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=33699" "--set" "monet_prompt=" 
"--trace" "--forcemito" "--set" "mal_listing=2" "--dbname=mTests_extras_jaql" 
"json02.mal"
+# 22:47:09 >  
+
+# MonetDB 5 server v11.8.0 "jacqueline-0c67cb41e11b+"
+# Serving database 'mTests_extras_jaql', using 8 threads
+# Compiled for x86_64-pc-linux-gnu/64bit with 64bit OIDs dynamically linked
+# Found 15.662 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:33699/
+# MonetDB/GIS module loaded
+# MonetDB/SQL module loaded
+# MonetDB/DataCell module not loaded: MALException:jaql.context:JAQL 
environment not found
+function user.main():void;
+# test extraction (cleanup) 
+    s := io.stdout();
+    (j1,j2,j3,j4,j5,j6,j7) := 
json.shred("[\"hello\",{\"world\":[0,2,true,null]}]");
+    json.print(s,j1,j2,j3,j4,j5,j6,j7);
+    elem0 := bat.new(:oid,:oid);
+    elem0 := bat.insert(elem0,0@0,0@0);
+    (k1,k2,k3,k4,k5,k6,k7) := json.extract(j1,j2,j3,j4,j5,j6,j7,elem0,0@0);
+    json.print(s,k1,k2,k3,k4,k5,k6,k7);
+    elem1 := bat.new(:oid,:oid);
+    elem1 := bat.insert(elem1,0@0,1@0);
+    (k1,k2,k3,k4,k5,k6,k7) := json.extract(j1,j2,j3,j4,j5,j6,j7,elem1,0@0);
+    json.print(s,k1,k2,k3,k4,k5,k6,k7);
+    elem2 := bat.new(:oid,:oid);
+    elem2 := bat.insert(elem2,0@0,2@0);
+    (k1,k2,k3,k4,k5,k6,k7) := json.extract(j1,j2,j3,j4,j5,j6,j7,elem2,0@0);
+    json.print(s,k1,k2,k3,k4,k5,k6,k7);
+    elem3 := bat.new(:oid,:oid);
+    elem3 := bat.insert(elem3,0@0,1@0);
+    elem3 := bat.insert(elem3,0@0,3@0);
+    (k1,k2,k3,k4,k5,k6,k7) := json.extract(j1,j2,j3,j4,j5,j6,j7,elem3,0@0);
+    json.print(s,k1,k2,k3,k4,k5,k6,k7);
+end main;
+[ "hello", { "world": [ 0, 2, true, null ] } ]
+[ [ "hello", { "world": [ 0, 2, true, null ] } ] ]
+[ "hello" ]
+[ { "world": [ 0, 2, true, null ] } ]
+[ "hello", [ 0, 2, true, null ] ]
+
+# 22:47:10 >  
+# 22:47:10 >  "Done."
+# 22:47:10 >  
+
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
@@ -724,3 +724,134 @@ JSONdrop(int *ret, str *name)
        *ret = 0;
        return MAL_SUCCEED;
 }
+
+oid
+json_copy_entry(BATiter bik, BATiter bis, BATiter bii, BATiter bid, BATiter 
bia, BATiter bio, BATiter bin, oid start, oid v, jsonbat *jb, jsonbat *jbr)
+{
+       oid w, x;
+       chr k;
+
+       BUNfndOID(w, bik, &v);
+       k = *(chr *)BUNtail(bik, w);
+       BUNappend(jbr->kind, &k, FALSE);
+
+       w = BUNlast(jbr->kind) - 1 + start;
+       switch (k) {
+               case 'i':
+                       BUNfndOID(x, bii, &v);
+                       BUNins(jbr->integer, &w, BUNtail(bii, x), FALSE);
+                       break;
+               case 'd':
+                       BUNfndOID(x, bid, &v);
+                       BUNins(jbr->doble, &w, BUNtail(bid, x), FALSE);
+                       break;
+               case 's':
+                       BUNfndOID(x, bis, &v);
+                       BUNins(jbr->string, &w, BUNtail(bis, x), FALSE);
+                       break;
+               case 'n':
+               case 't':
+               case 'f':
+                       /* nothing to do here */
+                       break;
+               case 'o': {
+                       BAT *elems;
+                       BUN p, q;
+                       BATiter bi;
+                       oid y, z;
+                       elems = BATmirror(BATselect(BATmirror(jb->object), &v, 
&v));
+                       bi = bat_iterator(elems);
+                       BATloop (elems, p, q) {
+                               x = *(oid *)BUNtail(bi, p);
+                               z = json_copy_entry(bik, bis, bii, bid, bia, 
bio, bin,
+                                               start, x, jb, jbr);
+                               BUNins(jbr->object, &w, &z, FALSE);
+                               BUNfndOID(y, bin, &x);
+                               BUNins(jbr->name, &z, BUNtail(bin, y), FALSE);
+                       }
+                       BBPunfix(elems->batCacheid);
+                       break;
+               }
+               case 'a': {
+                       BAT *elems;
+                       BUN p, q;
+                       BATiter bi;
+                       oid z;
+                       elems = BATmirror(BATselect(BATmirror(jb->array), &v, 
&v));
+                       bi = bat_iterator(elems);
+                       BATloop (elems, p, q) {
+                               z = json_copy_entry(bik, bis, bii, bid, bia, 
bio, bin,
+                                               start, *(oid *)BUNtail(bi, p), 
jb, jbr);
+                               BUNins(jbr->array, &w, &z, FALSE);
+                       }
+                       BBPunfix(elems->batCacheid);
+                       break;
+               }
+       }
+
+       return w;
+}
+
+str
+JSONextract(int *rkind, int *rstring, int *rinteger, int *rdoble, int *rarray, 
int *robject, int *rname, int *kind, int *string, int *integer, int *doble, int 
*array, int *object, int *name, int *elems, oid *startoid)
+{
+       jsonbat jb, jbr;
+       BAT *e;
+       BATiter bie, bik, bis, bii, bid, bia, bio, bin;
+       BUN p, q;
+       oid v, w, z;
+
+       loadbats();
+       bik = bat_iterator(jb.kind);
+       bis = bat_iterator(jb.string);
+       bii = bat_iterator(jb.integer);
+       bid = bat_iterator(jb.doble);
+       bia = bat_iterator(jb.array);
+       bio = bat_iterator(jb.object);
+       bin = bat_iterator(jb.name);
+       e = BBPquickdesc(ABS(*elems), FALSE);
+       if (*elems < 0)
+               e = BATmirror(e);
+       BBPfix(*elems);
+       bie = bat_iterator(e);
+
+       memset(&jbr, 0, sizeof(jsonbat));
+
+       /* initialise all bats */
+       jbr.kind = BATnew(TYPE_void, TYPE_chr, BATTINY);
+       jbr.kind = BATseqbase(jbr.kind, *startoid);
+       jbr.string = BATnew(TYPE_oid, TYPE_str, BATTINY);
+       jbr.doble = BATnew(TYPE_oid, TYPE_dbl, BATTINY);
+       jbr.integer = BATnew(TYPE_oid, TYPE_lng, BATTINY);
+       jbr.name = BATnew(TYPE_oid, TYPE_str, BATTINY);
+       jbr.object = BATnew(TYPE_oid, TYPE_oid, BATTINY);
+       jbr.array = BATnew(TYPE_oid, TYPE_oid, BATTINY);
+
+       /* return all elems as the outermost array */
+       BUNappend(jbr.kind, "a", FALSE);
+       w = BUNlast(jbr.kind) - 1 + *startoid;
+       BATloop(e, p, q) {
+               v = *(oid *)BUNtail(bie, p);
+               z = json_copy_entry(bik, bis, bii, bid, bia, bio, bin,
+                               *startoid, v, &jb, &jbr);
+               BUNins(jbr.array, &w, &z, FALSE);
+       }
+
+       unloadbats();
+
+       BBPkeepref(jbr.kind->batCacheid);
+       *rkind = jbr.kind->batCacheid;
+       BBPkeepref(jbr.string->batCacheid);
+       *rstring = jbr.string->batCacheid;
+       BBPkeepref(jbr.integer->batCacheid);
+       *rinteger = jbr.integer->batCacheid;
+       BBPkeepref(jbr.doble->batCacheid);
+       *rdoble = jbr.doble->batCacheid;
+       BBPkeepref(jbr.array->batCacheid);
+       *rarray = jbr.array->batCacheid;
+       BBPkeepref(jbr.object->batCacheid);
+       *robject = jbr.object->batCacheid;
+       BBPkeepref(jbr.name->batCacheid);
+       *rname = jbr.name->batCacheid;
+       return MAL_SUCCEED;
+}
diff --git a/monetdb5/extras/jaql/json.h b/monetdb5/extras/jaql/json.h
--- a/monetdb5/extras/jaql/json.h
+++ b/monetdb5/extras/jaql/json.h
@@ -40,6 +40,7 @@ json_export str JSONprint(int *ret, stre
 json_export str JSONstore(int *ret, str *nme, int *kind, int *string, int 
*integer, int *doble, int *array, int *object, int *name);
 json_export str JSONload(int *kind, int *string, int *integer, int *doble, int 
*array, int *object, int *name, str *nme);
 json_export str JSONdrop(int *ret, str *name);
+json_export str JSONextract(int *rkind, int *rstring, int *rinteger, int 
*rdoble, int *rarray, int *robject, int *rname, int *kind, int *string, int 
*integer, int *doble, int *array, int *object, int *name, int *elems, oid 
*startoid);
 
 #endif
 
diff --git a/monetdb5/extras/jaql/json.mal b/monetdb5/extras/jaql/json.mal
--- a/monetdb5/extras/jaql/json.mal
+++ b/monetdb5/extras/jaql/json.mal
@@ -36,3 +36,7 @@ comment "Load the JSON object name from 
 command drop(nme:str):void
 address JSONdrop
 comment "Drop the JSON object name from the database";
+
+command 
extract(k:bat[:oid,:chr],s:bat[:oid,:str],i:bat[:oid,:lng],d:bat[:oid,:dbl],a:bat[:oid,:oid],o:bat[:oid,:oid],n:bat[:oid,:str],elems:bat[:oid,:oid],start:oid)(kind:bat[:oid,:chr],string:bat[:oid,:str],integer:bat[:oid,:lng],double:bat[:oid,:dbl],array:bat[:oid,:oid],object:bat[:oid,:oid],name:bat[:oid,:str])
+address JSONextract
+comment "Extract the given elems (kind id) from the given JSON object";
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to