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