Changeset: c357add77275 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/c357add77275
Modified Files:
        clients/Tests/MAL-signatures-hge.test
        clients/Tests/MAL-signatures.test
        clients/Tests/exports.stable.out
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_statement.c
        sql/server/rel_exp.c
        sql/server/rel_multiset.c
        
sql/test/BugDay_2005-10-06_2.9.3/Tests/CrashMe_SQL_server_crash-2.SF-921673.test
        sql/test/BugTracker-2014/Tests/crash_on_or_with_in.Bug-3461.test
        sql/test/BugTracker-2014/Tests/in_incorrect_multi.Bug-3462.test
        sql/test/BugTracker-2019/Tests/alter_table_set_schema.Bug-6701.test
        sql/test/BugTracker-2020/Tests/drop-stream-table.Bug-7005.test
Branch: nested
Log Message:

initial support for reading array values from strings

approved some test outputs


diffs (truncated from 331 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
@@ -5866,6 +5866,53 @@ bailout:
        throw(SQL, "SQLfrom_json", SQLSTATE(HY013) MAL_MALLOC_FAIL);
 }
 
+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) /* TODO output parser error ?? */
+               goto bailout;
+
+       if (t->multiset)
+               (void)insert_json_array(&msg, js, bats, pci->retc, 0, 1, 1, t);
+       else
+               (void)insert_json_object(&msg, js, bats, pci->retc, 0, 1, 1, t);
+       JSONfree(js);
+       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 +6865,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;
@@ -3962,13 +3962,17 @@ composite_type_resultsize(sql_subtype *t
 static int
 composite_type_result(backend *be, InstrPtr q, sql_subtype *t)
 {
-       if (t->type->composite) {
+       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;
+               if (t->type->composite) {
+                       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;
+                       }
+               } else {
+                       q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(t->type->localtype)));
                }
                if (t->multiset) /* msid */
                        q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(TYPE_int)));
@@ -4008,7 +4012,54 @@ 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;
+       s->nr = getDestVar(q);
+       s->q = q;
+       //s->cand = pushed ? sel : NULL;
+       pushInstruction(be->mb, q);
+       /* 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));
+       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);
+
+       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) != 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);
+       be->mvc->sa->eb.enabled = enabled;
+       if(!s) {
+               freeInstruction(q);
+               goto bailout;
+       }
+       s->op1 = v;
+       s->nrcols = nrcols?2:1;
        s->key = v->key;
        s->aggr = v->aggr;
        s->op4.typeval = *t;
@@ -4042,6 +4093,8 @@ stmt_convert(backend *be, stmt *v, stmt 
 
        if (f->type->eclass == EC_EXTERNAL && t->type->composite && 
strcmp(f->type->base.name, "json") == 0)
                return stmt_from_json(be, v, sel, t);
+       if (EC_VARCHAR(f->type->eclass) && (t->type->composite || t->multiset))
+               return stmt_from_varchar(be, v, sel, t);
        if (f->type->eclass != EC_EXTERNAL && t->type->eclass != EC_EXTERNAL &&
                /* general cases */
                ((t->type->localtype == f->type->localtype && t->type->eclass 
== f->type->eclass &&
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -3718,6 +3718,8 @@ exp_check_multiset_type(mvc *sql, sql_su
                /* hard code conversion from json allowed */
                if (strcmp(et->type->base.name, "json") == 0)
                        return exp_convert(sql, exp, et, t);
+               if (EC_VARCHAR(et->type->eclass))
+                       return exp_convert(sql, exp, et, t);
                if (et && et->multiset == t->multiset && subtype_cmp(et, t) == 
0)
                        return exp;
                if (t->type->composite)
diff --git a/sql/server/rel_multiset.c b/sql/server/rel_multiset.c
--- a/sql/server/rel_multiset.c
+++ b/sql/server/rel_multiset.c
@@ -240,7 +240,7 @@ fm_project_ms(visitor *v, sql_exp *e, sq
        //sql_subtype *oidtype = sql_bind_localtype("oid");
        sql_subtype *inttype = sql_bind_localtype("int");
        int label = v->sql->label;
-       v->sql->label += 2 + (t->multiset == MS_ARRAY) + 
list_length(t->type->d.fields);
+       v->sql->label += 2 + (t->multiset == MS_ARRAY) + 
(t->type->composite?list_length(t->type->d.fields):1);
        e = exp_ref(v->sql, e);
        sql_exp *mse = exp_column(v->sql->sa, cn, "rowid", inttype, 1,1, 1, 1);
        mse->alias.label = (++label);
diff --git 
a/sql/test/BugDay_2005-10-06_2.9.3/Tests/CrashMe_SQL_server_crash-2.SF-921673.test
 
b/sql/test/BugDay_2005-10-06_2.9.3/Tests/CrashMe_SQL_server_crash-2.SF-921673.test
--- 
a/sql/test/BugDay_2005-10-06_2.9.3/Tests/CrashMe_SQL_server_crash-2.SF-921673.test
+++ 
b/sql/test/BugDay_2005-10-06_2.9.3/Tests/CrashMe_SQL_server_crash-2.SF-921673.test
@@ -27,5 +27,5 @@ WHERE columns.table_id = tables.id
     'objects', 'keys', 'modules', 'sequences')
 ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION
 ----
-1178 values hashing to 6976ccdc7572fb904e6a9eebae5b5af3
+1197 values hashing to 56f3defdf3e9070754bc7e49db1c6fd4
 
diff --git a/sql/test/BugTracker-2014/Tests/crash_on_or_with_in.Bug-3461.test 
b/sql/test/BugTracker-2014/Tests/crash_on_or_with_in.Bug-3461.test
--- a/sql/test/BugTracker-2014/Tests/crash_on_or_with_in.Bug-3461.test
+++ b/sql/test/BugTracker-2014/Tests/crash_on_or_with_in.Bug-3461.test
@@ -1,4 +1,4 @@
-query IITTIIII rowsort
+query IITTIIIII rowsort
 SELECT * FROM SYS.ARGS
  WHERE FUNC_ID NOT IN (SELECT ID FROM SYS.FUNCTIONS)
     OR FUNC_ID NOT IN (SELECT ID FROM SYS.FUNCTIONS)
diff --git a/sql/test/BugTracker-2014/Tests/in_incorrect_multi.Bug-3462.test 
b/sql/test/BugTracker-2014/Tests/in_incorrect_multi.Bug-3462.test
--- a/sql/test/BugTracker-2014/Tests/in_incorrect_multi.Bug-3462.test
+++ b/sql/test/BugTracker-2014/Tests/in_incorrect_multi.Bug-3462.test
@@ -2,7 +2,7 @@ statement error
 SELECT * FROM SYS.ARGS
  WHERE FUNC_ID NOT IN (SELECT * FROM SYS.FUNCTIONS)
 
-query IITTIIII rowsort
+query IITTIIIII rowsort
 SELECT * FROM SYS.ARGS
  WHERE FUNC_ID NOT IN (SELECT FUNC_ID FROM SYS.FUNCTIONS)
 ----
diff --git 
a/sql/test/BugTracker-2019/Tests/alter_table_set_schema.Bug-6701.test 
b/sql/test/BugTracker-2019/Tests/alter_table_set_schema.Bug-6701.test
--- a/sql/test/BugTracker-2019/Tests/alter_table_set_schema.Bug-6701.test
+++ b/sql/test/BugTracker-2019/Tests/alter_table_set_schema.Bug-6701.test
@@ -1,8 +1,8 @@
-query ITTIIITIITI rowsort
+query ITTIIITIITII rowsort
 SELECT * FROM sys.columns WHERE table_id NOT IN (SELECT id FROM sys.tables)
 ----
 
-query ITTIIITIITI rowsort
+query ITTIIITIITII rowsort
 SELECT * FROM sys._columns WHERE table_id NOT IN (SELECT id FROM sys._tables)
 ----
 
@@ -98,11 +98,11 @@ select count(*) as count_rows from sys.o
 ----
 1
 
-query ITTIIITIITI rowsort
+query ITTIIITIITII rowsort
 SELECT * FROM sys.columns WHERE table_id NOT IN (SELECT id FROM sys.tables)
 ----
 
-query ITTIIITIITI rowsort
+query ITTIIITIITII rowsort
 SELECT * FROM sys._columns WHERE table_id NOT IN (SELECT id FROM sys._tables)
 ----
 
@@ -129,11 +129,11 @@ SELECT * FROM sys.dependencies WHERE dep
 statement ok
 drop table sys.test2
 
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to