Changeset: fe6db6abcc69 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/fe6db6abcc69 Added Files: sql/test/nested/Tests/basic.test Modified Files: monetdb5/modules/mal/tablet.c monetdb5/modules/mal/tablet.h sql/backends/monet5/sql_result.c sql/include/sql_catalog.h sql/server/rel_select.c sql/storage/bat/res_table.c sql/test/nested/Tests/All sql/test/nested/Tests/json.test sql/test/nested/Tests/webclicks.test Branch: nested Log Message:
initial multiset output diffs (truncated from 407 to 300 lines): diff --git a/monetdb5/modules/mal/tablet.c b/monetdb5/modules/mal/tablet.c --- a/monetdb5/modules/mal/tablet.c +++ b/monetdb5/modules/mal/tablet.c @@ -222,6 +222,7 @@ TABLET_error(stream *s) /* The output line is first built before being sent. It solves a problem with UDP, where you may loose most of the information using short writes */ + static inline int output_line(char **buf, size_t *len, char **localbuf, size_t *locallen, Column *fmt, stream *fd, BUN nr_attrs, oid id) @@ -276,6 +277,100 @@ output_line(char **buf, size_t *len, cha return 0; } +#define MS_ARRAY 2 +/* move into sql_result and store in format */ +static int +multiset_size( Column *fmt) +{ + int nrattrs = 1 + (fmt->multiset == MS_ARRAY); + //if (fmt[1]) { /* todo check composite types */ + nrattrs ++; + //} + return nrattrs; +} + +static inline ssize_t +output_line_multiset(char **buf, size_t *len, ssize_t fill, char **localbuf, size_t *locallen, Column *fmt, stream *fd, BUN nr_attrs); + +static ssize_t +output_multiset_value(char **buf, size_t *len, ssize_t fill, char **localbuf, size_t *locallen, + Column *fmt, stream *fd, BUN nr_attrs, int multiset, int id) +{ + nr_attrs -= (multiset == MS_ARRAY)?2:1; + Column *msid = fmt + nr_attrs; + int *idp = (int*)Tloc(msid->c, msid->p); + int first = 1; + for (; *idp == id; idp++, msid->p++) { + if (!first) + (*buf)[fill++] = ','; + if ((fill = output_line_multiset(buf, len, fill, localbuf, locallen, fmt, fd, nr_attrs)) < 0) { + break; + } + first = 0; + } + return fill; +} + +static inline ssize_t +output_line_multiset(char **buf, size_t *len, ssize_t fill, char **localbuf, size_t *locallen, + Column *fmt, stream *fd, BUN nr_attrs) +{ + BUN i; + + for (i = 0; i < nr_attrs; i++) { + Column *f = fmt + i; + const char *p; + ssize_t l = 0; + + if (f->c) { + p = BUNtail(f->ci, f->p); + + if (p && i && f->multiset) { + int nr_attrs = multiset_size(f); + assert(f->c->ttype == TYPE_int); + + (*buf)[fill++] = '\''; + (*buf)[fill++] = '{'; + (*buf)[fill] = 0; + fill = output_multiset_value(buf, len, fill, localbuf, locallen, fmt + i + 1, fd, nr_attrs, f->multiset, *(int*)p); + (*buf)[fill++] = '}'; + (*buf)[fill++] = '\''; + (*buf)[fill] = 0; + i += nr_attrs; + f->p++; + f = fmt + i; + } else + + if (!p || ATOMcmp(f->adt, ATOMnilptr(f->adt), p) == 0) { + p = f->nullstr; + l = (ssize_t) strlen(p); + } else { + l = f->tostr(f->extra, localbuf, locallen, f->adt, p); + if (l < 0) + return -1; + p = *localbuf; + } + if (fill + l + f->seplen >= (ssize_t) * len) { + /* extend the buffer */ + char *nbuf; + nbuf = GDKrealloc(*buf, fill + l + f->seplen + BUFSIZ); + if (nbuf == NULL) + return -1; /* *buf freed by caller */ + *buf = nbuf; + *len = fill + l + f->seplen + BUFSIZ; + } + if (l) { + strncpy(*buf + fill, p, l); + fill += l; + f->p++; + } + } + strncpy(*buf + fill, f->sep, f->seplen); + fill += f->seplen; + } + return fill; +} + static inline int output_line_dense(char **buf, size_t *len, char **localbuf, size_t *locallen, Column *fmt, stream *fd, BUN nr_attrs) @@ -428,6 +523,36 @@ output_file_default(Tablet *as, BAT *ord } static int +output_multiset(Tablet *as, stream *fd, bstream *in) +{ + size_t len = BUFSIZ, locallen = BUFSIZ; + int res = 0; + char *buf = GDKmalloc(len); + char *localbuf = GDKmalloc(len); + BUN i = 0; + + if (buf == NULL || localbuf == NULL) { + GDKfree(buf); + GDKfree(localbuf); + return -1; + } + for (i = 0; i < as->nr; i++) { + if ((i & 8191) == 8191 && bstream_getoob(in)) { + res = -5; /* "Query aborted" */ + break; + } + if ((res = output_line_multiset(&buf, &len, 0, &localbuf, &locallen, as->format, fd, as->nr_attrs)) < 0) { + break; + } + if (fd && mnstr_write(fd, buf, 1, res) != res) + return TABLET_error(fd); + } + GDKfree(localbuf); + GDKfree(buf); + return res; +} + +static int output_file_dense(Tablet *as, stream *fd, bstream *in) { size_t len = BUFSIZ, locallen = BUFSIZ; @@ -500,7 +625,14 @@ TABLEToutput_file(Tablet *as, BAT *order as->nr = maxnr; } assert(as->nr != BUN_NONE); + int multiset = 0; + for (unsigned int i = 1; i < as->nr_attrs; i++) + multiset |= as->format[i].multiset; + if (multiset) { + assert(!order); + return output_multiset(as, s, in); + } base = check_BATs(as); if (!order || !is_oid_nil(base)) { if (!order || order->hseqbase == base) diff --git a/monetdb5/modules/mal/tablet.h b/monetdb5/modules/mal/tablet.h --- a/monetdb5/modules/mal/tablet.h +++ b/monetdb5/modules/mal/tablet.h @@ -43,6 +43,7 @@ typedef struct Column_t { size_t null_length; /* its length */ unsigned int width; /* actual column width */ unsigned int maxwidth; /* permissible width */ + int multiset; /* multiset */ int fieldstart; /* Fixed character field load positions */ int fieldwidth; int scale, precision; 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 @@ -1246,6 +1246,15 @@ mvc_export_table_columnar(stream *s, res } static int +multiset_size(res_col *c) +{ + if (c->type.multiset) { + return 1+(c->type.multiset == MS_ARRAY?3:2); + } + return 0; +} + +static int mvc_export_table_(mvc *m, int output_format, stream *s, res_table *t, BUN offset, BUN nr, const char *btag, const char *sep, const char *rsep, const char *ssep, const char *ns) { Tablet as; @@ -1277,6 +1286,7 @@ mvc_export_table_(mvc *m, int output_for fmt[0].ws = 0; fmt[0].nullstr = NULL; + int multiset = 0; for (i = 1; i <= t->nr_cols; i++) { res_col *c = t->cols + (i - 1); @@ -1300,6 +1310,13 @@ mvc_export_table_(mvc *m, int output_for fmt[i].seplen = _strlen(fmt[i].sep); fmt[i].rsep = rsep; } + fmt[i].multiset = c->type.multiset; + multiset += multiset_size(c); + if (multiset>1) { + fmt[i].sep = NULL; + fmt[i].seplen = 0; + multiset--; + } if (json) { res_col *p = t->cols + (i - 1); @@ -1311,13 +1328,13 @@ mvc_export_table_(mvc *m, int output_for */ if (i == 1) { bj = SA_NEW_ARRAY(m->sa, char, strlen(p->name) + strlen(btag)); - snprintf(bj, strlen(p->name) + strlen(btag), btag, p->name); + snprintf(bj, strlen(p->name) + strlen(btag), "%s%s", btag, p->name); fmt[i - 1].sep = bj; fmt[i - 1].seplen = _strlen(fmt[i - 1].sep); fmt[i - 1].rsep = NULL; } else if (i <= t->nr_cols) { bj = SA_NEW_ARRAY(m->sa, char, strlen(p->name) + strlen(sep)); - snprintf(bj, strlen(p->name) + 10, sep, p->name); + snprintf(bj, strlen(p->name) + 10, "%s%s", sep, p->name); fmt[i - 1].sep = bj; fmt[i - 1].seplen = _strlen(fmt[i - 1].sep); fmt[i - 1].rsep = NULL; @@ -1633,6 +1650,12 @@ mvc_export_affrows(backend *b, stream *s return mvc_affrows(b->mvc, s, val, w, query_id, b->last_id, starttime, maloptimizer, b->reloptimizer); } +static inline int +skip_multiset(res_col *c) +{ + return (c->type.multiset==MS_VALUE)?0:(c->type.multiset==MS_ARRAY)?3:2; +} + int mvc_export_head(backend *b, stream *s, int res_id, int only_header, int compute_lengths, lng starttime, lng maloptimizer) { @@ -1668,7 +1691,7 @@ mvc_export_head(backend *b, stream *s, i return -4; /* column count */ - if (mvc_send_int(s, t->nr_cols) != 1 || mnstr_write(s, " ", 1, 1) != 1) + if (mvc_send_int(s, t->nr_output_cols) != 1 || mnstr_write(s, " ", 1, 1) != 1) return -4; /* row count, min(count, reply_size) */ @@ -1699,6 +1722,7 @@ mvc_export_head(backend *b, stream *s, i if (len && mnstr_write(s, c->tn, len, 1) != 1) return -4; + i += skip_multiset(c); if (i + 1 < t->nr_cols && mnstr_write(s, ",\t", 2, 1) != 1) return -4; } @@ -1727,6 +1751,7 @@ mvc_export_head(backend *b, stream *s, i return -4; } + i += skip_multiset(c); if (i + 1 < t->nr_cols && mnstr_write(s, ",\t", 2, 1) != 1) return -4; } @@ -1736,8 +1761,14 @@ mvc_export_head(backend *b, stream *s, i for (i = 0; i < t->nr_cols; i++) { res_col *c = t->cols + i; - if (mnstr_write(s, c->type.type->base.name, strlen(c->type.type->base.name), 1) != 1) + if (c->type.multiset) { + if (mnstr_write(s, "varchar", 7, 1) != 1) + return -4; + } else if (mnstr_write(s, c->type.type->base.name, strlen(c->type.type->base.name), 1) != 1) return -4; + //if (c->type.multiset && mnstr_write(s, "[]", 2, 1) != 1) + //return -4; + i += skip_multiset(c); if (i + 1 < t->nr_cols && mnstr_write(s, ",\t", 2, 1) != 1) return -4; } @@ -1751,6 +1782,7 @@ mvc_export_head(backend *b, stream *s, i if ((res = export_length(s, mtype, eclass, c->type.digits, c->type.scale, type_has_tz(&c->type), c->b, c->p)) < 0) return res; + i += skip_multiset(c); if (i + 1 < t->nr_cols && mnstr_write(s, ",\t", 2, 1) != 1) return -4; } @@ -1765,6 +1797,7 @@ mvc_export_head(backend *b, stream *s, i if (mnstr_printf(s, "%u %u", c->type.digits, c->type.scale) < 0) return -4; + i += skip_multiset(c); if (i + 1 < t->nr_cols && mnstr_write(s, ",\t", 2, 1) != 1) _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org