Changeset: dbf659f59e8b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/dbf659f59e8b
Modified Files:
        monetdb5/modules/mal/tablet.c
        sql/test/nested/Tests/webclicks.test.in
Branch: nested
Log Message:

handle complex cases with many composites and multisets


diffs (276 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
@@ -299,132 +299,154 @@ multiset_size( Column *fmt)
        return nrattrs;
 }
 
-static inline ssize_t
-output_line_complex(char **buf, size_t *len, ssize_t fill, char **localbuf, 
size_t *locallen, Column *fmt, stream *fd, BUN nr_attrs, int composite, bool 
inms);
+static ssize_t output_multiset(char **buf, size_t *len, ssize_t fill, char 
**localbuf, size_t *locallen, Column *fmt, BUN nr_attrs, int multiset, int 
composite, bool quoted, int id);
 
-static ssize_t
-output_line_composite(char **buf, size_t *len, ssize_t fill, char **localbuf, 
size_t *locallen, Column *fmt, stream *fd, BUN nr_attrs, int composite, bool 
inms)
+static inline ssize_t
+output_value(char **buf, size_t *len, ssize_t fill, char **localbuf, size_t 
*locallen, Column *f)
 {
-       (*buf)[fill++] = '(';
-       if (fmt->virt) {
-               fmt++;
-               nr_attrs--;
+       assert (!f->virt && !f->composite && !f->multiset);
+
+       const char *p = BUNtail(f->ci, f->p);
+       ssize_t l = 0;
+
+       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 = output_line_complex(buf, len, fill, localbuf, locallen, 
fmt, fd, nr_attrs, composite, inms)) < 0) {
-               return -1;
+       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++;
        }
        return fill;
 }
 
 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 composite, int id)
+output_composite(char **buf, size_t *len, ssize_t fill, char **localbuf, 
size_t *locallen, Column *fmt, BUN nr_attrs, int composite, bool quoted)
+{
+       if (!quoted)
+               (*buf)[fill++] = '\'';
+       (*buf)[fill++] = '(';
+       (void)nr_attrs;
+       /*
+       if (fmt->virt) {
+               assert(0);
+               fmt++;
+               nr_attrs--;
+       }
+       */
+       int first = 1, j = 0;
+       for( ; composite; composite--) {
+               Column *f = fmt + j;
+
+               if (!first) {
+                       (*buf)[fill++] = ',';
+                       (*buf)[fill++] = ' ';
+                       (*buf)[fill] = 0;
+               }
+               if (f->multiset) {
+                       int nr_attrs = multiset_size(f)-1;
+                       const char *p = BUNtail(fmt[j+nr_attrs].ci, 
fmt[j+nr_attrs].p);
+
+                       fill = output_multiset(buf, len, fill, localbuf, 
locallen, fmt + j + 1, nr_attrs-1, f->multiset, f->composite, true, *(int*)p);
+                       fmt[j+nr_attrs].p++;
+                       f = fmt + j + nr_attrs; /* closing bracket */
+                       j += nr_attrs + 1;
+               } else if (f->composite) {
+                       int nr_attrs = multiset_size(f)-1;
+                       fill = output_composite(buf, len, fill, localbuf, 
locallen, fmt + j + 1, nr_attrs-j-1, f->composite, true);
+                       f = fmt + j + nr_attrs; /* closing bracket */
+                       j += nr_attrs + 1;
+               } else if (f->c) {
+                       fill = output_value(buf, len, fill, localbuf, locallen, 
f);
+                       j++;
+               }
+               first = 0;
+       }
+       (*buf)[fill++] = ')';
+       if (!quoted)
+               (*buf)[fill++] = '\'';
+       (*buf)[fill] = 0;
+       return fill;
+}
+
+static ssize_t
+output_multiset(char **buf, size_t *len, ssize_t fill, char **localbuf, size_t 
*locallen,
+                                 Column *fmt, BUN nr_attrs, int multiset, int 
composite, bool quoted, 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 (!quoted)
+               (*buf)[fill++] = '\'';
+       (*buf)[fill++] = '{';
+       (*buf)[fill] = 0;
+       for (; *idp == id && fill > 0; idp++, msid->p++) {
                if (!first)
                        (*buf)[fill++] = ',';
                if (composite) {
-                       if ((fill = output_line_composite(buf, len, fill, 
localbuf, locallen, fmt, fd, nr_attrs, composite, true)) < 0) {
-                               break;
-                       }
+                       fill = output_composite(buf, len, fill, localbuf, 
locallen, fmt, nr_attrs, composite, true);
                } else {
-                       if ((fill = output_line_complex(buf, len, fill, 
localbuf, locallen, fmt, fd, nr_attrs, 0, true)) < 0) {
-                               break;
-                       }
+                       fill = output_value(buf, len, fill, localbuf, locallen, 
fmt);
                }
                first = 0;
        }
+       if (fill < 0)
+               return fill;
+       (*buf)[fill++] = '}';
+       if (!quoted)
+               (*buf)[fill++] = '\'';
+       (*buf)[fill] = 0;
        return fill;
 }
 
-static inline ssize_t
+static ssize_t
 output_line_complex(char **buf, size_t *len, ssize_t fill, char **localbuf, 
size_t *locallen,
-                                 Column *fmt, stream *fd, BUN nr_attrs, int 
composite, bool inms)
+                                 Column *fmt, BUN nr_attrs)
 {
        BUN j;
 
        for (j = 0; j < nr_attrs; ) {
                Column *f = fmt + j;
                const char *p;
-               ssize_t l = 0;
 
-               if (f->virt && !f->multiset && f->composite > 1) {
-                       assert(composite == 0);
-                       (*buf)[fill++] = '\'';
-                       (*buf)[fill++] = '(';
-                       (*buf)[fill] = 0;
-                       composite = f->composite;
-                       j++;
-                       continue;
-               }
-               if (f->multiset && !inms) {
-                               int nr_attrs = multiset_size(f)-1;
-                               p = BUNtail(fmt[j+nr_attrs].ci, 
fmt[j+nr_attrs].p);
-
-                               if (!composite && !inms)
-                                       (*buf)[fill++] = '\'';
-                               (*buf)[fill++] = '{';
-                               (*buf)[fill] = 0;
-                               fill = output_multiset_value(buf, len, fill, 
localbuf, locallen, fmt + j + 1, fd, nr_attrs-1, f->multiset, f->composite, 
*(int*)p);
-                               (*buf)[fill++] = '}';
-                               if (!composite && !inms)
-                                       (*buf)[fill++] = '\'';
-                               (*buf)[fill] = 0;
-                               fmt[j+nr_attrs].p++;
-                               f = fmt + j + nr_attrs; /* closing bracket */
-                               j += nr_attrs + 1;
-               } else if (f->c) {
-                       p = BUNtail(f->ci, f->p);
+               if (f->multiset) {
+                       int nr_attrs = multiset_size(f)-1;
+                       p = BUNtail(fmt[j+nr_attrs].ci, fmt[j+nr_attrs].p);
 
-                       if (!p || ATOMcmp(f->adt, ATOMnilptr(f->adt), p) == 0) {
-                               p = f->nullstr;
-                               l = (ssize_t) strlen(p);
-                               j++;
-                       } else {
-                               l = f->tostr(f->extra, localbuf, locallen, 
f->adt, p);
-                               if (l < 0)
-                                       return -1;
-                               p = *localbuf;
-                               j++;
-                       }
-                       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++;
-                       }
-               } else
+                       fill = output_multiset(buf, len, fill, localbuf, 
locallen, fmt + j + 1, nr_attrs-1, f->multiset, f->composite, false, *(int*)p);
+                       fmt[j+nr_attrs].p++;
+                       f = fmt + j + nr_attrs; /* closing bracket */
+                       j += nr_attrs + 1;
+               } else if (f->composite) {
+                       int nr_attrs = multiset_size(f)-1;
+                       fill = output_composite(buf, len, fill, localbuf, 
locallen, fmt + j + 1, nr_attrs-j, f->composite, false);
+                       f = fmt + j + nr_attrs; /* closing bracket */
+                       j += nr_attrs + 1;
+               } else if (f->c) {
+                       fill = output_value(buf, len, fill, localbuf, locallen, 
f);
                        j++;
-               if (composite) {
-                       composite--;
-                       if (composite) {
-                               (*buf)[fill++] = ',';
-                               (*buf)[fill++] = ' ';
-                               (*buf)[fill] = 0;
-                       } else {
-                               (*buf)[fill++] = ')';
-                               if (!inms)
-                                       (*buf)[fill++] = '\'';
-                               (*buf)[fill] = 0;
-                               strncpy(*buf + fill, f->sep, f->seplen);
-                               fill += f->seplen;
-                       }
                } else {
-                       strncpy(*buf + fill, f->sep, f->seplen);
-                       fill += f->seplen;
+                       j++;
                }
+               strncpy(*buf + fill, f->sep, f->seplen);
+               fill += f->seplen;
        }
        return fill;
 }
@@ -603,7 +625,7 @@ output_complex(Tablet *as, stream *fd, b
                        res = -5;                       /* "Query aborted" */
                        break;
                }
-               if ((res = output_line_complex(&buf, &len, 0, &localbuf, 
&locallen, as->format, fd, as->nr_attrs, 0, false)) < 0) {
+               if ((res = output_line_complex(&buf, &len, 0, &localbuf, 
&locallen, as->format, as->nr_attrs)) < 0) {
                        break;
                }
                if (fd && mnstr_write(fd, buf, 1, res) != res)
diff --git a/sql/test/nested/Tests/webclicks.test.in 
b/sql/test/nested/Tests/webclicks.test.in
--- a/sql/test/nested/Tests/webclicks.test.in
+++ b/sql/test/nested/Tests/webclicks.test.in
@@ -105,9 +105,11 @@ state
 996257967-103007874
 title
 
-#query TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
-#select cast(t.json as event) from (select json from 
r'$TSTSRCDIR/webclicks.json') t
-#----
+query T
+select cast(t.json as event) from (select json from 
r'$TSTSRCDIR/webclicks.json') t
+----
+("996257967-103007874", 
"47f07c1399c9c6bd1012861f9c5c958e042732e259b909e077f7e8967b650c75", 
"8359e1f53c300c44ee0e8ba1610f620c589258a8a4752ea089cfc44fee51ff64", 
"productDetail", 2024-11-30 22:13:37.823000, "Mozilla", ({(("hash", 
"da39a3ee5e6b4b0d3255bfef95601890afd80709")),(("hostname", 
"e13dacd9566ecf8efd4aff212960c02de20aa110")),(("pageSubType", 
"d5d4cd07616a542891b7ec2d0257b3a24b69856e")),(("pageType", 
"6b5cdf4073b8166e5cc01a2532469d2e356eebfd")),(("pathname", 
"0b28998c6a5efc0afb854752b1bba65f37c70230")),(("protocol", 
"c3437dbc7c1255d3a21d444d86ebf2e9234c22bd")),(("referrer", 
"27bbe94658bf6bd4c431052e2065de0457ec8546")),(("search", 
"da39a3ee5e6b4b0d3255bfef95601890afd80709")),(("state", 
"da39a3ee5e6b4b0d3255bfef95601890afd80709")),(("title", 
"d08339b839a6716a96334736c1c769091a0a8644"))}), ({(("customerId", 
"d5d4cd07616a542891b7ec2d0257b3a24b69856e")),(("customerType", 
"d5d4cd07616a542891b7ec2d0257b3a24b69856e")),(("isAuthenticated", 
"7cb6efb98ba5972a9b5090dc2e517fe14d12cb04"))}), 
 ("detail", ({(("null", "null"))}), ({(("product", "null", ({(("brand", 
"b8884d21754edbf713af7000a67eac0efd5df8ea"))})))})))
+("996257967-103007874", 
"47f07c1399c9c6bd1012861f9c5c958e042732e259b909e077f7e8967b650c75", 
"8359e1f53c300c44ee0e8ba1610f620c589258a8a4752ea089cfc44fee51ff64", 
"productDetail", 2024-11-30 22:13:37.823000, "Mozilla", ({(("hash", 
"da39a3ee5e6b4b0d3255bfef95601890afd80709")),(("hostname", 
"e13dacd9566ecf8efd4aff212960c02de20aa110")),(("pageSubType", 
"d5d4cd07616a542891b7ec2d0257b3a24b69856e")),(("pageType", 
"6b5cdf4073b8166e5cc01a2532469d2e356eebfd")),(("pathname", 
"0b28998c6a5efc0afb854752b1bba65f37c70230")),(("protocol", 
"c3437dbc7c1255d3a21d444d86ebf2e9234c22bd")),(("referrer", 
"27bbe94658bf6bd4c431052e2065de0457ec8546")),(("search", 
"da39a3ee5e6b4b0d3255bfef95601890afd80709")),(("state", 
"da39a3ee5e6b4b0d3255bfef95601890afd80709")),(("title", 
"d08339b839a6716a96334736c1c769091a0a8644"))}), ({(("customerId", 
"d5d4cd07616a542891b7ec2d0257b3a24b69856e")),(("customerType", 
"d5d4cd07616a542891b7ec2d0257b3a24b69856e")),(("isAuthenticated", 
"7cb6efb98ba5972a9b5090dc2e517fe14d12cb04"))}), 
 ("detail", ({(("null", "null"))}), ({(("product", "null", ({(("brand", 
"b8884d21754edbf713af7000a67eac0efd5df8ea"))})))})))
 
 
 # clean up
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to