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