Changeset: b0ade9cf5f4d for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b0ade9cf5f4d Modified Files: monetdb5/extras/jaql/Tests/All monetdb5/extras/jaql/Tests/json04.mal monetdb5/extras/jaql/Tests/json04.stable.err monetdb5/extras/jaql/Tests/json04.stable.out monetdb5/extras/jaql/json.c monetdb5/extras/jaql/json.h monetdb5/extras/jaql/json.mal Branch: jacqueline Log Message:
json: add wrap() function to encapsulate a BAT in an array wrap returns a JSON array with the values from the BAT. NULL values are mapped appropriately, as are boolean (bit) values. 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 @@ -2,6 +2,7 @@ json00 json01 json02 json03 +json04 expand00 filter00 diff --git a/monetdb5/extras/jaql/Tests/json04.mal b/monetdb5/extras/jaql/Tests/json04.mal new file mode 100644 --- /dev/null +++ b/monetdb5/extras/jaql/Tests/json04.mal @@ -0,0 +1,42 @@ +# test wrap on some bats + +s := io.stdout(); + +elems := bat.new(:oid, :str); +elems := bat.insert(elems, 1@0, "hello"); +elems := bat.insert(elems, 9@0, "world"); +elems := bat.insert(elems, 9@0, nil:str); + +(r1,r2,r3,r4,r5,r6,r7) := json.wrap(elems); + +json.print(s, r1,r2,r3,r4,r5,r6,r7); + + +elemi := bat.new(:oid, :lng); +elemi := bat.insert(elemi, 1@0, 4:lng); +elemi := bat.insert(elemi, 1@0, nil:lng); +elemi := bat.insert(elemi, 9@0, 2:lng); + +(r1,r2,r3,r4,r5,r6,r7) := json.wrap(elemi); + +json.print(s, r1,r2,r3,r4,r5,r6,r7); + + +elemd := bat.new(:oid, :dbl); +elemd := bat.insert(elemd, 1@0, 7.3:dbl); +elemd := bat.insert(elemd, 9@0, 8.6:dbl); +elemd := bat.insert(elemd, 3@0, nil:dbl); + +(r1,r2,r3,r4,r5,r6,r7) := json.wrap(elemd); + +json.print(s, r1,r2,r3,r4,r5,r6,r7); + + +elemb := bat.new(:oid, :bit); +elemb := bat.insert(elemb, 3@0, nil:bit); +elemb := bat.insert(elemb, 1@0, true); +elemb := bat.insert(elemb, 9@0, false); + +(r1,r2,r3,r4,r5,r6,r7) := json.wrap(elemb); + +json.print(s, r1,r2,r3,r4,r5,r6,r7); diff --git a/monetdb5/extras/jaql/Tests/json04.stable.err b/monetdb5/extras/jaql/Tests/json04.stable.err new file mode 100644 --- /dev/null +++ b/monetdb5/extras/jaql/Tests/json04.stable.err @@ -0,0 +1,31 @@ +stderr of test 'json04` in directory 'extras/jaql` itself: + + +# 19:57:32 > +# 19:57:32 > "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=31045" "--set" "monet_prompt=" "--trace" "--forcemito" "--set" "mal_listing=2" "--dbname=mTests_extras_jaql" "json04.mal" +# 19:57:32 > + +# 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 = 31045 +# cmdline opt monet_prompt = +# cmdline opt mal_listing = 2 +# cmdline opt gdk_dbname = mTests_extras_jaql + +# 19:57:32 > +# 19:57:32 > "Done." +# 19:57:32 > + diff --git a/monetdb5/extras/jaql/Tests/json04.stable.out b/monetdb5/extras/jaql/Tests/json04.stable.out new file mode 100644 --- /dev/null +++ b/monetdb5/extras/jaql/Tests/json04.stable.out @@ -0,0 +1,54 @@ +stdout of test 'json04` in directory 'extras/jaql` itself: + + +# 19:57:32 > +# 19:57:32 > "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=31045" "--set" "monet_prompt=" "--trace" "--forcemito" "--set" "mal_listing=2" "--dbname=mTests_extras_jaql" "json04.mal" +# 19:57:32 > + +# 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:31045/ +# MonetDB/GIS module loaded +# MonetDB/SQL module loaded +function user.main():void; +# test wrap on some bats + s := io.stdout(); + elems := bat.new(:oid,:str); + elems := bat.insert(elems,1@0,"hello"); + elems := bat.insert(elems,9@0,"world"); + elems := bat.insert(elems,9@0,nil:str); + (r1,r2,r3,r4,r5,r6,r7) := json.wrap(elems); + json.print(s,r1,r2,r3,r4,r5,r6,r7); + elemi := bat.new(:oid,:lng); + elemi := bat.insert(elemi,1@0,4:lng); + elemi := bat.insert(elemi,1@0,nil:lng); + elemi := bat.insert(elemi,9@0,2:lng); + (r1,r2,r3,r4,r5,r6,r7) := json.wrap(elemi); + json.print(s,r1,r2,r3,r4,r5,r6,r7); + elemd := bat.new(:oid,:dbl); + elemd := bat.insert(elemd,1@0,7.3000001907348633:dbl); + elemd := bat.insert(elemd,9@0,8.6000003814697266:dbl); + elemd := bat.insert(elemd,3@0,nil:dbl); + (r1,r2,r3,r4,r5,r6,r7) := json.wrap(elemd); + json.print(s,r1,r2,r3,r4,r5,r6,r7); + elemb := bat.new(:oid,:bit); + elemb := bat.insert(elemb,3@0,nil:bit); + elemb := bat.insert(elemb,1@0,true); + elemb := bat.insert(elemb,9@0,false); + (r1,r2,r3,r4,r5,r6,r7) := json.wrap(elemb); + json.print(s,r1,r2,r3,r4,r5,r6,r7); +end main; +[ "hello", "world", null ] +[ 4, null, 2 ] +[ 7.300000, 8.600000, null ] +[ null, true, false ] + +# 19:57:32 > +# 19:57:32 > "Done." +# 19:57:32 > + 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 @@ -863,3 +863,119 @@ JSONextract(int *rkind, int *rstring, in *rname = jbr.name->batCacheid; return MAL_SUCCEED; } + +str +JSONwrap(int *rkind, int *rstring, int *rinteger, int *rdoble, int *rarray, int *robject, int *rname, int *elems) +{ + jsonbat jbr; + BAT *e; + BATiter bie; + BUN p, q; + oid v, w; + bte k; + str s; + lng i; + dbl d; + bit b; + + e = BBPquickdesc(ABS(*elems), FALSE); + if (*elems < 0) + e = BATmirror(e); + + /* figure out what type this is */ + switch (e->ttype) { + case TYPE_str: + case TYPE_lng: + case TYPE_dbl: + case TYPE_bit: + break; + default: + throw(MAL, "json.wrap", "unsupported tail type"); + } + + BBPfix(*elems); + bie = bat_iterator(e); + + memset(&jbr, 0, sizeof(jsonbat)); + + /* initialise all bats */ + jbr.kind = BATnew(TYPE_void, TYPE_bte, BATTINY); + jbr.kind = BATseqbase(jbr.kind, (oid)0); + 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 */ + v = BUNlast(jbr.kind); + BUNappend(jbr.kind, "a", FALSE); + w = BUNlast(jbr.kind); + + BATloop(e, p, q) { + switch (e->ttype) { + case TYPE_str: + s = (str)BUNtail(bie, p); + k = 's'; + if (strcmp(s, str_nil) == 0) { + k = 'n'; + } else { + BUNins(jbr.string, &w, s, FALSE); + } + break; + case TYPE_lng: + i = *(lng *)BUNtail(bie, p); + k = 'i'; + if (i == lng_nil) { + k = 'n'; + } else { + BUNins(jbr.integer, &w, &i, FALSE); + } + break; + case TYPE_dbl: + d = *(dbl *)BUNtail(bie, p); + k = 'd'; + if (d == dbl_nil) { + k = 'n'; + } else { + BUNins(jbr.doble, &w, &d, FALSE); + } + break; + case TYPE_bit: + b = *(bit *)BUNtail(bie, p); + if (b == bit_nil) { + k = 'n'; + } else if (b != 0) { + k = 't'; + } else { + k = 'f'; + } + break; + default: + assert(0); + } + BUNins(jbr.array, &v, &w, FALSE); + BUNappend(jbr.kind, &k, FALSE); + w = BUNlast(jbr.kind); + } + + BBPunfix(*elems); + + 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 @@ -41,6 +41,7 @@ json_export str JSONstore(int *ret, str 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); +json_export str JSONwrap(int *rkind, int *rstring, int *rinteger, int *rdoble, int *rarray, int *robject, int *rname, int *elems); #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 @@ -40,3 +40,7 @@ comment "Drop the JSON object name from command extract(k:bat[:oid,:bte],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,:bte],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"; + +command wrap(elems:bat[:oid,:any])(kind:bat[:oid,:bte],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 JSONwrap +comment "Wrap the given BAT inside a JSON array"; _______________________________________________ Checkin-list mailing list [email protected] http://mail.monetdb.org/mailman/listinfo/checkin-list
