Changeset: 1f7ae6fcfccb for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1f7ae6fcfccb
Modified Files:
clients/Tests/MAL-signatures.stable.out
clients/Tests/MAL-signatures.stable.out.int128
monetdb5/modules/atoms/Tests/json13.maltest
monetdb5/modules/atoms/json.c
Branch: default
Log Message:
Do not just send random data to the client: changed json.dump to return a BAT.
diffs (270 lines):
diff --git a/clients/Tests/MAL-signatures.stable.out
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -8798,7 +8798,7 @@ stdout of test 'MAL-signatures` in direc
[ "iterator", "next", "command iterator.next(X_1:lng, X_2:lng):lng ",
"ITRnext_lng;", "" ]
[ "iterator", "next", "command iterator.next(X_1:oid, X_2:oid):oid ",
"ITRnext_oid;", "" ]
[ "iterator", "next", "command iterator.next(X_1:sht, X_2:sht):sht ",
"ITRnext_sht;", "" ]
-[ "json", "dump", "pattern json.dump(X_1:json):void ", "JSONdump;",
"" ]
+[ "json", "dump", "pattern json.dump(X_1:json):bat[:str] ",
"JSONdump;", "" ]
[ "json", "filter", "command json.filter(X_1:json, X_2:str):json ",
"JSONfilter;", "" ]
[ "json", "filter", "command json.filter(X_1:json, X_2:bte,
X_3:str):json ", "JSONfilterArrayDefault_bte;", "" ]
[ "json", "filter", "command json.filter(X_1:json, X_2:int,
X_3:str):json ", "JSONfilterArrayDefault_int;", "" ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -12094,7 +12094,7 @@ stdout of test 'MAL-signatures` in direc
[ "iterator", "next", "command iterator.next(X_1:lng, X_2:lng):lng ",
"ITRnext_lng;", "" ]
[ "iterator", "next", "command iterator.next(X_1:oid, X_2:oid):oid ",
"ITRnext_oid;", "" ]
[ "iterator", "next", "command iterator.next(X_1:sht, X_2:sht):sht ",
"ITRnext_sht;", "" ]
-[ "json", "dump", "pattern json.dump(X_1:json):void ", "JSONdump;",
"" ]
+[ "json", "dump", "pattern json.dump(X_1:json):bat[:str] ",
"JSONdump;", "" ]
[ "json", "filter", "command json.filter(X_1:json, X_2:str):json ",
"JSONfilter;", "" ]
[ "json", "filter", "command json.filter(X_1:json, X_2:bte,
X_3:str):json ", "JSONfilterArrayDefault_bte;", "" ]
[ "json", "filter", "command json.filter(X_1:json, X_2:hge,
X_3:str):json ", "JSONfilterArrayDefault_hge;", "" ]
diff --git a/monetdb5/modules/atoms/Tests/json13.maltest
b/monetdb5/modules/atoms/Tests/json13.maltest
--- a/monetdb5/modules/atoms/Tests/json13.maltest
+++ b/monetdb5/modules/atoms/Tests/json13.maltest
@@ -1,64 +1,11 @@
statement ok
js:= json.new("{ \"store\": { \"book\": [ { \"category\": \"reference\",
\"author\": \"Nigel Rees\", \"title\": \"Sayings of the Century\", \"price\":
8.95 }, { \"category\": \"fiction\", \"author\": \"Evelyn Waugh\", \"title\":
\"Sword of Honour\", \"price\": 12.99 }, { \"category\": \"fiction\",
\"author\": \"Herman Melville\", \"title\": \"Moby Dick\", \"isbn\":
\"0-553-21311-3\", \"price\": 8.99 }, { \"category\": \"fiction\", \"author\":
\"J. R. R. Tolkien\", \"title\": \"The Lord of the Rings\", \"isbn\":
\"0-395-19395-8\", \"price\": 22.99 } ], \"bicycle\": { \"color\": \"red\",
\"price\": 19.95 } } }")
-query T rowsort
-json.dump(js)
+query IT rowsort
+jd := json.dump(js);
+io.print(jd);
----
-0] object child 0 list 1 { "store": { "book": [ { "category": "reference",
"author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, {
"category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour",
"price": 12.99 }, { "category": "fiction", "author": "Herman Melville",
"title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category":
"fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings",
"isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red",
"price": 19.95 } }
-10] element child 11 list 12 titl
-11] string child 0 list "Sayings of the Century
-12] element child 13 list pric
-13] number child 0 list 8.9
-14] value child 5 list 24 36 48
-15] object child 0 list 16 18 20 22 { "category": "fiction", "author": "Evelyn
Waugh", "title": "Sword of Honour", "price": 12.99
-16] element child 17 list 18 20 22 categor
-17] string child 0 list "fiction
-18] element child 19 list 20 22 autho
-19] string child 0 list "Evelyn Waugh
-1] element child 2 list stor
-20] element child 21 list 22 titl
-21] string child 0 list "Sword of Honour
-22] element child 23 list pric
-23] number child 0 list 12.9
-24] value child 15 list 36 48
-25] object child 0 list 26 28 30 32 34 { "category": "fiction", "author":
"Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99
-26] element child 27 list 28 30 32 34 categor
-27] string child 0 list "fiction
-28] element child 29 list 30 32 34 autho
-29] string child 0 list "Herman Melville
-2] object child 0 list 3 49 { "book": [ { "category": "reference", "author":
"Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category":
"fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99
}, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick",
"isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author":
"J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8",
"price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 }
-30] element child 31 list 32 34 titl
-31] string child 0 list "Moby Dick
-32] element child 33 list 34 isb
-33] string child 0 list "0-553-21311-3
-34] element child 35 list pric
-35] number child 0 list 8.9
-36] value child 25 list 48
-37] object child 0 list 38 40 42 44 46 { "category": "fiction", "author": "J.
R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8",
"price": 22.99
-38] element child 39 list 40 42 44 46 categor
-39] string child 0 list "fiction
-3] element child 4 list 49 boo
-40] element child 41 list 42 44 46 autho
-41] string child 0 list "J. R. R. Tolkien
-42] element child 43 list 44 46 titl
-43] string child 0 list "The Lord of the Rings
-44] element child 45 list 46 isb
-45] string child 0 list "0-395-19395-8
-46] element child 47 list pric
-47] number child 0 list 22.9
-48] value child 37 list
-49] element child 50 list bicycl
-4] array child 0 list 14 24 36 48 [ { "category": "reference", "author":
"Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category":
"fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99
}, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick",
"isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author":
"J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8",
"price": 22.99 }
-50] object child 0 list 51 53 { "color": "red", "price": 19.95
-51] element child 52 list 53 colo
-52] string child 0 list "red
-53] element child 54 list pric
-54] number child 0 list 19.9
-5] object child 0 list 6 8 10 12 { "category": "reference", "author": "Nigel
Rees", "title": "Sayings of the Century", "price": 8.95
-6] element child 7 list 8 10 12 categor
-7] string child 0 list "reference
-8] element child 9 list 10 12 autho
-9] string child 0 list "Nigel Rees
+110 values hashing to 84992dc677b13759a408ee7ea3828340
statement ok
p:= json.filter(js,".store.book[*]..author")
diff --git a/monetdb5/modules/atoms/json.c b/monetdb5/modules/atoms/json.c
--- a/monetdb5/modules/atoms/json.c
+++ b/monetdb5/modules/atoms/json.c
@@ -241,75 +241,133 @@ JSONtoString(str *s, size_t *len, const
return (ssize_t) (dst - *s);
}
-#define tab(D)
\
- do {
\
- int kk;
\
- for (kk = 0; kk < (D) * 4; kk++) \
- mnstr_printf(fd, " "); \
- } while (0)
-
-static void
-JSONdumpInternal(stream *fd, JSON *jt, int depth)
+static BAT *
+JSONdumpInternal(JSON *jt, int depth)
{
int i, idx;
JSONterm *je;
+ size_t buflen = 1024;
+ char *buffer = GDKmalloc(buflen);
+ BAT *bn = COLnew(0, TYPE_str, 0, TRANSIENT);
+ if (bn == NULL)
+ return NULL;
for (idx = 0; idx < jt->free; idx++) {
+ size_t datlen = 0;
je = jt->elm + idx;
- tab(depth);
- mnstr_printf(fd, "[%d] ", idx);
+ if (datlen + depth*4 + 512 > buflen) {
+ do {
+ buflen += 1024;
+ } while (datlen + depth*4 + 512 > buflen);
+ char *newbuf = GDKrealloc(buffer, buflen);
+ if (newbuf == NULL) {
+ GDKfree(buffer);
+ BBPreclaim(bn);
+ return NULL;
+ }
+ buffer = newbuf;
+ }
+ datlen += snprintf(buffer + datlen, buflen - datlen, "%*s",
depth * 4, "");
+ datlen += snprintf(buffer + datlen, buflen - datlen, "[%d] ",
idx);
switch (je->kind) {
case JSON_OBJECT:
- mnstr_printf(fd, "object ");
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"object ");
break;
case JSON_ARRAY:
- mnstr_printf(fd, "array ");
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"array ");
break;
case JSON_ELEMENT:
- mnstr_printf(fd, "element ");
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"element ");
break;
case JSON_VALUE:
- mnstr_printf(fd, "value ");
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"value ");
break;
case JSON_STRING:
- mnstr_printf(fd, "string ");
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"string ");
break;
case JSON_NUMBER:
- mnstr_printf(fd, "number ");
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"number ");
break;
case JSON_BOOL:
- mnstr_printf(fd, "bool ");
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"bool ");
break;
case JSON_NULL:
- mnstr_printf(fd, "null ");
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"null ");
break;
default:
- mnstr_printf(fd, "unknown %d ", (int) je->kind);
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"unknown %d ", (int) je->kind);
}
- mnstr_printf(fd, "child %d list ", je->child);
- for (i = je->next; i; i = jt->elm[i].next)
- mnstr_printf(fd, "%d ", i);
+ datlen += snprintf(buffer + datlen, buflen - datlen, "child %d
list ", je->child);
+ for (i = je->next; i; i = jt->elm[i].next) {
+ if (datlen + 10 > buflen) {
+ buflen += 1024;
+ char *newbuf = GDKrealloc(buffer, buflen);
+ if (newbuf == NULL) {
+ GDKfree(buffer);
+ BBPreclaim(bn);
+ return NULL;
+ }
+ buffer = newbuf;
+ }
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"%d ", i);
+ }
if (je->name) {
- mnstr_printf(fd, "%.*s : ", (int) je->namelen,
je->name);
+ if (datlen + 10 + je->namelen > buflen) {
+ do {
+ buflen += 1024;
+ } while (datlen + 10 + je->namelen > buflen);
+ char *newbuf = GDKrealloc(buffer, buflen);
+ if (newbuf == NULL) {
+ GDKfree(buffer);
+ BBPreclaim(bn);
+ return NULL;
+ }
+ buffer = newbuf;
+ }
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"%.*s : ", (int) je->namelen, je->name);
}
- if (je->value)
- mnstr_printf(fd, "%.*s", (int) je->valuelen, je->value);
- mnstr_printf(fd, "\n");
+ if (je->value) {
+ if (datlen + 10 + je->valuelen > buflen) {
+ do {
+ buflen += 1024;
+ } while (datlen + 10 + je->valuelen > buflen);
+ char *newbuf = GDKrealloc(buffer, buflen);
+ if (newbuf == NULL) {
+ GDKfree(buffer);
+ BBPreclaim(bn);
+ return NULL;
+ }
+ buffer = newbuf;
+ }
+ datlen += snprintf(buffer + datlen, buflen - datlen,
"%.*s", (int) je->valuelen, je->value);
+ }
+ if (BUNappend(bn, buffer, false) != GDK_SUCCEED) {
+ BBPreclaim(bn);
+ GDKfree(buffer);
+ return NULL;
+ }
}
+ GDKfree(buffer);
+ return bn;
}
static str
JSONdump(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
(void) mb;
+ (void) cntxt;
+ bat *ret = getArgReference_bat(stk, pci, 0);
json *val = (json*) getArgReference(stk, pci, 1);
JSON *jt = JSONparse(*val);
CHECK_JSON(jt);
- JSONdumpInternal(cntxt->fdout, jt, 0);
+ BAT *bn = JSONdumpInternal(jt, 0);
JSONfree(jt);
+ if (bn == NULL)
+ throw(MAL, "json.dump", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ BBPkeepref(*ret = bn->batCacheid);
return MAL_SUCCEED;
}
@@ -2656,7 +2714,7 @@ static mel_func json_init_funcs[] = {
command("json", "text", JSONjson2textSeparator, false, "Convert JSON values
to their plain string equivalent, injecting a separator.", args(1,3,
arg("",str),arg("j",json),arg("s",str))),
command("json", "number", JSONjson2number, false, "Convert simple JSON values
to a double, return nil upon error.", args(1,2, arg("",dbl),arg("j",json))),
command("json", "integer", JSONjson2integer, false, "Convert simple JSON
values to an integer, return nil upon error.", args(1,2,
arg("",lng),arg("j",json))),
- pattern("json", "dump", JSONdump, false, "", args(1,2,
arg("",void),arg("j",json))),
+ pattern("json", "dump", JSONdump, false, "", args(1,2,
batarg("",str),arg("j",json))),
command("json", "filter", JSONfilter, false, "Filter all members of an object
by a path expression, returning an array.\nNon-matching elements are skipped.",
args(1,3, arg("",json),arg("name",json),arg("pathexpr",str))),
command("json", "filter", JSONfilterArray_bte, false, "", args(1,3,
arg("",json),arg("name",json),arg("idx",bte))),
command("json", "filter", JSONfilterArrayDefault_bte, false, "", args(1,4,
arg("",json),arg("name",json),arg("idx",bte),arg("other",str))),
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list