Changeset: e05926cd3c81 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e05926cd3c81
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/server/rel_exp.c
        sql/server/rel_multiset.c
        sql/test/nested/Tests/webclicks.test
Branch: nested
Log Message:

improved handling of mixure of composites and multisets


diffs (truncated from 322 to 300 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -645,7 +645,11 @@ composite_value_list(backend *be, sql_ex
                        i = exp_bin(be, e, left, NULL, NULL, NULL, NULL, sel, 
0, 0, 0);
                if (!i)
                        return NULL;
-               list_append(f, i);
+               if (i->type == st_list) {
+                       for( node *n = i->op4.lval->h; n; n = n->next)
+                               list_append(f, n->data);
+               } else
+                       list_append(f, i);
        }
        return stmt_list(be, f);
 }
@@ -764,21 +768,25 @@ append_tuple(backend *be, sql_exp *tuple
                }
                m = m->next;
        }
-       if (type->type->composite) {
-               for(n = attr->h, o = type->type->d.fields->h; n && o; n = 
n->next, o = o->next) {
+       sql_subtype *ntype = type;
+       if (is_row(tuple) && list_length(type->type->d.fields) == 1) {
+               sql_arg *f = type->type->d.fields->h->data;
+               ntype = &f->type;
+       }
+       if (ntype->type->composite) {
+               for(n = attr->h, o = ntype->type->d.fields->h; n && o; n = 
n->next, o = o->next) {
+                       sql_arg *f = o->data;
                        sql_exp *e = n->data;
                        list *vals = m->data;
-                       sql_subtype *type = exp_subtype(e);
-                       assert(type->type == ((sql_arg*)o->data)->type.type);
-                       if (type->type->composite) {
-                               node *nm = append_tuple(be, e, type, left, sel, 
m, rowcnt, lcnt, type->multiset);
+                       if (f->type.type->composite) {
+                               node *nm = append_tuple(be, e, &f->type, left, 
sel, m, rowcnt, lcnt, ntype->multiset);
                                if (nm == m)
                                        return m;
                                m = nm;
                        } else {
                                stmt *i = exp_bin(be, e, left, NULL, NULL, 
NULL, NULL, sel, 0, 0, 0);
+                               append(vals, i);
                                m = m->next;
-                               append(vals, i);
                        }
                }
        } else {
@@ -5816,27 +5824,27 @@ table_update_stmts(mvc *sql, sql_table *
 }
 
 static node *
-insert_composite(stmt **updates, sql_column *c, node *n, stmt *input_tuple)
-{
-       node *m, *f;
+insert_composite(stmt **updates, sql_column *c, node *n, node **M)
+{
+       node *m = *M, *f;
+       /*
        while(input_tuple->type == st_alias)
                input_tuple = input_tuple->op1;
        if (input_tuple->type != st_list)
                return NULL;
-       /* TODO we need to insert the id into the composite column itself if 
this is a multiset */
-       if (c->type.multiset) {
-               printf("todo insert next id?\n");
-       }
-       for(m = input_tuple->op4.lval->h, n = n->next, f = 
c->type.type->d.fields->h; n && m && f; m = m->next, f = f->next) {
+               */
+       for(n = n->next, f = c->type.type->d.fields->h; n && m && f; f = 
f->next) {
                sql_column *c = n->data;
 
-               if (c->type.type->composite) {
-                       n = insert_composite(updates, c, n, m->data);
+               if (c->type.type->composite && !c->type.multiset) {
+                       n = insert_composite(updates, c, n, &m);
                } else {
                        updates[c->colnr] = m->data;
                        n = n->next;
-               }
-       }
+                       m = m->next;
+               }
+       }
+       /*
        if (c->type.multiset) {
                sql_column *c = n->data;
 
@@ -5851,8 +5859,10 @@ insert_composite(stmt **updates, sql_col
                n = n->next;
                m = m->next;
        }
-       if (f || m) /* did we find all fields and use all values */
-               return NULL;
+       */
+       //if (f || m) /* did we find all fields and use all values */
+               //return NULL;
+       *M = m;
        return n;
 }
 
@@ -5904,14 +5914,15 @@ rel2bin_insert(backend *be, sql_rel *rel
                return NULL;
 
        updates = table_update_stmts(sql, t, &len);
-       for (n = ol_first_node(t->columns), m = inserts->op4.lval->h; n && m; m 
= m->next) {
+       for (n = ol_first_node(t->columns), m = inserts->op4.lval->h; n && m; ) 
{
                sql_column *c = n->data;
 
                if (c->type.type->composite && !c->type.multiset) {
-                       n = insert_composite(updates, c, n, m->data);
+                       n = insert_composite(updates, c, n, &m);
                } else {
                        updates[c->colnr] = m->data;
                        n = n->next;
+                       m = m->next;
                }
        }
 
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -3697,7 +3697,12 @@ exp_check_composite_type(mvc *sql, sql_s
        for(n = t->type->d.fields->h, m = vals->h; n && m; n = n->next, m = 
m->next) {
                sql_arg *f = n->data;
                sql_exp *e = m->data;
-               e = exp_check_type(sql, &f->type, rel, e, tpe);
+               sql_subtype *ftype = &f->type;
+               if (!ftype->multiset && ftype->type->composite && 
list_length(ftype->type->d.fields) == 1) {
+                       sql_arg *f1 = ftype->type->d.fields->h->data;
+                       ftype = &f1->type;
+               }
+               e = exp_check_type(sql, ftype, rel, e, tpe);
                if (!e)
                        return NULL;
                m->data = e;
@@ -3715,6 +3720,8 @@ exp_check_composite_type(mvc *sql, sql_s
 static sql_exp *
 exp_check_multiset_type(mvc *sql, sql_subtype *t, sql_rel *rel, sql_exp *exp, 
check_type tpe)
 {
+       if (t->multiset && exp_is_null(exp))
+               return exp;
        assert(t->type->composite || t->multiset);
        if (!exp_is_rel(exp) && !is_values(exp)) {
                sql_subtype *et = exp_subtype(exp);
@@ -3742,6 +3749,11 @@ exp_check_multiset_type(mvc *sql, sql_su
        }
        sql_subtype ct = *t;
        ct.multiset = false;
+
+       if (ct.type->composite && list_length(ct.type->d.fields) == 1) {
+               sql_arg *f1 = ct.type->d.fields->h->data;
+               ct = f1->type;
+       }
        for(node *v = msvals->h; v; v = v->next) {
                sql_exp *r = v->data;
 
diff --git a/sql/server/rel_multiset.c b/sql/server/rel_multiset.c
--- a/sql/server/rel_multiset.c
+++ b/sql/server/rel_multiset.c
@@ -79,6 +79,33 @@ fm_table(visitor *v, sql_rel *rel)
 }
 #endif
 
+static node * fm_insert_ms(visitor *v, node *m, sql_subtype *t, sql_table *pt, 
char *name, list *btexps, list *niexps, sql_rel **cur, sql_rel *ins);
+
+static node *
+fm_insert_composite(visitor *v, node *m, node **N, sql_subtype *t, sql_table 
*subtable, list *btexps, list *niexps, sql_rel **cur, sql_rel *ins)
+{
+       node *n = *N;
+       assert (t->type->composite && !t->multiset);
+       n = n->next; /* skip virtual column */
+       for(node *o = t->type->d.fields->h; n && m && o; o = o->next) {
+               sql_column *c = n->data;
+               if (!c->type.multiset && c->type.type->composite) {
+                       m = fm_insert_composite(v, m, &n, &c->type, subtable, 
btexps, niexps, cur, ins);
+               } else if (c->type.multiset) {
+                       m = fm_insert_ms(v, m, &c->type, subtable, 
c->storage_type, btexps, niexps, cur, ins);
+                       n = n->next;
+               } else {
+                       sql_exp *e = exp_ref(v->sql, m->data);
+                       append(niexps, e = exp_ref(v->sql, m->data));
+                       append(btexps, exp_ref(v->sql, e));
+                       m = m->next;
+                       n = n->next;
+               }
+       }
+       *N = n;
+       return m;
+}
+
 static node *
 fm_insert_ms(visitor *v, node *m, sql_subtype *t, sql_table *pt, char *name, 
list *btexps, list *niexps, sql_rel **cur, sql_rel *ins)
 {
@@ -115,15 +142,19 @@ fm_insert_ms(visitor *v, node *m, sql_su
        append(btexps, nrowid);
        m = m->next;
        if (t->type->composite) {
-               for(node *n = ol_first_node(subtable->columns), *o = 
t->type->d.fields->h; n && m && o; n = n->next, o = o->next) {
+               for(node *n = ol_first_node(subtable->columns), *o = 
t->type->d.fields->h; n && m && o; o = o->next) {
                        sql_column *c = n->data;
-                       if (c->type.multiset) {
+                       if (!c->type.multiset && c->type.type->composite) {
+                               m = fm_insert_composite(v, m, &n, &c->type, 
subtable, nexps, niexps, cur, ins);
+                       } else if (c->type.multiset) {
                                m = fm_insert_ms(v, m, &c->type, subtable, 
c->storage_type, nexps, niexps, cur, ins);
+                               n = n->next;
                        } else {
                                sql_exp *e = exp_ref(v->sql, m->data);
                                append(niexps, e = exp_ref(v->sql, m->data));
                                append(nexps, exp_ref(v->sql, e));
                                m = m->next;
+                               n = n->next;
                        }
                }
        } else {
@@ -176,15 +207,19 @@ fm_insert(visitor *v, sql_rel *rel)
                        list *niexps = sa_list(v->sql->sa); /* inject extra 
project, such that referencing becomes easier */
                        /* do insert per multiset and once for base table */
                        rel->r = ins = rel_project(v->sql->sa, ins, niexps);
-                       for(node *n = ol_first_node(t->columns), *m = exps->h; 
n && m; n = n->next) {
+                       for(node *n = ol_first_node(t->columns), *m = exps->h; 
n && m; ) {
                                sql_column *c = n->data;
-                               if (c->type.multiset) {
+                               if (!c->type.multiset && 
c->type.type->composite) {
+                                       m = fm_insert_composite(v, m, &n, 
&c->type, t, btexps, niexps, &cur, ins);
+                               } else if (c->type.multiset) {
                                        m = fm_insert_ms(v, m, &c->type, t, 
c->storage_type, btexps, niexps, &cur, ins);
+                                       n = n->next;
                                } else {
                                        sql_exp *e = exp_ref(v->sql, m->data);
                                        append(niexps, e);
                                        append(btexps, exp_ref(v->sql, e));
                                        m = m->next;
+                                       n = n->next;
                                }
                        }
                        rel->r = rel_project(v->sql->sa, rel->r, btexps);
@@ -234,6 +269,35 @@ fm_join(visitor *v, sql_rel *rel)
        return rel;
 }
 
+static void fm_project_ms(visitor *v, sql_exp *e, sql_subtype *t, sql_alias 
*cn, list *nexps);
+
+static void
+fm_project_composite(visitor *v, sql_exp *e, sql_subtype *t, sql_alias *cn, 
list *nexps)
+{
+       assert (t->type->composite);
+       int label = v->sql->label;
+       v->sql->label += list_length(t->type->d.fields);
+
+       for(node *f = t->type->d.fields->h; f; f = f->next) {
+               sql_arg *field = f->data;
+
+               if (field->type.type->composite && !field->type.multiset) {
+                       sql_alias *nn = a_create(v->sql->sa, field->name);
+                       nn->parent = cn;
+                       fm_project_composite(v, e, &field->type, nn, nexps);
+               } else if (field->type.multiset) {
+                       sql_alias *nn = a_create(v->sql->sa, field->name);
+                       nn->parent = cn;
+                       fm_project_ms(v, e, &field->type, nn, nexps);
+               } else {
+                       sql_exp *mse = exp_column(v->sql->sa, cn, field->name, 
&field->type, 1,1, 1, 1);
+                       mse->alias.label = (++label);
+                       mse->nid = mse->alias.label;
+                       append(nexps, mse);
+               }
+       }
+}
+
 static void
 fm_project_ms(visitor *v, sql_exp *e, sql_subtype *t, sql_alias *cn, list 
*nexps)
 {
@@ -249,7 +313,11 @@ fm_project_ms(visitor *v, sql_exp *e, sq
                for(node *f = t->type->d.fields->h; f; f = f->next) {
                        sql_arg *field = f->data;
 
-                       if (field->type.multiset) {
+                       if (field->type.type->composite && 
!field->type.multiset) {
+                               sql_alias *nn = a_create(v->sql->sa, 
field->name);
+                               nn->parent = cn;
+                               fm_project_composite(v, e, &field->type, nn, 
nexps);
+                       } else if (field->type.multiset) {
                                sql_alias *nn = a_create(v->sql->sa, 
field->name);
                                nn->parent = cn;
                                fm_project_ms(v, e, &field->type, nn, nexps);
@@ -331,7 +399,7 @@ fm_project(visitor *v, sql_rel *rel)
                for(node *n = rel->exps->h; n; n = n->next) {
                        sql_exp *e = n->data;
                        sql_subtype *t = exp_subtype(e);
-                       needed = (t && t->multiset);
+                       needed = (t && (t->multiset || t->type->composite));
                        if (needed && is_intern(e)) {
                                needed = false;
                                break;
@@ -347,7 +415,10 @@ fm_project(visitor *v, sql_rel *rel)
                        for(node *n = rel->exps->h; n; n = n->next) {
                                sql_exp *e = n->data;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to