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