Changeset: e6738d06ca12 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e6738d06ca12
Modified Files:
        sql/server/rel_optimize_proj.c
        sql/server/rel_select.c
        sql/test/cte/Tests/test_correlated_recursive_cte.test
        sql/test/cte/Tests/test_cte.test
Branch: recursive_cte
Log Message:

fixed handling of nested recursive ctes


diffs (190 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
@@ -3095,6 +3095,10 @@ rel_push_project_down_union(visitor *v, 
 
                sql_rel *r;
 
+               assert(!is_union(u->op));
+               if (is_recursive(u))
+                       return rel;
+
                /* don't push project down union of single values */
                for (node *n = ((list*)u->l)->h; n; n = n->next) {
                        r = n->data;
@@ -3248,7 +3252,7 @@ rel_push_join_down_munion(visitor *v, sq
                if (is_munion(l->op) && is_munion(r->op) && list_length(l->l) 
!= list_length(r->l))
                        return rel;
 
-               if (is_munion(l->op) && !need_distinct(l) && !is_single(l) &&
+               if (is_munion(l->op) && !need_distinct(l) && !is_single(l) && 
!is_recursive(l) &&
                   !is_munion(r->op)){
                        /* join(munion(a,b,c), d) -> munion(join(a,d), 
join(b,d), join(c,d)) */
                        list *js = sa_list(v->sql->sa);
@@ -3272,8 +3276,8 @@ rel_push_join_down_munion(visitor *v, sq
                        v->changes++;
                        return rel_inplace_setop_n_ary(v->sql, rel, js, 
op_munion,
                                                               
rel_projections(v->sql, rel, NULL, 1, 1));
-               } else if (is_munion(l->op) && !need_distinct(l) && 
!is_single(l) &&
-                              is_munion(r->op) && !need_distinct(r) && 
!is_single(r) &&
+               } else if (is_munion(l->op) && !need_distinct(l) && 
!is_single(l) && !is_recursive(l) &&
+                              is_munion(r->op) && !need_distinct(r) && 
!is_single(r) && !is_recursive(r) &&
                               je) {
                        /* join(munion(a,b,c), munion(d,e,f)) -> 
munion(join(a,d), join(b,e), join(c,f)) */
                        list *cps = sa_list(v->sql->sa);
@@ -3311,7 +3315,7 @@ rel_push_join_down_munion(visitor *v, sq
                        return rel_inplace_setop_n_ary(v->sql, rel, cps, 
op_munion,
                                                                                
   rel_projections(v->sql, rel, NULL, 1, 1));
                } else if (!is_munion(l->op) &&
-                               is_munion(r->op) && !need_distinct(r) && 
!is_single(r) &&
+                               is_munion(r->op) && !need_distinct(r) && 
!is_single(r) && !is_recursive(r) &&
                               !is_semi(rel->op)) {
                        /* join(a, munion(b,c,d)) -> munion(join(a,b), 
join(a,c), join(a,d)) */
                        list *js = sa_list(v->sql->sa);
@@ -3336,7 +3340,7 @@ rel_push_join_down_munion(visitor *v, sq
                        return rel_inplace_setop_n_ary(v->sql, rel, js, 
op_munion,
                                                               
rel_projections(v->sql, rel, NULL, 1, 1));
                } else if (!is_munion(l->op) &&
-                               is_munion(r->op) && !need_distinct(r) && 
!is_single(r) &&
+                               is_munion(r->op) && !need_distinct(r) && 
!is_single(r) && !is_recursive(r) &&
                                is_semi(rel->op) && je) {
                        /* {semi}join ( A1, munion (B, A2a, C, A2b)) 
[A1.partkey = A2.partkey] ->
                         * {semi}join ( A1, munion (A2a, A2b))
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -382,7 +382,7 @@ rel_with_query(sql_query *query, symbol 
                                set_distinct(nrel);
                        rel_setop_n_ary_set_exps(sql, nrel, 
rel_projections(sql, nrel, NULL, 0, 1), false);
                        set_processed(nrel);
-                       recursive_union->rel_view = nrel;
+                       recursive_union->rel_view = rel_dup(nrel); /* extra 
incref for independent flow */
                }
                if (!is_project(nrel->op)) {
                        if (is_topn(nrel->op) || is_sample(nrel->op)) {
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
@@ -217,8 +217,6 @@ 4
 8
 16
 
-# fails to end (causing overflow)
-skipif knownfail                                                               
                                                                                
            
 query III
 SELECT t2.*
 FROM (VALUES (1)) t(_corr), LATERAL (
@@ -232,19 +230,38 @@ WITH RECURSIVE collatz(x, t, steps) AS
    WHERE  t <> _corr)
 )
 SELECT * FROM collatz WHERE t = _corr
-ORDER BY x
-) t2;
+) t2 order by x;
 ----
-1      1       0
-2      1       1
-3      1       7
-4      1       2
-5      1       5
-6      1       8
-7      1       16
-8      1       3
-9      1       19
-10     1       6
+1
+1
+0
+2
+1
+1
+3
+1
+7
+4
+1
+2
+5
+1
+5
+6
+1
+8
+7
+1
+16
+8
+1
+3
+9
+1
+19
+10
+1
+6
 
 # UNION semantics
 
diff --git a/sql/test/cte/Tests/test_cte.test b/sql/test/cte/Tests/test_cte.test
--- a/sql/test/cte/Tests/test_cte.test
+++ b/sql/test/cte/Tests/test_cte.test
@@ -94,42 +94,43 @@ select * from vb
 43
 
 # cte in set operation node
-skipif knownfail
+#SELECT 1 UNION ALL (WITH cte AS (SELECT 42) SELECT * FROM cte);
 query I
-SELECT 1 UNION ALL (WITH cte AS (SELECT 42) SELECT * FROM cte);
+SELECT 1 UNION ALL (select * from (WITH cte AS (SELECT 42) SELECT * FROM cte) 
as a)
 ----
 1
 42
 
 # cte in recursive cte
-skipif knownfail
 query I
 WITH RECURSIVE cte(d) AS (
                SELECT 1
        UNION ALL
+               (select * from
                (WITH c(d) AS (SELECT * FROM cte)
                        SELECT d + 1
                        FROM c
                        WHERE FALSE
-               )
+               ) as a)
 )
 SELECT max(d) FROM cte;
 ----
 1
 
 ## test CTE with nested aliases in where clause
-#query II
-#with cte (a) as (
-#   select 1
-#)
-#select
-#   a as alias1,
-#   alias1 as alias2
-#from cte
-#where alias2 > 0;
-#----
-#1
-#1
+# incorrect query was corrected
+query II
+with cte (a) as (
+   select 1
+)
+select
+   a as alias1,
+   a as alias2
+from cte
+where a > 0;
+----
+1
+1
 
 # recursive CTE and a non-recursive CTE with except
 query I
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to