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

Reply via email to