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