Changeset: 6f28c3ab6d14 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6f28c3ab6d14
Modified Files:
monetdb5/extras/jaql/Tests/json05.mal
monetdb5/extras/jaql/Tests/json05.stable.out
monetdb5/extras/jaql/json.c
monetdb5/extras/jaql/json.h
monetdb5/extras/jaql/json.mal
Branch: jacqueline
Log Message:
unwrap: give explicit type, can be deduced from unwraptype
Because MAL does type analysis and resolution before execution, we need
to allow the type system to deduce the type of the returned BAT by
unwrap. For that, we need an argument that's the return can be deduced
from. That argument can only be given if one knows what unwrap would
normally return without argument. Hence unwraptype() to return that
type, as a string.
diffs (258 lines):
diff --git a/monetdb5/extras/jaql/Tests/json05.mal
b/monetdb5/extras/jaql/Tests/json05.mal
--- a/monetdb5/extras/jaql/Tests/json05.mal
+++ b/monetdb5/extras/jaql/Tests/json05.mal
@@ -1,13 +1,19 @@
# Test the unwrapping of JSON arrays
(j1,j2,j3,j4,j5,j6,j7) := json.shred("[false,1,2,null,4]");
-a := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7);
+io.print(t);
+a := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0:lng);
io.print(a);
(j1,j2,j3,j4,j5,j6,j7) := json.shred("[1,true,2.3,null,4]");
-b := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7);
+io.print(t);
+b := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0:dbl);
io.print(b);
(j1,j2,j3,j4,j5,j6,j7) := json.shred("[1,2.3,null,4,\"4\",true]");
-c := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7);
+io.print(t);
+c := json.unwrap(j1,j2,j3,j4,j5,j6,j7,"":str);
io.print(c);
diff --git a/monetdb5/extras/jaql/Tests/json05.stable.out
b/monetdb5/extras/jaql/Tests/json05.stable.out
--- a/monetdb5/extras/jaql/Tests/json05.stable.out
+++ b/monetdb5/extras/jaql/Tests/json05.stable.out
@@ -18,15 +18,22 @@ stdout of test 'json05` in directory 'ex
function user.main():void;
# Test the unwrapping of JSON arrays
(j1,j2,j3,j4,j5,j6,j7) := json.shred("[false,1,2,null,4]");
- a := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+ t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7);
+ io.print(t);
+ a := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0:lng);
io.print(a);
(j1,j2,j3,j4,j5,j6,j7) := json.shred("[1,true,2.3,null,4]");
- b := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+ t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7);
+ io.print(t);
+ b := json.unwrap(j1,j2,j3,j4,j5,j6,j7,0:dbl);
io.print(b);
(j1,j2,j3,j4,j5,j6,j7) := json.shred("[1,2.3,null,4,\"4\",true]");
- c := json.unwrap(j1,j2,j3,j4,j5,j6,j7);
+ t := json.unwraptype(j1,j2,j3,j4,j5,j6,j7);
+ io.print(t);
+ c := json.unwrap(j1,j2,j3,j4,j5,j6,j7,"":str);
io.print(c);
end main;
+[ "lng" ]
#-----------------#
# h t # name
# oid lng # type
@@ -36,6 +43,7 @@ end main;
[ 0@0, 2 ]
[ 0@0, nil ]
[ 0@0, 4 ]
+[ "dbl" ]
#---------------------------------#
# h t # name
# oid dbl # type
@@ -45,6 +53,7 @@ end main;
[ 0@0, 2.2999999999999998 ]
[ 0@0, nil ]
[ 0@0, 4 ]
+[ "str" ]
#---------------------------------#
# h t # name
# oid str # type
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
@@ -980,37 +980,21 @@ JSONwrap(int *rkind, int *rstring, int *
}
str
-JSONunwrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+JSONunwraptype(str *ret, int *kind, int *string, int *integer, int *doble, int
*array, int *object, int *name)
{
- int *ret = (int *)getArgReference(stk, pci, 0);
- int *kind = (int *)getArgReference(stk, pci, 1);
- int *string = (int *)getArgReference(stk, pci, 2);
- int *integer = (int *)getArgReference(stk, pci, 3);
- int *doble = (int *)getArgReference(stk, pci, 4);
- int *array = (int *)getArgReference(stk, pci, 5);
- int *object = (int *)getArgReference(stk, pci, 6);
- int *name = (int *)getArgReference(stk, pci, 7);
jsonbat jb;
- BATiter bi, bis, bii, bid;
- BAT *b, *r;
+ BAT *b;
+ BATiter bi;
BUN p, q;
- oid v = 0, x;
- lng l;
- dbl d;
- str s;
- char buf[24];
enum typeorder {tlng, tdbl, tstr} totype = tlng;
- (void)mb;
- (void)cntxt;
-
loadbats();
/* find types of outermost array */
bi = bat_iterator(jb.kind);
if (*(bte *)BUNtail(bi, BUNfirst(jb.kind)) != 'a') {
unloadbats();
- throw(MAL, "json.unwrap", "JSON value must be an array");
+ throw(MAL, "json.unwraptype", "JSON value must be an array");
}
b = BATselect(BATmirror(jb.array),
BUNhead(bi, BUNfirst(jb.kind)),
@@ -1034,12 +1018,72 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
break;
}
}
-
+
+ if (totype == tlng) {
+ *ret = GDKstrdup("lng");
+ } else if (totype == tdbl) {
+ *ret = GDKstrdup("dbl");
+ } else {
+ *ret = GDKstrdup("str");
+ }
+ return MAL_SUCCEED;
+}
+
+str
+JSONunwrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+ int *ret = (int *)getArgReference(stk, pci, 0);
+ int *kind = (int *)getArgReference(stk, pci, 1);
+ int *string = (int *)getArgReference(stk, pci, 2);
+ int *integer = (int *)getArgReference(stk, pci, 3);
+ int *doble = (int *)getArgReference(stk, pci, 4);
+ int *array = (int *)getArgReference(stk, pci, 5);
+ int *object = (int *)getArgReference(stk, pci, 6);
+ int *name = (int *)getArgReference(stk, pci, 7);
+ ValPtr tpe = getArgReference(stk, pci, 8);
+ jsonbat jb;
+ BATiter bi, bis, bii, bid;
+ BAT *b, *r;
+ BUN p, q;
+ oid v = 0, x;
+ lng l;
+ dbl d;
+ str s;
+ char buf[24];
+
+ (void)mb;
+ (void)cntxt;
+
+ switch (tpe->vtype) {
+ case TYPE_str:
+ case TYPE_dbl:
+ case TYPE_lng:
+ /* ok, can do these */
+ break;
+ default:
+ throw(MAL, "json.unwrap", "can only unwrap to "
+ "str, dbl and lng values");
+ }
+
+ loadbats();
+
+ /* find types of outermost array */
+ bi = bat_iterator(jb.kind);
+ if (*(bte *)BUNtail(bi, BUNfirst(jb.kind)) != 'a') {
+ unloadbats();
+ throw(MAL, "json.unwraptype", "JSON value must be an array");
+ }
+ b = BATselect(BATmirror(jb.array),
+ BUNhead(bi, BUNfirst(jb.kind)),
+ BUNhead(bi, BUNfirst(jb.kind)));
+ b = BATsemijoin(jb.kind, b);
+ bi = bat_iterator(b);
+
bis = bat_iterator(jb.string);
bii = bat_iterator(jb.integer);
bid = bat_iterator(jb.doble);
- switch (totype) {
- case tstr:
+ switch (tpe->vtype) {
+ case TYPE_str:
r = BATnew(TYPE_oid, TYPE_str, BATcount(b));
BATloop(b, p, q) {
switch (*(bte *)BUNtail(bi, p)) {
@@ -1079,10 +1123,15 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
}
}
break;
- case tdbl:
+ case TYPE_dbl:
r = BATnew(TYPE_oid, TYPE_dbl, BATcount(b));
BATloop(b, p, q) {
switch (*(bte *)BUNtail(bi, p)) {
+ case 's':
+ BUNfndOID(x, bis, BUNhead(bi,
p));
+ d = atof((str)BUNtail(bis, x));
+ BUNins(r, &v, &d, FALSE);
+ break;
case 'i':
BUNfndOID(x, bii, BUNhead(bi,
p));
d = (dbl)*(lng *)BUNtail(bii,
x);
@@ -1107,10 +1156,20 @@ JSONunwrap(Client cntxt, MalBlkPtr mb, M
}
}
break;
- case tlng:
+ case TYPE_lng:
r = BATnew(TYPE_oid, TYPE_lng, BATcount(b));
BATloop(b, p, q) {
switch (*(bte *)BUNtail(bi, p)) {
+ case 's':
+ BUNfndOID(x, bis, BUNhead(bi,
p));
+ l = atoi((str)BUNtail(bis, x));
+ BUNins(r, &v, &l, FALSE);
+ break;
+ case 'd':
+ BUNfndOID(x, bid, BUNhead(bi,
p));
+ l = (lng)*(dbl *)BUNtail(bis,
x);
+ BUNins(r, &v, &l, FALSE);
+ break;
case 'i':
BUNfndOID(x, bii, BUNhead(bi,
p));
BUNins(r, &v, BUNtail(bii, x),
FALSE);
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
@@ -42,6 +42,7 @@ json_export str JSONload(int *kind, int
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);
+json_export str JSONunwraptype(str *ret, int *kind, int *string, int *integer,
int *doble, int *array, int *object, int *name);
json_export str JSONunwrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr
pci);
#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
@@ -45,6 +45,10 @@ command wrap(elems:bat[:oid,:any])(kind:
address JSONwrap
comment "Wrap the given BAT inside a JSON array";
-pattern
unwrap(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])(:bat[:oid,:any])
+command
unwraptype(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]):str
+address JSONunwraptype
+comment "Retrieve the type necessary to unwrap the given JSON array to";
+
+pattern
unwrap(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],
tpe:any_1)(:bat[:oid,:any_1])
address JSONunwrap
-comment "Return the outermost JSON array elements as BAT performing the
necessary casts";
+comment "Return the outermost JSON array elements as BAT with tail type tpe
performing the necessary casts";
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list