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

Reply via email to