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