Changeset: 5d46ef638df2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5d46ef638df2
Modified Files:
        sql/server/rel_unnest.c
        sql/test/SQLancer/Tests/sqlancer07.stable.out
        sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
Branch: octbugs
Log Message:

rewrite outer-join when we have a outer ref (freevar) or subquery (exp_is_rel)
into union( innerjoin/ except (x, innerjoin)) ..
added expra projection around innerjoin to make sure, unnesting can savely 
happen


diffs (146 lines):

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
@@ -898,8 +898,10 @@ push_up_project(mvc *sql, sql_rel *rel, 
                                }
                        }
                        /* remove old project */
-                       rel->r = r->l;
-                       r->l = NULL;
+                       if (r->l) {
+                               rel->r = r->l;
+                               r->l = NULL;
+                       }
                        rel_destroy(r);
                        return n;
                }
@@ -3122,7 +3124,7 @@ static sql_rel *
 rewrite_outer2inner_union(visitor *v, sql_rel *rel)
 {
        if (is_outerjoin(rel->op) && !list_empty(rel->exps) && 
(((is_left(rel->op) || is_full(rel->op)) && rel_has_freevar(v->sql,rel->l)) ||
-               ((is_right(rel->op) || is_full(rel->op)) && 
rel_has_freevar(v->sql,rel->r)) || exps_have_freevar(v->sql, rel->exps) 
/*exps_have_rel_exp(rel->exps)*/)) {
+               ((is_right(rel->op) || is_full(rel->op)) && 
rel_has_freevar(v->sql,rel->r)) || exps_have_freevar(v->sql, rel->exps) || 
exps_have_rel_exp(rel->exps))) {
                sql_exp *f = exp_atom_bool(v->sql->sa, 0);
                int nrcols = rel->nrcols;
 
@@ -3130,44 +3132,47 @@ rewrite_outer2inner_union(visitor *v, sq
                nrcols += include_tid(rel->r);
                rel->nrcols = nrcols;
                if (is_left(rel->op)) {
+                       sql_rel *prel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
                        sql_rel *except = rel_setop(v->sql->sa,
                                        rel_project(v->sql->sa, 
rel_dup(rel->l), rel_projections(v->sql, rel->l, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, rel_dup(rel), 
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
+                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
                        rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->l, NULL, 1, 1));
                        sql_rel *nrel = rel_crossproduct(v->sql->sa, except, 
rel_dup(rel->r),  op_left);
                        rel_join_add_exp(v->sql->sa, nrel, f);
                        rel->op = op_join;
                        nrel = rel_setop(v->sql->sa,
-                                       rel_project(v->sql->sa, rel,  
rel_projections(v->sql, rel, NULL, 1, 1)),
+                                       prel,
                                        rel_project(v->sql->sa, nrel, 
rel_projections(v->sql, nrel, NULL, 1, 1)),
                                        op_union);
                        rel_set_exps(nrel, rel_projections(v->sql, rel, NULL, 
1, 1));
                        return nrel;
                } else if (is_right(rel->op)) {
+                       sql_rel *prel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
                        sql_rel *except = rel_setop(v->sql->sa,
                                        rel_project(v->sql->sa, 
rel_dup(rel->r), rel_projections(v->sql, rel->r, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, rel_dup(rel), 
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
+                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
                        rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->r, NULL, 1, 1));
                        sql_rel *nrel = rel_crossproduct(v->sql->sa, 
rel_dup(rel->l), except, op_right);
                        rel_join_add_exp(v->sql->sa, nrel, f);
                        rel->op = op_join;
                        nrel = rel_setop(v->sql->sa,
-                                       rel_project(v->sql->sa, rel,  
rel_projections(v->sql, rel, NULL, 1, 1)),
+                                       prel,
                                        rel_project(v->sql->sa, nrel, 
rel_projections(v->sql, nrel, NULL, 1, 1)),
                                        op_union);
                        rel_set_exps(nrel, rel_projections(v->sql, rel, NULL, 
1, 1));
                        return nrel;
                } else if (is_full(rel->op)) {
+                       sql_rel *prel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
                        sql_rel *except = rel_setop(v->sql->sa,
                                        rel_project(v->sql->sa, 
rel_dup(rel->l), rel_projections(v->sql, rel->l, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, rel_dup(rel), 
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
+                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
                        rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->l, NULL, 1, 1));
                        sql_rel *lrel = rel_crossproduct(v->sql->sa, except, 
rel_dup(rel->r),  op_left);
                        rel_join_add_exp(v->sql->sa, lrel, f);
 
                        except = rel_setop(v->sql->sa,
                                        rel_project(v->sql->sa, 
rel_dup(rel->r), rel_projections(v->sql, rel->r, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, rel_dup(rel), 
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
+                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
                        rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->r, NULL, 1, 1));
                        sql_rel *rrel = rel_crossproduct(v->sql->sa, 
rel_dup(rel->l), except, op_right);
                        rel_join_add_exp(v->sql->sa, rrel, f);
@@ -3178,7 +3183,7 @@ rewrite_outer2inner_union(visitor *v, sq
                        rel_setop_set_exps(v->sql, lrel, 
rel_projections(v->sql, rel, NULL, 1, 1));
                        rel->op = op_join;
                        lrel = rel_setop(v->sql->sa,
-                                       rel_project(v->sql->sa, rel,  
rel_projections(v->sql, rel, NULL, 1, 1)),
+                                       rel_project(v->sql->sa, prel,  
rel_projections(v->sql, rel, NULL, 1, 1)),
                                        rel_project(v->sql->sa, lrel, 
rel_projections(v->sql, lrel, NULL, 1, 1)),
                                        op_union);
                        rel_setop_set_exps(v->sql, lrel, 
rel_projections(v->sql, rel, NULL, 1, 1));
@@ -3278,10 +3283,9 @@ rel_unnest(mvc *sql, sql_rel *rel)
 
        rel = rel_visitor_bottomup(&v, rel, &rewrite_aggregates);
        rel = rel_exp_visitor_bottomup(&v, rel, &rewrite_rank, false);
+       rel = rel_visitor_bottomup(&v, rel, &rewrite_values);
        rel = rel_visitor_bottomup(&v, rel, &rewrite_outer2inner_union);
 
-       rel = rel_visitor_bottomup(&v, rel, &rewrite_values); /* must come 
before rewrite_exp_rel */
-
        // remove empty project/groupby !
        rel = rel_visitor_bottomup(&v, rel, &rewrite_empty_project);
        rel = rel_exp_visitor_bottomup(&v, rel, &rewrite_complex, true);
diff --git a/sql/test/SQLancer/Tests/sqlancer07.stable.out 
b/sql/test/SQLancer/Tests/sqlancer07.stable.out
--- a/sql/test/SQLancer/Tests/sqlancer07.stable.out
+++ b/sql/test/SQLancer/Tests/sqlancer07.stable.out
@@ -73,7 +73,7 @@ stdout of test 'sqlancer07` in directory
 #CREATE TABLE "t1" ("c0" INTERVAL MONTH,"c1" BOOLEAN);
 #CREATE TABLE "t2" ("c0" INTERVAL MONTH);
 #SELECT CAST(t1.c1 AS INT) FROM t1, t0 RIGHT OUTER JOIN t2 ON ((SELECT 
DISTINCT t1.c0 FROM t1, t0 WHERE FALSE)) NOT IN (t0.c0);
-% sys.%4 # table_name
+% .%4 # table_name
 % %4 # name
 % int # type
 % 1 # length
@@ -467,8 +467,8 @@ stdout of test 'sqlancer07` in directory
 % 1,   1 # length
 [ 1,   2       ]
 #SELECT FALSE FROM v3, v0 FULL OUTER JOIN v4 ON sql_max(FALSE, (0.6902854) NOT 
IN (0.5854332103580835, CASE WHEN v4.vc0 THEN (SELECT 0.023816515 WHERE TRUE) 
END));
-% .%16 # table_name
-% %16 # name
+% .%15 # table_name
+% %15 # name
 % boolean # type
 % 5 # length
 [ false        ]
diff --git a/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128 
b/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
--- a/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
+++ b/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
@@ -73,7 +73,7 @@ stdout of test 'sqlancer07` in directory
 #CREATE TABLE "t1" ("c0" INTERVAL MONTH,"c1" BOOLEAN);
 #CREATE TABLE "t2" ("c0" INTERVAL MONTH);
 #SELECT CAST(t1.c1 AS INT) FROM t1, t0 RIGHT OUTER JOIN t2 ON ((SELECT 
DISTINCT t1.c0 FROM t1, t0 WHERE FALSE)) NOT IN (t0.c0);
-% sys.%4 # table_name
+% .%4 # table_name
 % %4 # name
 % int # type
 % 1 # length
@@ -467,8 +467,8 @@ stdout of test 'sqlancer07` in directory
 % 1,   1 # length
 [ 1,   2       ]
 #SELECT FALSE FROM v3, v0 FULL OUTER JOIN v4 ON sql_max(FALSE, (0.6902854) NOT 
IN (0.5854332103580835, CASE WHEN v4.vc0 THEN (SELECT 0.023816515 WHERE TRUE) 
END));
-% .%16 # table_name
-% %16 # name
+% .%15 # table_name
+% %15 # name
 % boolean # type
 % 5 # length
 [ false        ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to