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 -- [email protected]
To unsubscribe send an email to [email protected]