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

Reply via email to