Changeset: a44844d922ae for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a44844d922ae
Branch: newjson
Log Message:

merge nested


diffs (truncated from 1339 to 300 lines):

diff --git a/clients/Tests/MAL-signatures-hge.test 
b/clients/Tests/MAL-signatures-hge.test
--- a/clients/Tests/MAL-signatures-hge.test
+++ b/clients/Tests/MAL-signatures-hge.test
@@ -49147,7 +49147,12 @@ sql
 from_json
 pattern sql.from_json(X_0:json, X_1:ptr):bat[:any]...
 SQLfrom_json
-Reads json string into table of nested structures
+Reads json string into table of nested/multiset structures
+sql
+from_varchar
+pattern sql.from_varchar(X_0:str, X_1:ptr):bat[:any]...
+SQLfrom_varchar
+Reads string into table of nested/multiset structures
 sql
 getVariable
 pattern sql.getVariable(X_0:int, X_1:str, X_2:str):any_1
diff --git a/clients/Tests/MAL-signatures.test 
b/clients/Tests/MAL-signatures.test
--- a/clients/Tests/MAL-signatures.test
+++ b/clients/Tests/MAL-signatures.test
@@ -37602,7 +37602,12 @@ sql
 from_json
 pattern sql.from_json(X_0:json, X_1:ptr):bat[:any]...
 SQLfrom_json
-Reads json string into table of nested structures
+Reads json string into table of nested/multiset structures
+sql
+from_varchar
+pattern sql.from_varchar(X_0:str, X_1:ptr):bat[:any]...
+SQLfrom_varchar
+Reads string into table of nested/multiset structures
 sql
 getVariable
 pattern sql.getVariable(X_0:int, X_1:str, X_2:str):any_1
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -791,6 +791,8 @@ str COPYrejects(Client cntxt, MalBlkPtr 
 str COPYrejects_clear(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
 str GRPgroup1(bat *ngid, bat *next, bat *nhis, const bat *bid);
 str GRPsubgroup5(bat *ngid, bat *next, bat *nhis, const bat *bid, const bat 
*sid, const bat *gid, const bat *eid, const bat *hid);
+void JSONfree(JSON *jt);
+JSON *JSONparse(const char *j);
 int MAL_MAXCLIENTS;
 int MALcommentsOnly(MalBlkPtr mb);
 lng MALdebug;
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -1045,7 +1045,6 @@ mvc_renumber_bulk(Client cntxt, MalBlkPt
        /* if oi is dense, use offset based renumbers */
        if (!bo->tsorted || !BATtkey(bo) || (bcnt && (oi[0] + (int)(bcnt-1)) != 
oi[bcnt-1]) ) {
                BAT *lo = NULL;
-               printf("not dense %d\n", oi[0]);
                if (BATleftjoin(&lo, NULL, bo, i, NULL, NULL, false, cnt) != 
GDK_SUCCEED) {
                        BBPreclaim(i);
                        BBPreclaim(bo);
@@ -5866,6 +5865,109 @@ bailout:
        throw(SQL, "SQLfrom_json", SQLSTATE(HY013) MAL_MALLOC_FAIL);
 }
 
+#define skipspace(s) while(*s && isspace(*s)) s++;
+
+static str
+ARRAYparser(char *s, BAT **bats, int nr, int elm, int id, int oanr, 
sql_subtype *t)
+{
+       (void)bats;
+       (void)nr;
+       if (!s && s[0] != '{')
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing { at 
start of array value");
+       s++;
+       skipspace(s);
+       /* insert id */
+       (void)id;
+       (void)oanr;
+       elm++;
+       int oelm = elm;
+       while (*s && s[0] != '}') {
+               elm = oelm;
+               /* insert values */
+               if (t->type->composite) {
+                       if (*s && s[0] != '(')
+                               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) 
"missing ( at start of composite value");
+                       /* handle composite */
+                       for (node *n = t->type->d.fields->h; n; n = n->next) {
+                               //sql_arg *f = n->data;
+                               elm++;
+                       }
+                       if (*s && s[0] != ')')
+                               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) 
"missing ( at end of composite value");
+               } else {
+                       /* handle literals */
+                       elm++;
+               }
+               /* insert msid */
+               elm++;
+               if (t->multiset == MS_ARRAY) {
+                       /* insert msnr */
+                       elm++;
+               }
+
+               skipspace(s);
+               /* handle optinal ',' */
+               if (*s && s[0] != ',')
+                       break;
+               s++;
+               skipspace(s);
+       }
+       if (!s || s[0] != '}')
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing } at end 
of array value");
+       return MAL_SUCCEED;
+}
+
+static str
+SQLfrom_varchar(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+       (void)cntxt;
+       str msg = NULL;
+       int mtype = getArgType(mb, pci, pci->retc);
+
+       if (mtype != TYPE_str)
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(HY013) "Incorrect 
argument type");
+       str s = *(str*)getArgReference(stk, pci, pci->retc);
+       sql_subtype *t = *(sql_subtype**)getArgReference(stk, pci, pci->retc+1);
+
+       BAT **bats = (BAT**)GDKzalloc(sizeof(BAT*) * pci->retc);
+       if (!bats)
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+       for(int i = 0; i < pci->retc; i++) {
+               bats[i] = COLnew(0, getBatType(getArgType(mb, pci, i)), 10, 
TRANSIENT);
+               if (!bats[i])
+                       goto bailout;
+       }
+
+       /*
+       JSON *js = JSONparse(s);
+       if (!js)
+               goto bailout;
+
+       if (t->multiset)
+               (void)insert_json_array(&msg, js, bats, pci->retc, 0, 1, 1, t);
+       JSONfree(js);
+       */
+
+       assert(t->multiset);
+       /* this should parse { 1, 2,3 } and { (1,"string"), (2,"str2") } */
+       msg = ARRAYparser(s, bats, pci->retc, 0, 1, 1, t);
+       if (msg)
+               goto bailout;
+       for(int i = 0; i < pci->retc && bats[i]; i++) {
+               *getArgReference_bat(stk, pci, i) = bats[i]->batCacheid;
+               BBPkeepref(bats[i]);
+       }
+       GDKfree(bats);
+       return MAL_SUCCEED;
+bailout:
+       for(int i = 0; i < pci->retc && bats[i]; i++)
+               BBPreclaim(bats[i]);
+       GDKfree(bats);
+       if (msg)
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "%s", msg);
+       throw(SQL, "SQLfrom_varchar", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+}
+
 static mel_func sql_init_funcs[] = {
  pattern("sql", "shutdown", SQLshutdown_wrap, true, "", args(1,3, 
arg("",str),arg("delay",bte),arg("force",bit))),
  pattern("sql", "shutdown", SQLshutdown_wrap, true, "", args(1,3, 
arg("",str),arg("delay",sht),arg("force",bit))),
@@ -6818,7 +6920,8 @@ static mel_func sql_init_funcs[] = {
  pattern("sql", "stop_vacuum", SQLstr_stop_vacuum, true, "stop auto vacuum", 
args(0,2, arg("sname",str),arg("tname",str))),
  pattern("sql", "check", SQLcheck, false, "Return sql string of check 
constraint.", args(1,3, arg("sql",str), arg("sname", str), arg("name", str))),
  pattern("sql", "read_dump_rel", SQLread_dump_rel, false, "Reads sql_rel 
string into sql_rel object and then writes it to the return value", args(1,2, 
arg("sql",str), arg("sql_rel", str))),
- pattern("sql", "from_json", SQLfrom_json, false, "Reads json string into 
table of nested structures", args(1,3, batvarargany("t",0), arg("input", json), 
arg("type", ptr))),
+ pattern("sql", "from_json", SQLfrom_json, false, "Reads json string into 
table of nested/multiset structures", args(1,3, batvarargany("t",0), 
arg("input", json), arg("type", ptr))),
+ pattern("sql", "from_varchar", SQLfrom_varchar, false, "Reads string into 
table of nested/multiset structures", args(1,3, batvarargany("t",0), 
arg("input", str), arg("type", ptr))),
  { .imp=NULL }
 };
 #include "mal_import.h"
diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -3947,7 +3947,7 @@ composite_type_resultsize(sql_subtype *t
        int nr = 0;
 
        if (t->multiset)
-               nr += 1 + (t->multiset == MS_ARRAY) + t->type->composite;
+               nr += 2 + (t->multiset == MS_ARRAY);
        if (t->type->composite) {
                for (node *n = t->type->d.fields->h; n; n = n->next) {
                        sql_arg *a = n->data;
@@ -3960,24 +3960,39 @@ composite_type_resultsize(sql_subtype *t
 }
 
 static int
-composite_type_result(backend *be, InstrPtr q, sql_subtype *t)
+composite_type_result(backend *be, InstrPtr q, sql_subtype *t, sql_subtype 
*tps)
 {
-       if (t->type->composite) {
-               if (t->multiset) /* id col : rowid */
+       int i = 0;
+       if (t->multiset || t->type->composite) {
+               if (t->multiset) { /* id col : rowid */
                        q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(TYPE_int)));
-               for (node *n = t->type->d.fields->h; n; n = n->next) {
-                       sql_arg *a = n->data;
-                       if (composite_type_result(be, q, &a->type) != 0)
-                               return -1;
+                       tps[i++] = *sql_bind_localtype("int");
                }
-               if (t->multiset) /* msid */
+               if (t->type->composite) {
+                       for (node *n = t->type->d.fields->h; n; n = n->next) {
+                               sql_arg *a = n->data;
+                               int r = 0;
+                               if ((r = composite_type_result(be, q, &a->type, 
tps+i)) < 0)
+                                       return -1;
+                               i += r;
+                       }
+               } else {
+                       q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(t->type->localtype)));
+                       tps[i++] = *t;
+               }
+               if (t->multiset) { /* msid */
                        q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(TYPE_int)));
-               if (t->multiset == MS_ARRAY) /* msnr */
+                       tps[i++] = *sql_bind_localtype("int");
+               }
+               if (t->multiset == MS_ARRAY) { /* msnr */
                        q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(TYPE_int)));
+                       tps[i++] = *sql_bind_localtype("int");
+               }
        } else {
                q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(t->type->localtype)));
+               tps[i++] = *t;
        }
-       return 0;
+       return i;
 }
 
 static stmt *
@@ -3985,13 +4000,14 @@ stmt_from_json(backend *be, stmt *v, stm
 {
        (void)sel;
        int nrcols = composite_type_resultsize(t);
+       sql_subtype *tps = SA_NEW_ARRAY(be->mvc->sa, sql_subtype, nrcols);
 
        InstrPtr q = newStmtArgs(be->mb, "sql", "from_json", nrcols + 2);
        if (q == NULL)
                goto bailout;
 
        q->retc = q->argc = 0;
-       if (composite_type_result(be, q, t) != 0) {
+       if (composite_type_result(be, q, t, tps) < 0) {
                freeInstruction(q);
                goto bailout;
        }
@@ -4008,7 +4024,7 @@ stmt_from_json(backend *be, stmt *v, stm
                goto bailout;
        }
        s->op1 = v;
-       s->nrcols = nrcols;     /* function without arguments returns single 
value */
+       s->nrcols = nrcols?2:1;
        s->key = v->key;
        s->aggr = v->aggr;
        s->op4.typeval = *t;
@@ -4019,7 +4035,55 @@ stmt_from_json(backend *be, stmt *v, stm
        /* for each result create stmt_result and return stmt list */
        list *r = sa_list(be->mvc->sa);
        for(int i = 0; i < nrcols; i++)
-               append(r, stmt_result(be, s, i));
+               append(r, stmt_blackbox_result(be, s->q, i, tps+i));
+       return stmt_list(be, r);
+bailout:
+       if (be->mvc->sa->eb.enabled)
+               eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr 
: be->mb->errors ? be->mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 
1000);
+       return NULL;
+}
+
+static stmt *
+stmt_from_varchar(backend *be, stmt *v, stmt *sel, sql_subtype *t)
+{
+       (void)sel;
+       int nrcols = composite_type_resultsize(t);
+       sql_subtype *tps = SA_NEW_ARRAY(be->mvc->sa, sql_subtype, nrcols);
+
+       InstrPtr q = newStmtArgs(be->mb, "sql", "from_varchar", nrcols + 2);
+       if (q == NULL)
+               goto bailout;
+
+       q->retc = q->argc = 0;
+       if (composite_type_result(be, q, t, tps) < 0) {
+               freeInstruction(q);
+               goto bailout;
+       }
+
+       q = pushArgument(be->mb, q, v->nr);
+       q = pushPtr(be->mb, q, t);
+
+       bool enabled = be->mvc->sa->eb.enabled;
+       be->mvc->sa->eb.enabled = false;
+       stmt *s = stmt_create(be->mvc->sa, st_convert);
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to