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