Changeset: b8e57d47ff64 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b8e57d47ff64
Modified Files:
        monetdb5/modules/atoms/Tests/json03.stable.out
        monetdb5/modules/atoms/json_atom.c
        monetdb5/modules/atoms/json_atom.h
        monetdb5/modules/atoms/json_atom.mal
Branch: default
Log Message:

Implementation of nest/unnest operations for JSON


diffs (truncated from 439 to 300 lines):

diff --git a/monetdb5/modules/atoms/Tests/json03.stable.out 
b/monetdb5/modules/atoms/Tests/json03.stable.out
--- a/monetdb5/modules/atoms/Tests/json03.stable.out
+++ b/monetdb5/modules/atoms/Tests/json03.stable.out
@@ -21,10 +21,40 @@ stdout of test 'json03` in directory 'mo
 function user.main():void;
     js := calc.json("[{ \"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 }, { \"color\": \"red\", \"price\": 19.95 }]");
     io.print(js);
-    (k,v) := json.pairs(js);
+    (k,v) := json.unnest(js);
     io.print(k,v);
-    (o,k,v) := json.pairs(js);
-    io.print(o,k,v);
+    jsn := json.nest(k,v);
+    io.print(jsn);
+    (o,l,w) := json.unnest(js);
+    io.print(o,l,w);
+    jsm := json.nest(o,l,w);
+    io.print(jsm);
+    b := bat.new(:oid,:int);
+    bat.append(b,1);
+    bat.append(b,22);
+    bat.append(b,333);
+    bl := json.nest(b);
+    io.print(bl);
+# create comple structure 
+    bat.append(b,2);
+    bat.append(b,3);
+    bat.append(b,4);
+    n := bat.new(:oid,:str);
+    bat.append(n,"a");
+    bat.append(n,"b");
+    bat.append(n,"c");
+    bat.append(n,"a");
+    bat.append(n,"c");
+    bat.append(n,"b");
+    i := bat.new(:oid,:oid);
+    bat.append(i,0@0);
+    bat.append(i,0@0);
+    bat.append(i,0@0);
+    bat.append(i,1@0);
+    bat.append(i,1@0);
+    bat.append(i,2@0);
+    jsn := json.nest(i,n,b);
+    io.print(jsn);
 end main;
 [ "[{ \"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 }, { \"color\": \"red\", 
\"price\": 19.95 }]" ]
 #---------------------------------------------------------#
@@ -51,6 +81,7 @@ end main;
 [ 17@0,          "price",        "22.99 "                        ]
 [ 18@0,          "color",        "\"red\""                       ]
 [ 19@0,          "price",        "19.95 "                        ]
+[ "[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings 
of the Century\",\"price\":.9\",\"category\":\"fiction\",\"author\":\"Evelyn 
Waugh\",\"title\":\"Sword of 
Honour\",\"price\":2.9\",\"category\":\"fiction\",\"author\":\"Herman 
Melville\",\"title\":\"Moby 
Dick\",\"isbn\":\"0-553-21311-3\",\"price\":.9\",\"category\":\"fiction\",\"author\":\"J.
 R. R. Tolkien\",\"title\":\"The Lord of the 
Rings\",\"isbn\":\"0-395-19395-8\",\"price\":2.9\",\"color\":\"red\",\"price\":9.9\"}]"
 ]
 #-----------------------------------------------------------------#
 # h    t       t               t                                 # name
 # void oid     str             json                              # type
@@ -75,6 +106,9 @@ end main;
 [ 17@0,          3@0,    "price",        "22.99 "                        ]
 [ 18@0,          4@0,    "color",        "\"red\""                       ]
 [ 19@0,          4@0,    "price",        "19.95 "                        ]
+[ "[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings 
of the Century\",\"price\":.9\"},{\"category\":\"fiction\",\"author\":\"Evelyn 
Waugh\",\"title\":\"Sword of 
Honour\",\"price\":2.9\"},{\"category\":\"fiction\",\"author\":\"Herman 
Melville\",\"title\":\"Moby 
Dick\",\"isbn\":\"0-553-21311-3\",\"price\":.9\"},{\"category\":\"fiction\",\"author\":\"J.
 R. R. Tolkien\",\"title\":\"The Lord of the 
Rings\",\"isbn\":\"0-395-19395-8\",\"price\":2.9\"},{\"color\":\"red\",\"price\":9.9\"}]"
 ]
+[ "[1,22,333]" ]
+[ "[{\"a\":1,\"b\":22,\"c\":333},{\"a\":2,\"c\":3},{\"b\":4}]" ]
 
 # 19:03:08 >  
 # 19:03:08 >  "Done."
diff --git a/monetdb5/modules/atoms/json_atom.c 
b/monetdb5/modules/atoms/json_atom.c
--- a/monetdb5/modules/atoms/json_atom.c
+++ b/monetdb5/modules/atoms/json_atom.c
@@ -578,7 +578,7 @@ wrapup:;
        return msg;
 }
 
-str JSONpairs(int *key, int *val, json *js)
+str JSONunnest(int *key, int *val, json *js)
 {
        BAT *bk, *bv;
        char  *namebegin,*nameend;
@@ -590,7 +590,7 @@ str JSONpairs(int *key, int *val, json *
 
        bk = BATnew(TYPE_void,TYPE_str,64);
        if ( bk == NULL)
-               throw(MAL,"json.names",MAL_MALLOC_FAIL);
+               throw(MAL,"json.unnest",MAL_MALLOC_FAIL);
        BATseqbase(bk,0);
        bk->hsorted = 1;
        bk->hrevsorted = 0;
@@ -602,7 +602,7 @@ str JSONpairs(int *key, int *val, json *
        bv = BATnew(TYPE_void,TYPE_json,64);
        if ( bv == NULL){
                BBPreleaseref(bk->batCacheid);
-               throw(MAL,"json.names",MAL_MALLOC_FAIL);
+               throw(MAL,"json.unnest",MAL_MALLOC_FAIL);
        }
        BATseqbase(bv,0);
        bv->hsorted = 1;
@@ -618,14 +618,14 @@ str JSONpairs(int *key, int *val, json *
                j++;
        }
        if ( *j != '{' )
-               throw(MAL,"json.filter","JSON object expected");
+               throw(MAL,"json.unnest","JSON object expected");
        
        // the result is an array of values
        result = (char *) GDKmalloc(BUFSIZ);
        if ( result == 0){
                BBPreleaseref(bk->batCacheid);
                BBPreleaseref(bv->batCacheid);
-               throw(MAL,"json.names",MAL_MALLOC_FAIL);
+               throw(MAL,"json.unnest",MAL_MALLOC_FAIL);
        }
        lim = BUFSIZ;
 
@@ -637,7 +637,7 @@ str JSONpairs(int *key, int *val, json *
                if (*j == '}')
                        break;
                if (*j != '"'){
-                       msg = createException(MAL,"json.names","Name expected");
+                       msg = createException(MAL,"json.unnest","Name 
expected");
                        goto wrapup;
                }
                namebegin = j+1;
@@ -654,7 +654,7 @@ str JSONpairs(int *key, int *val, json *
 
                skipblancs;
                if ( *j != ':'){
-                       msg = createException(MAL,"json.names","Value 
expected");
+                       msg = createException(MAL,"json.unnest","Value 
expected");
                        goto wrapup;
                }
                j++;
@@ -680,7 +680,7 @@ str JSONpairs(int *key, int *val, json *
                        continue;
                }
                if (*j != ',')
-                       msg = createException(MAL,"json.names","',' expected");
+                       msg = createException(MAL,"json.unnest","',' expected");
        }
 wrapup:;
        BBPkeepref(*key= bk->batCacheid);
@@ -689,7 +689,7 @@ wrapup:;
        return msg;
 }
 
-str JSONpairsGrouped(int *grp, int *key, int *val, json *js)
+str JSONunnestGrouped(int *grp, int *key, int *val, json *js)
 {
        BAT *bk, *bv, *bg;
        char  *namebegin,*nameend;
@@ -702,7 +702,7 @@ str JSONpairsGrouped(int *grp, int *key,
 
        bk = BATnew(TYPE_void,TYPE_str,64);
        if ( bk == NULL)
-               throw(MAL,"json.names",MAL_MALLOC_FAIL);
+               throw(MAL,"json.unnest",MAL_MALLOC_FAIL);
        BATseqbase(bk,0);
        bk->hsorted = 1;
        bk->hrevsorted = 0;
@@ -714,7 +714,7 @@ str JSONpairsGrouped(int *grp, int *key,
        bv = BATnew(TYPE_void,TYPE_json,64);
        if ( bv == NULL){
                BBPreleaseref(bk->batCacheid);
-               throw(MAL,"json.names",MAL_MALLOC_FAIL);
+               throw(MAL,"json.unnest",MAL_MALLOC_FAIL);
        }
        BATseqbase(bv,0);
        bv->hsorted = 1;
@@ -728,7 +728,7 @@ str JSONpairsGrouped(int *grp, int *key,
        if ( bg == NULL){
                BBPreleaseref(bk->batCacheid);
                BBPreleaseref(bv->batCacheid);
-               throw(MAL,"json.names",MAL_MALLOC_FAIL);
+               throw(MAL,"json.unnest",MAL_MALLOC_FAIL);
        }
        BATseqbase(bg,0);
        bg->hsorted = 1;
@@ -744,14 +744,14 @@ str JSONpairsGrouped(int *grp, int *key,
                j++;
        }
        if ( *j != '{' )
-               throw(MAL,"json.filter","JSON object expected");
+               throw(MAL,"json.unnest","JSON object expected");
        
        // the result is an array of values
        result = (char *) GDKmalloc(BUFSIZ);
        if ( result == 0){
                BBPreleaseref(bk->batCacheid);
                BBPreleaseref(bv->batCacheid);
-               throw(MAL,"json.names",MAL_MALLOC_FAIL);
+               throw(MAL,"json.unnest",MAL_MALLOC_FAIL);
        }
        lim = BUFSIZ;
 
@@ -763,7 +763,7 @@ str JSONpairsGrouped(int *grp, int *key,
                if (*j == '}')
                        break;
                if (*j != '"'){
-                       msg = createException(MAL,"json.names","Name expected");
+                       msg = createException(MAL,"json.unnest","Name 
expected");
                        goto wrapup;
                }
                namebegin = j+1;
@@ -780,7 +780,7 @@ str JSONpairsGrouped(int *grp, int *key,
 
                skipblancs;
                if ( *j != ':'){
-                       msg = createException(MAL,"json.names","Value 
expected");
+                       msg = createException(MAL,"json.unnest","Value 
expected");
                        goto wrapup;
                }
                j++;
@@ -810,7 +810,7 @@ str JSONpairsGrouped(int *grp, int *key,
                        continue;
                }
                if (*j != ',')
-                       msg = createException(MAL,"json.names","',' expected");
+                       msg = createException(MAL,"json.unnest","',' expected");
        }
 wrapup:;
        BBPkeepref(*key= bk->batCacheid);
@@ -819,7 +819,6 @@ wrapup:;
        GDKfree(result);
        return msg;
 }
-
 str
 JSONnames(int *ret, json *js)
 {
@@ -1190,3 +1189,145 @@ JSONrenderarray(Client cntxt, MalBlkPtr 
        return MAL_SUCCEED;
 }
 
+static 
+str JSONnestKeyValue(str *ret, int *id, int *key, int *values)
+{
+       BAT *bo=0, *bk=0, *bv;
+       BATiter boi,bki,bvi;
+       int tpe;
+       char *row, *val=0, *nme =0;
+       size_t i, len, lim, l;
+       void *p;
+       BUN cnt;
+       oid o;
+
+       if ( key){
+               bk = BATdescriptor(*key);
+               if ( bk == NULL)
+                       throw(MAL,"json.nest", RUNTIME_OBJECT_MISSING);
+       }
+
+       bv = BATdescriptor(*values);
+       if ( bv == NULL){
+               if(bk) BBPreleaseref(bk->batCacheid);
+               throw(MAL,"json.nest", RUNTIME_OBJECT_MISSING);
+       }
+       tpe = bv->ttype;
+       cnt = BATcount(bv);
+
+       if ( id){
+               bo = BATdescriptor(*id);
+               if ( bo == NULL){
+                       if(bk) BBPreleaseref(bk->batCacheid);
+                       BBPreleaseref(bv->batCacheid);
+                       throw(MAL,"json.nest", RUNTIME_OBJECT_MISSING);
+               }
+       }
+
+       row = (char *) GDKmalloc( lim = BUFSIZ);
+       row[0]='[';
+       row[1]=0;
+       len =1;
+       val = (char *) GDKmalloc( BUFSIZ);
+       if ( id){
+               boi = bat_iterator(bo);
+               o = *(oid*) BUNtail(boi, BUNfirst(bo));
+       }
+       if(bk)
+               bki = bat_iterator(bk);
+       bvi = bat_iterator(bv);
+
+       if ( cnt && bk){
+               row[1]='{';
+               row[2]=0;
+               len =2;
+       }
+
+       for( i = 0; i < cnt; i++){
+               if( id && bk){
+                       p = BUNtail(boi, BUNfirst(bo)+i);
+                       if (*(oid*)p != o){
+                               snprintf(row+len-1,lim -len,"},{");
+                               len +=2;
+                               o = *(oid*)p;
+                       }
+               }
+
+               if( bk) {
+                       nme = (str) BUNtail(bki, BUNfirst(bk)+i);
+                       l = (int) strlen(nme);
+                       if (l+3 > lim-len)
+                                       row= (char*) GDKrealloc(row, lim = 
(lim/(i+1)) * cnt + BUFSIZ+l+3);
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to