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