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
ou