Changeset: 49391079ada4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/49391079ada4
Modified Files:
        sql/backends/monet5/sql_result.c
        sql/test/nested/Tests/array.test
        sql/test/nested/Tests/composite.test
Branch: nestedtypes
Log Message:

implemented handling of composites in the string composite/array values


diffs (truncated from 396 to 300 lines):

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
@@ -2117,76 +2117,124 @@ end:
 #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)
+VALUEparser(char **S, Column *cols, int elm, sql_subtype *t, char tsep, char 
rsep)
 {
-       (void)cols;
-       (void)nr;
-       (void)oanr;
+       /* handle literals */
+       char *s = *S;
+       int skip = 0;
+       char *ns = NULL;
+       if (t->type->localtype == TYPE_str) {
+               /* todo improve properly skip "" strings. */
+               if (*s != '"')
+                       throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing 
\" at start of string value");
+               s++;
+               ns = s;
+               while(*ns && *ns != '"')
+                       ns++;
+               if (*ns != '"')
+                       throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing 
\" at end of string value");
+               skip++;
+       } else if (tsep) {
+               ns = strchr(s, tsep);
+       }
+       if (!ns && rsep) {
+               ns = strchr(s, rsep);
+       }
+       char sep = 0;
+       if (!ns)
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing '%c' at 
end of value", rsep?rsep:tsep);
+       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)
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "append failed");
+       *ns = sep;
+       s = ns;
+       if (skip)
+               s++;
+       *S = s;
+       return NULL;
+}
+
+static str ARRAYparser(char **s, Column *cols, int nr, int *elm, sql_subtype 
*t);
+
+static str
+TUPLEparser(char **S, Column *cols, int nr, int *elm, sql_subtype *t)
+{
+       char *s = *S;
+       str msg = NULL;
+       int i = *elm;
+
+       skipspace(s);
+       if (!s && *s && s[0] != '(')
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing ( at 
start of composite value");
+       s++;
+       /* handle composite */
+       for (node *n = t->type->d.fields->h; n && !msg; n = n->next) {
+               sql_arg *f = n->data;
+
+               if (f->type.multiset) {
+                       msg = ARRAYparser(&s, cols, nr, &i, &f->type);
+               } else if (f->type.type->composite) {
+                       msg = TUPLEparser(&s, cols, nr, &i, &f->type);
+               } else {
+                       msg = VALUEparser(&s, cols, i, &f->type, ',', ')');
+                       i++;
+               }
+               if (n->next) {
+                       skipspace(s);
+                       if (!s && *s && s[0] != ',')
+                               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) 
"missing , within composite value");
+                       s++;
+                       skipspace(s);
+               }
+       }
+       if (msg)
+               return msg;
+       skipspace(s);
+       if (!s && *s && s[0] != ')')
+               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing ) at end 
of composite value");
+       s++;
+       *S = s;
+       *elm = i;
+       return msg;
+}
+
+static str
+ARRAYparser(char **S, Column *cols, int nr, int *elm, sql_subtype *t)
+{
+       char *s = *S;
+       str msg = NULL;
        if (!s && s[0] != '{')
                throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing { at 
start of array value");
        s++;
        skipspace(s);
-       int anr = 1;
-       int oelm = elm;
-       while (*s && s[0] != '}') {
-               elm = oelm;
+       int i = *elm;
+       int oelm = i;
+       int anr = 1, id = 0;
+       while (*s && s[0] != '}' && !msg) {
+               i = 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");
+                       msg = TUPLEparser(&s, cols, nr, &i, t);
                } else {
-                       /* handle literals */
-                       int skip = 0;
-                       char *ns = NULL;
-                       if (t->type->localtype == TYPE_str) {
-                               /* todo improve properly skip "" strings. */
-                               if (*s != '"')
-                                       throw(SQL, "SQLfrom_varchar", 
SQLSTATE(42000) "missing \" at start of string value");
-                               s++;
-                               ns = s;
-                               while(*ns && *ns != '"')
-                                       ns++;
-                               if (*ns != '"')
-                                       throw(SQL, "SQLfrom_varchar", 
SQLSTATE(42000) "missing \" at end of string value");
-                               skip++;
-                       } else {
-                               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;
-                       if (skip)
-                               s++;
+                       msg = VALUEparser(&s, cols, i, t, ',', '}');
+                       i++;
                }
                /* insert msid */
-               if (elm >= 0 && BUNappend(cols[elm].c, &id, false) != 
GDK_SUCCEED)
-                       elm = -2;
-               elm++;
+               if (t->multiset) {
+                       id = BATcount(cols[i + (t->multiset == 
MS_ARRAY?2:1)].c);
+                       if (i < 0 || BUNappend(cols[i].c, &id, false) != 
GDK_SUCCEED)
+                               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) 
"append failed");
+                       i++;
+               }
                if (t->multiset == MS_ARRAY) {
                        /* insert msnr */
-                       if (elm >= 0 && BUNappend(cols[elm].c, &anr, false) != 
GDK_SUCCEED)
-                               elm = -2;
-                       elm++;
+                       if (i < 0 || BUNappend(cols[i].c, &anr, false) != 
GDK_SUCCEED)
+                               throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) 
"append failed");
+                       i++;
                }
 
                skipspace(s);
@@ -2198,12 +2246,80 @@ ARRAYparser(char *s, Column *cols, int n
                anr++;
        }
        /* insert row-id */
-       if (elm >= 0 && BUNappend(cols[elm].c, &id, false) != GDK_SUCCEED)
-               elm = -2;
-       elm++;
+       if (t->multiset) {
+               if (i < 0 || BUNappend(cols[i].c, &id, false) != GDK_SUCCEED)
+                       throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "append 
failed");
+               i++;
+       }
        if (!s || s[0] != '}')
                throw(SQL, "SQLfrom_varchar", SQLSTATE(42000) "missing } at end 
of array value");
-       return MAL_SUCCEED;
+       *elm = i;
+       *S = s;
+       return msg;
+}
+
+static int
+from_string_cols(Column *fmt, BAT **bats, int nr, int cur, sql_subtype *t)
+{
+       int i = cur;
+
+       if (t->type->composite) {
+               for(node *n = t->type->d.fields->h; n; n = n->next) {
+                       if (i < 0 || i >= nr)
+                               return -10;
+                       sql_arg *f = n->data;
+                       if (f->type.multiset || f->type.type->composite) {
+                               i = from_string_cols(fmt, bats, nr, i, 
&f->type);
+                       } else {
+                               fmt[i].frstr = &_ASCIIadt_frStr;
+                               fmt[i].extra = &f->type;
+                               fmt[i].adt = f->type.type->localtype;
+                               fmt[i].len = ATOMlen(fmt[i].adt, 
ATOMnilptr(fmt[i].adt));
+                               fmt[i].c = bats[i];
+                               i++;
+                       }
+               }
+       } else {
+               if (i < 0 || i >= nr)
+                       return -10;
+               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++;
+       }
+       if (t->multiset) {
+               /* msid */
+               if (i < 0 || i >= nr)
+                       return -10;
+               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) {
+                       if (i < 0 || i >= nr)
+                               return -10;
+                       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 (i < 0 || i >= nr)
+                       return -10;
+               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++;
+       }
+       return i;
 }
 
 str
@@ -2211,50 +2327,25 @@ mvc_from_string(mvc *m, BAT **bats, int 
 {
        str msg = MAL_SUCCEED;
 
-       if (!t || !t->multiset)
-               throw(SQL, "sql.from_varchar", SQLSTATE(HY013) "Multiset type 
expected");
+       if (!t || (!t->multiset && !t->type->composite))
+               throw(SQL, "sql.from_varchar", SQLSTATE(HY013) "Multiset and/or 
composite type expected");
        Column *fmt = (Column *) GDKzalloc(sizeof(Column) * nr);
        if (!fmt)
                throw(SQL, "sql.from_varchar", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+       (void)m;
 
-       int i = 0;
 
-       (void)m;
-       if (t->type->composite) {
-               printf("todo implement composite type array values\n");
-               assert(0);
-       } 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++;
+       if (from_string_cols(fmt, bats, nr, 0, t) < 0) {
+               GDKfree(fmt);
+               throw(SQL, "sql.from_varchar", SQLSTATE(HY013) "Multiset and/or 
composite type expected");
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to