Changeset: 2f87799f6ece for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2f87799f6ece
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/rel_unnest.c
        sql/test/mergetables/Tests/sqlsmith-exists2.stable.out
        sql/test/subquery/Tests/subquery5.stable.out
Branch: Jun2020
Log Message:

add more projects around relations when introduction set operators
reduce explosion of relations when rewriting outer joins into inner + union


diffs (215 lines):

diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -7701,7 +7701,6 @@ rel_simplify_predicates(mvc *sql, sql_re
                                        } else if (is_atom(r->type) && r->l) { 
/* direct literal */
                                                atom *a = r->l;
                                                int flag = a->data.val.bval;
-                                               list *args = l->l;
 
                                                assert(list_length(args) == 1);
                                                l = args->h->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
@@ -2966,7 +2966,7 @@ include_tid(sql_rel *r)
 static sql_rel *
 rewrite_outer2inner_union(mvc *sql, sql_rel *rel, int *changes)
 {
-       if (is_outerjoin(rel->op) && !list_empty(rel->exps) && 
rel_has_freevar(sql,rel)) {
+       if (is_outerjoin(rel->op) && !list_empty(rel->exps) && 
(rel_has_freevar(sql,rel->l) || rel_has_freevar(sql,rel->r) || 
exps_have_rel_exp(rel->exps))) {
                sql_exp *f = exp_atom_bool(sql->sa, 0);
                int nrcols = rel->nrcols;
 
@@ -2975,37 +2975,57 @@ rewrite_outer2inner_union(mvc *sql, sql_
                nrcols += include_tid(rel->r);
                rel->nrcols = nrcols;
                if (is_left(rel->op)) {
-                       sql_rel *except = rel_setop(sql->sa, rel_dup(rel->l), 
rel_project(sql->sa, rel_dup(rel), rel_projections(sql, rel->l, NULL, 1, 1)), 
op_except);
+                       sql_rel *except = rel_setop(sql->sa, 
+                                       rel_project(sql->sa, rel_dup(rel->l), 
rel_projections(sql, rel->l, NULL, 1, 1)), 
+                                       rel_project(sql->sa, rel_dup(rel), 
rel_projections(sql, rel->l, NULL, 1, 1)), op_except);
                        except->exps = rel_projections(sql, rel->l, NULL, 1, 1);
                        sql_rel *nrel = rel_crossproduct(sql->sa, except, 
rel_dup(rel->r),  op_left);
                        rel_join_add_exp(sql->sa, nrel, f);
                        rel->op = op_join;
-                       nrel = rel_setop(sql->sa, rel, nrel, op_union);
+                       nrel = rel_setop(sql->sa, 
+                                       rel_project(sql->sa, rel,  
rel_projections(sql, rel, NULL, 1, 1)),
+                                       rel_project(sql->sa, nrel, 
rel_projections(sql, nrel, NULL, 1, 1)),
+                                       op_union);
                        rel_set_exps(nrel, rel_projections(sql, rel, NULL, 1, 
1));
                        return nrel;
                } else if (is_right(rel->op)) {
-                       sql_rel *except = rel_setop(sql->sa, rel_dup(rel->r), 
rel_project(sql->sa, rel_dup(rel), rel_projections(sql, rel->r, NULL, 1, 1)), 
op_except);
+                       sql_rel *except = rel_setop(sql->sa, 
+                                       rel_project(sql->sa, rel_dup(rel->r), 
rel_projections(sql, rel->r, NULL, 1, 1)), 
+                                       rel_project(sql->sa, rel_dup(rel), 
rel_projections(sql, rel->r, NULL, 1, 1)), op_except);
                        except->exps = rel_projections(sql, rel->r, NULL, 1, 1);
                        sql_rel *nrel = rel_crossproduct(sql->sa, 
rel_dup(rel->l), except, op_right);
                        rel_join_add_exp(sql->sa, nrel, f);
                        rel->op = op_join;
-                       nrel = rel_setop(sql->sa, rel, nrel, op_union);
+                       nrel = rel_setop(sql->sa, 
+                                       rel_project(sql->sa, rel,  
rel_projections(sql, rel, NULL, 1, 1)),
+                                       rel_project(sql->sa, nrel, 
rel_projections(sql, nrel, NULL, 1, 1)),
+                                       op_union);
                        rel_set_exps(nrel, rel_projections(sql, rel, NULL, 1, 
1));
                        return nrel;
                } else if (is_full(rel->op)) {
-                       sql_rel *except = rel_setop(sql->sa, rel_dup(rel->l), 
rel_project(sql->sa, rel_dup(rel), rel_projections(sql, rel->l, NULL, 1, 1)), 
op_except);
+                       sql_rel *except = rel_setop(sql->sa, 
+                                       rel_project(sql->sa, rel_dup(rel->l), 
rel_projections(sql, rel->l, NULL, 1, 1)), 
+                                       rel_project(sql->sa, rel_dup(rel), 
rel_projections(sql, rel->l, NULL, 1, 1)), op_except);
                        except->exps = rel_projections(sql, rel->l, NULL, 1, 1);
                        sql_rel *lrel = rel_crossproduct(sql->sa, except, 
rel_dup(rel->r),  op_left);
                        rel_join_add_exp(sql->sa, lrel, f);
 
-                       except = rel_setop(sql->sa, rel_dup(rel->r), 
rel_project(sql->sa, rel_dup(rel), rel_projections(sql, rel->r, NULL, 1, 1)), 
op_except);
+                       except = rel_setop(sql->sa, 
+                                       rel_project(sql->sa, rel_dup(rel->r), 
rel_projections(sql, rel->r, NULL, 1, 1)), 
+                                       rel_project(sql->sa, rel_dup(rel), 
rel_projections(sql, rel->r, NULL, 1, 1)), op_except);
                        except->exps = rel_projections(sql, rel->r, NULL, 1, 1);
                        sql_rel *rrel = rel_crossproduct(sql->sa, 
rel_dup(rel->l), except, op_right);
                        rel_join_add_exp(sql->sa, rrel, f);
-                       lrel = rel_setop(sql->sa, lrel, rrel, op_union);
+                       lrel = rel_setop(sql->sa, 
+                                       rel_project(sql->sa, lrel,  
rel_projections(sql, lrel, NULL, 1, 1)),
+                                       rel_project(sql->sa, rrel, 
rel_projections(sql, rrel, NULL, 1, 1)),
+                                       op_union);
                        rel_set_exps(lrel, rel_projections(sql, rel, NULL, 1, 
1));
                        rel->op = op_join;
-                       lrel = rel_setop(sql->sa, rel, lrel, op_union);
+                       lrel = rel_setop(sql->sa, 
+                                       rel_project(sql->sa, rel,  
rel_projections(sql, rel, NULL, 1, 1)),
+                                       rel_project(sql->sa, lrel, 
rel_projections(sql, lrel, NULL, 1, 1)),
+                                       op_union);
                        rel_set_exps(lrel, rel_projections(sql, rel, NULL, 1, 
1));
                        return lrel;
                }
diff --git a/sql/test/mergetables/Tests/sqlsmith-exists2.stable.out 
b/sql/test/mergetables/Tests/sqlsmith-exists2.stable.out
--- a/sql/test/mergetables/Tests/sqlsmith-exists2.stable.out
+++ b/sql/test/mergetables/Tests/sqlsmith-exists2.stable.out
@@ -298,6 +298,108 @@ stdout of test 'sqlsmith-exists2` in dir
 [ "Ball",      0,      NULL    ]
 [ "Ball",      0,      NULL    ]
 [ "Ball",      0,      NULL    ]
+#select 
+# subq_1.c0 as c0, 
+# subq_1.c0 as c1, 
+# subq_1.c0 as c2, 
+# subq_0.c0 as c3, 
+# subq_0.c1 as c4, 
+# subq_0.c0 as c5, 
+# subq_0.c0 as c6
+#from 
+# (select 
+# ref_0.col0 as c0, 
+# ref_1.bb as c1
+# from 
+# tab0 as ref_0
+# right join analytics as ref_1
+# on (exists (
+# select 
+# ref_1.aa as c0
+# from 
+# longtable as ref_2
+# where ref_0.col2 is not null))
+# where ((ref_1.aa is null) 
+# and ((false) 
+# and (ref_0.col2 is not null))) 
+# or (ref_0.col2 is not null)) as subq_0
+# inner join (select 
+# ref_3.col3 as c0
+# from 
+# tbl_productsales as ref_3
+% .,   .,      .,      .,      .,      .,      . # table_name
+% c0,  c1,     c2,     c3,     c4,     c5,     c6 # name
+% varchar,     varchar,        varchar,        int,    int,    int,    int # 
type
+% 0,   0,      0,      1,      1,      1,      1 # length
+#select 
+# ref_0.col2 as c0, 
+# cast(nullif(ref_0.col1,
+# ref_0.col0) as int) as c1, 
+# 29 as c2, 
+# ref_0.col1 as c3, 
+# ref_0.col1 as c4, 
+# ref_0.col0 as c5
+#from 
+# tab1 as ref_0
+#where (((true) 
+# and ((ref_0.col0 is not null) 
+# and (ref_0.col2 is null))) 
+# or (false)) 
+# or (exists (
+# select 
+# ref_1.col2 as c0, 
+# subq_0.c0 as c1, 
+# ref_1.col1 as c2, 
+# subq_0.c6 as c3, 
+# ref_0.col1 as c4, 
+# ref_1.col2 as c5, 
+# ref_1.col1 as c6, 
+# ref_1.col0 as c7, 
+# ref_0.col2 as c8, 
+# ref_1.col1 as c9, 
+# ref_1.col0 as c10, 
+# subq_0.c1 as c11, 
+% .,   .,      .,      .,      .,      . # table_name
+% c0,  c1,     c2,     c3,     c4,     c5 # name
+% int, int,    tinyint,        int,    int,    int # type
+% 2,   2,      2,      2,      2,      2 # length
+[ 96,  14,     29,     14,     14,     51      ]
+[ 59,  5,      29,     5,      5,      85      ]
+[ 68,  47,     29,     47,     47,     91      ]
+#select 
+# cast(coalesce(subq_1.c0,
+# cast(nullif(subq_0.c0,
+# 93) as int)) as int) as c0, 
+# subq_1.c0 as c1
+#from 
+# (select 
+# ref_0.col4 as c0, 
+# ref_0.col7 as c1, 
+# ref_0.col4 as c2
+# from 
+# another_t as ref_0
+# where false
+# limit 139) as subq_0
+# inner join (select 
+# ref_1.col1 as c0
+# from 
+# longtable as ref_1
+# where 7 is not null
+# limit 114) as subq_1
+# on (exists (
+# select 
+# ref_3.col1 as c0, 
+# subq_1.c0 as c1, 
+# ref_3.col0 as c2, 
+# ref_2.bb as c3, 
+# ref_4.col8 as c4
+# from 
+# analytics as ref_2
+# left join tab2 as ref_3
+% .,   . # table_name
+% c0,  c1 # name
+% int, int # type
+% 1,   1 # length
 #ROLLBACK;
 
 # 22:12:15 >  
diff --git a/sql/test/subquery/Tests/subquery5.stable.out 
b/sql/test/subquery/Tests/subquery5.stable.out
--- a/sql/test/subquery/Tests/subquery5.stable.out
+++ b/sql/test/subquery/Tests/subquery5.stable.out
@@ -208,8 +208,8 @@ stdout of test 'subquery5` in directory 
 [ NULL,        3       ]
 [ NULL,        NULL    ]
 #SELECT 1 FROM integers i1 RIGHT OUTER JOIN integers i2 ON NOT EXISTS(SELECT 
1);
-% . # table_name
-% single_value # name
+% .%17 # table_name
+% %17 # name
 % tinyint # type
 % 1 # length
 [ 1    ]
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to