Changeset: 18f2d7de449a for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/18f2d7de449a Modified Files: sql/server/rel_optimize_proj.c sql/server/rel_unnest.c sql/test/cte/Tests/test_correlated_recursive_cte.test Branch: recursive_cte Log Message:
handle some more correlated recursive cte's diffs (191 lines): diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c --- a/sql/server/rel_optimize_proj.c +++ b/sql/server/rel_optimize_proj.c @@ -1752,13 +1752,13 @@ rel_push_aggr_down_n_arry(visitor *v, sq list *rgbe = NULL, *gbe = NULL, *exps = NULL; node *n, *m; - if (is_recursive(u)) - return rel; - // TODO why? if (u->op == op_project && !need_distinct(u)) u = u->l; + if (is_recursive(u)) + return rel; + /* make sure we don't create group by on group by's */ for (node *n = ((list*)u->l)->h; n; n = n->next) { r = n->data; diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c --- a/sql/server/rel_unnest.c +++ b/sql/server/rel_unnest.c @@ -827,17 +827,10 @@ push_up_project(mvc *sql, sql_rel *rel, sql_rel *r = rel->r; if (rel_is_ref(r) && is_recursive(r)) { - - if (is_join(rel->op) && is_dependent(rel)) { - sql_rel *l = r->l; - r->l = rel; - rel->r = l; - /* add missing expressions */ - list *exps = rel_projections(sql, rel->l, NULL, 1, 1); - r->exps = list_distinct(list_merge(exps, r->exps, (fdup)NULL), (fcmp)exp_equal, (fdup)NULL); - return r; - } - assert(0); + reset_dependent(rel); + if (is_join(rel->op) && list_length(rel->exps)) + return rel; + return r; } assert(is_simple_project(r->op)); if (rel_is_ref(r)) { @@ -1584,6 +1577,8 @@ push_up_set(mvc *sql, sql_rel *rel, list return rel; } +static sql_rel * rel_unnest_dependent(mvc *sql, sql_rel *rel); + static sql_rel * push_up_munion(mvc *sql, sql_rel *rel, list *ad) { @@ -1594,6 +1589,9 @@ push_up_munion(mvc *sql, sql_rel *rel, l int len = 0, need_length_reduction = 0; int rec = is_recursive(s); + /* Incase of recursive push up the project of the base side (inplace) */ + /* push normaly into right side, but stop when we hit this base again */ + /* left of rel should be a set */ list *rlist = sa_list(sql->sa); if (d && is_distinct_set(sql, d, ad) && s && is_munion(s->op)) { @@ -1639,6 +1637,20 @@ push_up_munion(mvc *sql, sql_rel *rel, l set_processed(sl); n->data = sl; } + if (rec) { + sql_rel *sl = rlist->h->data; + list *exps = exps_copy(sql, ad); + for(node *n = exps->h; n; n = n->next) { + sql_exp *e = n->data; + set_freevar(e, 0); + } + sl->exps = list_merge(exps, sl->exps, (fdup)NULL); + sql_rel *nl = rel_crossproduct(sql->sa, rel_dup(d), sl->l, rel->op); + nl->exps = exps_copy(sql, rel->exps); + set_dependent(nl); + set_processed(nl); + sl->l = nl; + } sql_rel *ns = rel_setop_n_ary(sql->sa, rlist, s->op); ns->exps = exps_copy(sql, s->exps); @@ -1660,15 +1672,6 @@ push_up_munion(mvc *sql, sql_rel *rel, l ns->exps = list_merge(sexps, ns->exps, (fdup)NULL); } /* add/remove projections to inner parts of the union (as we push a join or semijoin down) */ - if (rec) { - sql_rel *sl = rlist->h->data; - list *exps = exps_copy(sql, ad); - for(node *n = exps->h; n; n = n->next) { - sql_exp *e = n->data; - set_freevar(e, 0); - } - sl->exps = list_merge(exps, sl->exps, (fdup)NULL); - } for(node *n = rec?rlist->h->next:rlist->h; n; n = n->next) { sql_rel *sl = n->data; n->data = rel_project(sql->sa, sl, rel_projections(sql, sl, NULL, 1, 1)); @@ -1697,8 +1700,6 @@ push_up_munion(mvc *sql, sql_rel *rel, l return rel; } -static sql_rel * rel_unnest_dependent(mvc *sql, sql_rel *rel); - static sql_rel * push_up_table(mvc *sql, sql_rel *rel) { @@ -1829,10 +1830,13 @@ rel_unnest_dependent(mvc *sql, sql_rel * sql_rel *l = r->l; if (!rel_is_ref(r) && l && !rel_is_ref(l) && l->op == op_join && list_empty(l->exps)) { + int fv = exps_have_freevar(sql, r->exps); l->exps = r->exps; r->l = NULL; rel_destroy(r); rel->r = l; + if (fv) + rel->op = op_left; return rel_unnest_dependent(sql, rel); } } diff --git a/sql/test/cte/Tests/test_correlated_recursive_cte.test b/sql/test/cte/Tests/test_correlated_recursive_cte.test --- a/sql/test/cte/Tests/test_correlated_recursive_cte.test +++ b/sql/test/cte/Tests/test_correlated_recursive_cte.test @@ -90,8 +90,6 @@ 4 4 # Correlation with multiple recursive anchors -# too many rows -skipif knownfail query II SELECT x, y FROM generate_series(1,4+1) AS _(x), LATERAL @@ -143,8 +141,6 @@ 2 4 # Complex nested recursive query -# sum(z) wrong output -skipif knownfail query III rowsort SELECT x, y, (WITH RECURSIVE t(z) AS ( SELECT x + y @@ -162,22 +158,29 @@ SELECT x, y, (WITH RECURSIVE t(z) AS ( ) SELECT sum(z) FROM t) AS z FROM generate_series(1,2+1) AS _(x), generate_series(1,2+1) AS __(y) order by all; ---- -1 1 23 -1 2 12 -2 1 12 -2 2 9 +1 +1 +23 +1 +2 +12 +2 +1 +12 +2 +2 +9 statement ok CREATE TABLE a AS SELECT * FROM generate_series(1,100+1) t1(i); -# expression fails to bind -skipif knownfail query I SELECT t2.* FROM (VALUES (1000000)) t(_corr), LATERAL ( WITH RECURSIVE t AS ( - SELECT 1 AS x + SELECT cast(1 as bigint) + AS x UNION SELECT SUM(x) AS x FROM t, a @@ -201,7 +204,7 @@ WITH RECURSIVE t AS ( SELECT 1 AS x UNION - SELECT (SELECT t.x+t2.x FROM t t2 LIMIT 1) AS x + SELECT (SELECT t.x+t2.x FROM t t2 limit 1) AS x FROM t WHERE x < _corr ) _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org