Changeset: ab0a7788091a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ab0a7788091a
Modified Files:
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_result.c
        sql/backends/monet5/sql_result.h
        sql/server/sql_scan.c
Branch: nested
Log Message:

support parsing {1,2,3} array values


diffs (truncated from 324 to 300 lines):

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
@@ -5821,8 +5821,13 @@ insert_json_array(char **msg, JSON *js, 
 static str
 SQLfrom_json(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       (void)cntxt;
        str msg = NULL;
+       mvc *m = NULL;
+
+       if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL)
+               return msg;
+       if ((msg = checkSQLContext(cntxt)) != NULL)
+               return msg;
        int mtype = getArgType(mb, pci, pci->retc);
 
        if (strcmp(BATatoms[mtype].name, "json") != 0)
@@ -5838,6 +5843,7 @@ SQLfrom_json(Client cntxt, MalBlkPtr mb,
                if (!bats[i])
                        goto bailout;
        }
+       (void)m;
 
        JSON *js = JSONparse(json);
        if (!js) /* TODO output parser error ?? */
@@ -5865,65 +5871,18 @@ 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;
+       mvc *m = NULL;
+
+       if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL)
+               return msg;
+       if ((msg = checkSQLContext(cntxt)) != NULL)
+               return msg;
+
        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);
@@ -5937,20 +5896,7 @@ SQLfrom_varchar(Client cntxt, MalBlkPtr 
                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);
+       msg = mvc_from_string(m, bats, pci->retc, s, t);
        if (msg)
                goto bailout;
        for(int i = 0; i < pci->retc && bats[i]; i++) {
diff --git a/sql/backends/monet5/sql_result.c b/sql/backends/monet5/sql_result.c
--- a/sql/backends/monet5/sql_result.c
+++ b/sql/backends/monet5/sql_result.c
@@ -302,8 +302,7 @@ bat_max_length(hge, hge)
 
 #define DEC_FRSTR(X)                                                           
                                        \
        do {                                                                    
                                                        \
-               sql_column *col = c->extra;                                     
                                        \
-               sql_subtype *t = &col->type;                                    
                                \
+               sql_subtype *t = c->extra;                                      
                                        \
                unsigned int scale = t->scale;                                  
                                \
                unsigned int i;                                                 
                                                \
                bool neg = false;                                               
                                                \
@@ -534,10 +533,10 @@ static void *
                }
                break;
        case TYPE_str: {
-               sql_column *col = (sql_column *) c->extra;
+               sql_subtype *t = c->extra;
 
                s = c->data;
-               if (col->type.digits > 0 && len > 0 && !strNil(s) && 
UTF8_strlen(s) > (int) col->type.digits) {
+               if (t->digits > 0 && len > 0 && !strNil(s) && UTF8_strlen(s) > 
(int) t->digits) {
                        return NULL;
                }
                break;
@@ -660,7 +659,7 @@ mvc_import_table(Client cntxt, BAT ***ba
                        fmt[i].adt = ATOMindex(col->type.type->d.impl);
                        fmt[i].tostr = &_ASCIIadt_toStr;
                        fmt[i].frstr = &_ASCIIadt_frStr;
-                       fmt[i].extra = col;
+                       fmt[i].extra = &col->type;
                        fmt[i].len = ATOMlen(fmt[i].adt, 
ATOMnilptr(fmt[i].adt));
                        fmt[i].data = GDKzalloc(fmt[i].len);
                        if(fmt[i].data == NULL || fmt[i].type == NULL) {
@@ -2062,3 +2061,131 @@ end:
        mnstr_destroy(countstream);
        return ret;
 }
+
+#define skipspace(s) while(*s && isspace(*s)) s++;
+
+static str
+ARRAYparser(char *s, Column *cols, int nr, int elm, int id, int oanr, 
sql_subtype *t)
+{
+       (void)cols;
+       (void)nr;
+       (void)oanr;
+       if (!s && s[0] != '{')
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing { at 
start of array value");
+       s++;
+       skipspace(s);
+       int anr = 1;
+       /* insert id */
+       if (elm >= 0 && BUNappend(cols[elm].c, &id, false) != GDK_SUCCEED)
+               elm = -2;
+       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 */
+                       char *ns = strchr(s, ',');
+                       if (!ns) {
+                               ns = strchr(s, '}');
+                       }
+                       char sep = 0;
+                       if (!ns)
+                               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) 
"missing } at end of array value");
+                       else {
+                               sep = *ns;
+                               *ns = 0;
+                       }
+                       void *d = cols[elm].frstr(cols+elm, cols[elm].adt, s);
+                       if (elm >= 0 && d && BUNappend(cols[elm].c, d, false) 
!= GDK_SUCCEED)
+                               elm = -2;
+                       elm++;
+                       *ns = sep;
+                       s = ns;
+               }
+               /* insert msid */
+               if (elm >= 0 && BUNappend(cols[elm].c, &id, false) != 
GDK_SUCCEED)
+                       elm = -2;
+               elm++;
+               if (t->multiset == MS_ARRAY) {
+                       /* insert msnr */
+                       if (elm >= 0 && BUNappend(cols[elm].c, &anr, false) != 
GDK_SUCCEED)
+                               elm = -2;
+                       elm++;
+               }
+
+               skipspace(s);
+               /* handle optinal ',' */
+               if (*s && s[0] != ',')
+                       break;
+               s++;
+               skipspace(s);
+               anr++;
+       }
+       if (!s || s[0] != '}')
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing } at end 
of array value");
+       return MAL_SUCCEED;
+}
+
+str
+mvc_from_string(mvc *m, BAT **bats, int nr, char *s, sql_subtype *t)
+{
+       str msg = MAL_SUCCEED;
+
+       if (!t || !t->multiset)
+               throw(SQL, "sql.from_varchar", SQLSTATE(HY013) "Multiset type 
expected");
+       Column *fmt = (Column *) GDKzalloc(sizeof(Column) * nr);
+       if (!fmt)
+               throw(SQL, "sql.from_varchar", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+
+       int i = 0;
+
+       (void)m;
+       fmt[i].frstr = &_ASCIIadt_frStr;
+       fmt[i].extra = sql_bind_localtype("int");
+       fmt[i].adt = TYPE_int;
+       fmt[i].len = ATOMlen(fmt[i].adt, ATOMnilptr(fmt[i].adt));
+       fmt[i].c = bats[i];
+       i++;
+       if (t->type->composite) {
+               printf("todo implement composite type array values\n");
+       } else {
+               fmt[i].frstr = &_ASCIIadt_frStr;
+               fmt[i].extra = t;
+               fmt[i].adt = t->type->localtype;
+               fmt[i].len = ATOMlen(fmt[i].adt, ATOMnilptr(fmt[i].adt));
+               fmt[i].c = bats[i];
+               i++;
+       }
+       /* msid */
+       fmt[i].frstr = &_ASCIIadt_frStr;
+       fmt[i].extra = sql_bind_localtype("int");
+       fmt[i].adt = TYPE_int;
+       fmt[i].len = ATOMlen(fmt[i].adt, ATOMnilptr(fmt[i].adt));
+       fmt[i].c = bats[i];
+       i++;
+       /* msnr */
+       if (t->multiset == MS_ARRAY) {
+               fmt[i].frstr = &_ASCIIadt_frStr;
+               fmt[i].extra = sql_bind_localtype("int");
+               fmt[i].adt = TYPE_int;
+               fmt[i].len = ATOMlen(fmt[i].adt, ATOMnilptr(fmt[i].adt));
+               fmt[i].c = bats[i];
+               i++;
+       }
+       /* this should parse { 1, 2,3 } and { (1,"string"), (2,"str2") } */
+       msg = ARRAYparser(s, fmt, nr, 0, 1, 1, t);
+       GDKfree(fmt);
+       return msg;
+}
+
diff --git a/sql/backends/monet5/sql_result.h b/sql/backends/monet5/sql_result.h
--- a/sql/backends/monet5/sql_result.h
+++ b/sql/backends/monet5/sql_result.h
@@ -50,4 +50,6 @@ extern const char *mvc_export_error(back
 extern ssize_t convert2str(mvc *m, sql_class eclass, int d, int sc, int 
has_tz, const void *p, int mtype, char **buf, size_t *len);
 extern int mvc_export(mvc *m, stream *s, res_table *t, BUN nr);
 
+extern str mvc_from_string(mvc *m, BAT **bats, int nr, char *s, sql_subtype 
*t);
+
 #endif /* sql_result_H */
diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c
--- a/sql/server/sql_scan.c
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to