Changeset: 4fd82b761be9 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/4fd82b761be9 Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql_statement.c sql/backends/monet5/sql_statement.h sql/include/sql_relation.h sql/server/rel_exp.c sql/server/rel_multiset.c sql/test/nested/Tests/webclicks.test.in Branch: nestedtypes Log Message:
keep better track of nested structures diffs (290 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 @@ -1759,6 +1759,7 @@ nested_stmts(backend *be, list *exps, no if (e->type == e_column && e->f) { stmt *s = nested_stmts(be, e->f, &m); s->label = e->alias.label; + s->nested = true; append(r, s); } else { stmt *s = m->data; @@ -1927,8 +1928,10 @@ exp_bin(backend *be, sql_exp *e, stmt *l } else { s = stmt_convert(be, l, (!push&&l->nrcols==0)?NULL:sel, from, to); } - if (s && s->type == st_list && e->f) + if (s && s->type == st_list && e->f) { s = nested_stmts(be, e->f, &s->op4.lval->h); + s->nested = true; + } } break; case e_func: { node *en; @@ -2586,6 +2589,9 @@ rel2bin_subtable(backend *be, sql_table assert(c); if (exp->f && (c->type.multiset || c->type.type->composite)) { s = rel2bin_subtable(be, t, dels, c, exp->f); + if (!s) + return s; + s->nested = true; if (s && s->type == st_list && c->type.multiset) { /* keep rowid at the end */ stmt *ns = stmt_col(be, c, dels, dels->partition); list_append(s->op4.lval, ns); @@ -2669,6 +2675,7 @@ rel2bin_basetable(backend *be, sql_rel * s = rel2bin_subtable(be, t, dels, c, exp->f); if (!s) return s; + s->nested = true; if (s && s->type == st_list && c->type.multiset) { /* keep rowid at the end */ stmt *ns = (c == fcol) ? col : stmt_col(be, c, complex?dels:NULL, dels->partition); list_append(s->op4.lval, ns); diff --git a/sql/backends/monet5/sql_statement.c b/sql/backends/monet5/sql_statement.c --- a/sql/backends/monet5/sql_statement.c +++ b/sql/backends/monet5/sql_statement.c @@ -2609,6 +2609,15 @@ stmt_project_join(backend *be, stmt *op1 return q; } +static list * +unnest_stmt(stmt *o) +{ + while (o->type == st_alias) + o = o->op1; + assert(o && o->type == st_list); + return o->op4.lval; +} + stmt * stmt_project(backend *be, stmt *op1, stmt *op2) { @@ -2616,6 +2625,21 @@ stmt_project(backend *be, stmt *op1, stm return NULL; if (!op2->nrcols) return stmt_const(be, op1, op2); + if (op2->nested) { + list *ops = unnest_stmt(op2); + list *nops = sa_list(be->mvc->sa); + for(node *n = ops->h; n; n = n->next) { + stmt *i = n->data; + if (!i->nested) + i = stmt_project(be, op1, i); + append(nops, i); + } + stmt *s = stmt_list(be, nops); + if (s == NULL) + return NULL; + s->nested = true; + return s; + } InstrPtr q = stmt_project_join(be, op1, op2, false); if (q) { stmt *s = stmt_create(be->mvc->sa, st_join); @@ -4744,6 +4768,7 @@ stmt_alias_(backend *be, stmt *op1, int s->key = op1->key; s->aggr = op1->aggr; s->multiset = op1->multiset; + s->nested = op1->nested; s->tname = tname; s->cname = alias; diff --git a/sql/backends/monet5/sql_statement.h b/sql/backends/monet5/sql_statement.h --- a/sql/backends/monet5/sql_statement.h +++ b/sql/backends/monet5/sql_statement.h @@ -125,7 +125,8 @@ typedef struct stmt { partition:1, /* selected as mitosis candidate */ reduce:1, /* used to reduce number of rows (also for joins) */ loop:1, /* cond statement is looping */ - multiset:1; /* id column of multiset */ + multiset:1, /* id column of multiset */ + nested:1; /* id column of nested */ struct stmt *cand; /* optional candidate list */ diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h --- a/sql/include/sql_relation.h +++ b/sql/include/sql_relation.h @@ -193,6 +193,7 @@ typedef enum operator_type { #define is_column(et) (et != e_cmp) #define is_alias(et) (et == e_column) #define is_analytic(e) ((e)->type == e_func && ((sql_subfunc*)(e)->f)->func->type == F_ANALYTIC) +#define is_nested(e) (e->f && ((e)->type == e_convert || (e)->type == e_column)) #define is_base(op) (op == op_basetable || op == op_table) #define is_basetable(op) (op == op_basetable) 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 @@ -1047,7 +1047,7 @@ exp_setname(mvc *sql, sql_exp *e, sql_al if (name) e->alias.name = name; e->alias.parent = p; - if ((e->type == e_convert || e->type == e_column) && e->f) + if (is_nested(e)) exps_setname(sql, e->f, p, name); } @@ -2917,7 +2917,7 @@ exps_bind_nid(list *exps, int nid) if (e->alias.label == nid) return e; - if (e->f && (e->type == e_column || e->type == e_convert)) { + if (is_nested(e)) { e = exps_bind_nid(e->f, nid); if (e) return e; 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 @@ -7,44 +7,61 @@ #include "rel_updates.h" #include "rel_rewriter.h" -extern void _rel_print(mvc *sql, sql_rel *cur); +/* TODO move into unnest code */ +static bool +has_multiset(list *exps) +{ + bool needed = false; + if (list_empty(exps)) + return needed; + for(node *n = exps->h; n && !needed; n = n->next) { + sql_exp *e = n->data; + sql_subtype *t = exp_subtype(e); + + needed = (t && t->multiset); + if (!needed && t->type->composite && is_nested(e)) + needed = has_multiset(e->f); + } + return needed; +} + +static sql_rel * +ms_add_join_exps(visitor *v, sql_rel *rel, list *exps) +{ + if (list_empty(exps)) + return rel; + for(node *n = exps->h; n; n = n->next) { + sql_exp *e = n->data; + sql_subtype *t = exp_subtype(e); + if (t->multiset) { + v->changes++; + sql_exp *le = exp_ref(v->sql, e); + list *rexps = rel_projections(v->sql, rel->r, NULL, 0, 1); + sql_exp *re = exps_bind_column(rexps, "id", NULL, NULL, 0); + if (le && re) { + re = exp_ref(v->sql, re); + e = exp_compare(v->sql->sa, le, re, cmp_equal); + rel->exps = sa_list_append(v->sql->sa, rel->exps, e); + } + return rel; + } else if (t->type->composite) { + /* sofar only handles one level */ + return ms_add_join_exps(v, rel, e->f); + } + } + return rel; +} /* TODO handle composite/multset (ie deep nested cases) too */ static sql_rel * fm_join(visitor *v, sql_rel *rel) { if (list_empty(rel->exps) && is_dependent(rel)) { - bool needed = false; - sql_rel *l = rel->l; - sql_rel *r = rel->r; - if (0 && r && is_basetable(r->op)) { - sql_table *t = r->l; - if (t->base.name[0] == '%') - return l; - } - list *exps = rel_projections(v->sql, l, NULL, 0, 1); - for(node *n = exps->h; n && !needed; n = n->next) { - sql_subtype *t = exp_subtype(n->data); - needed = (t && t->multiset); - } - if (needed) { - for(node *n = exps->h; n; n = n->next) { - sql_exp *e = n->data; - sql_subtype *t = exp_subtype(e); - if (t->multiset) { - v->changes++; - sql_exp *le = exp_ref(v->sql, e); - list *rexps = rel_projections(v->sql, r, NULL, 0, 1); - sql_exp *re = exps_bind_column(rexps, "id", NULL, NULL, 0); - if (le && re) { - re = exp_ref(v->sql, re); - e = exp_compare(v->sql->sa, le, re, cmp_equal); - rel->exps = sa_list_append(v->sql->sa, rel->exps, e); - } - return rel; - } - } - } + list *exps = rel_projections(v->sql, rel->l, NULL, 0, 1); + bool needed = has_multiset(exps); + + if (needed) + return ms_add_join_exps(v, rel, exps); } return rel; } 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 @@ -61,11 +61,49 @@ productDetail 2024-11-30 22:13:37.823000 Mozilla -#query -#select e.eventid, el.element.key from ( select cast(t.json as event) as e from (select json from r'/home/niels/data/rc/default/sql/test/nested/Tests/webclicks.json') t), unnest(e.location.list) el -#---- -#996257967-103007874 -#996257967-103007874 +query TT +select e.eventid, el.element.key from ( select cast(t.json as event) as e from (select json from r'/home/niels/data/rc/default/sql/test/nested/Tests/webclicks.json') t), unnest(e.location.list) el +---- +996257967-103007874 +hash +996257967-103007874 +hostname +996257967-103007874 +pageSubType +996257967-103007874 +pageType +996257967-103007874 +pathname +996257967-103007874 +protocol +996257967-103007874 +referrer +996257967-103007874 +search +996257967-103007874 +state +996257967-103007874 +title +996257967-103007874 +hash +996257967-103007874 +hostname +996257967-103007874 +pageSubType +996257967-103007874 +pageType +996257967-103007874 +pathname +996257967-103007874 +protocol +996257967-103007874 +referrer +996257967-103007874 +search +996257967-103007874 +state +996257967-103007874 +title #query TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT #select cast(t.json as event) from (select json from r'$TSTSRCDIR/webclicks.json') t _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org