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