Changeset: 1c9f2e6fbdc7 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/1c9f2e6fbdc7
Modified Files:
        sql/server/rel_optimizer.c
Branch: default
Log Message:

Merged with Jul2021


diffs (252 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
@@ -4634,13 +4634,13 @@ rel_push_select_down(visitor *v, sql_rel
        exps = rel->exps;
 
        /* push select through join */
-       if (is_select(rel->op) && r && is_join(r->op) && !(rel_is_ref(r))) {
+       if (is_select(rel->op) && r && is_join(r->op) && !rel_is_ref(r) && 
!is_single(r)){
                sql_rel *jl = r->l;
                sql_rel *jr = r->r;
                int left = r->op == op_join || r->op == op_left;
                int right = r->op == op_join || r->op == op_right;
 
-               if (r->op == op_full || is_single(r))
+               if (r->op == op_full)
                        return rel;
 
                /* introduce selects under the join (if needed) */
@@ -4668,7 +4668,7 @@ rel_push_select_down(visitor *v, sql_rel
        }
 
        /* merge select and cross product ? */
-       if (is_select(rel->op) && r && r->op == op_join && !(rel_is_ref(r))) {
+       if (is_select(rel->op) && r && r->op == op_join && !rel_is_ref(r) && 
!is_single(r)){
                for (n = exps->h; n;) {
                        node *next = n->next;
                        sql_exp *e = n->data;
@@ -4684,7 +4684,7 @@ rel_push_select_down(visitor *v, sql_rel
                }
        }
 
-       if (is_select(rel->op) && r && r->op == op_project && !(rel_is_ref(r))){
+       if (is_select(rel->op) && r && r->op == op_project && !rel_is_ref(r) && 
!is_single(r)){
                sql_rel *pl = r->l;
                /* we cannot push through rank (row_number etc) functions or 
projects with distinct */
                if (pl && !project_unsafe(r, 1, 1)) {
@@ -4710,6 +4710,55 @@ rel_push_select_down(visitor *v, sql_rel
                        }
                }
        }
+
+       /* try push select under set relation */
+       if (is_select(rel->op) && r && !rel_is_ref(r) && !is_single(r) && 
!list_empty(exps)) {
+               sql_rel *u = r, *ou = u;
+               sql_rel *ul = u->l;
+               sql_rel *ur = u->r;
+
+               if (!rel_is_ref(u) && !is_single(u) && u->op == op_project)
+                       u = u->l;
+
+               if (u && is_set(u->op) && !is_single(u) && !list_empty(u->exps) 
&& !rel_is_ref(u)) {
+                       ul = u->l;
+                       ur = u->r;
+
+                       ul = rel_dup(ul);
+                       ur = rel_dup(ur);
+                       if (!is_project(ul->op))
+                               ul = rel_project(v->sql->sa, ul,
+                                       rel_projections(v->sql, ul, NULL, 1, 
1));
+                       if (!is_project(ur->op))
+                               ur = rel_project(v->sql->sa, ur,
+                                       rel_projections(v->sql, ur, NULL, 1, 
1));
+                       rel_rename_exps(v->sql, u->exps, ul->exps);
+                       rel_rename_exps(v->sql, u->exps, ur->exps);
+
+                       if (u != ou) {
+                               ul = rel_project(v->sql->sa, ul, NULL);
+                               ul->exps = exps_copy(v->sql, ou->exps);
+                               rel_rename_exps(v->sql, ou->exps, ul->exps);
+                               set_processed(ul);
+                               ur = rel_project(v->sql->sa, ur, NULL);
+                               ur->exps = exps_copy(v->sql, ou->exps);
+                               rel_rename_exps(v->sql, ou->exps, ur->exps);
+                               set_processed(ur);
+                       }
+
+                       /* introduce selects under the set */
+                       ul = rel_select(v->sql->sa, ul, NULL);
+                       ul->exps = exps_copy(v->sql, exps);
+                       ur = rel_select(v->sql->sa, ur, NULL);
+                       ur->exps = exps_copy(v->sql, exps);
+
+                       rel = rel_inplace_setop(v->sql, rel, ul, ur, u->op, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       if (need_distinct(u))
+                               set_distinct(rel);
+                       v->changes++;
+               }
+       }
+
        return try_remove_empty_select(v, rel);
 }
 
@@ -5413,60 +5462,6 @@ rel_join2semijoin(visitor *v, sql_rel *r
        return rel;
 }
 
-static sql_rel *
-rel_push_select_down_union(visitor *v, sql_rel *rel)
-{
-       if (is_select(rel->op) && rel->l && rel->exps) {
-               sql_rel *u = rel->l, *ou = u;
-               sql_rel *ul = u->l;
-               sql_rel *ur = u->r;
-
-               if (u->op == op_project)
-                       u = u->l;
-
-               if (!u || !is_union(u->op) || need_distinct(u) || is_single(u) 
|| !u->exps || rel_is_ref(u))
-                       return rel;
-
-               ul = u->l;
-               ur = u->r;
-
-               ul = rel_dup(ul);
-               ur = rel_dup(ur);
-               if (!is_project(ul->op))
-                       ul = rel_project(v->sql->sa, ul,
-                               rel_projections(v->sql, ul, NULL, 1, 1));
-               if (!is_project(ur->op))
-                       ur = rel_project(v->sql->sa, ur,
-                               rel_projections(v->sql, ur, NULL, 1, 1));
-               rel_rename_exps(v->sql, u->exps, ul->exps);
-               rel_rename_exps(v->sql, u->exps, ur->exps);
-
-               if (u != ou) {
-                       ul = rel_project(v->sql->sa, ul, NULL);
-                       ul->exps = exps_copy(v->sql, ou->exps);
-                       rel_rename_exps(v->sql, ou->exps, ul->exps);
-                       ur = rel_project(v->sql->sa, ur, NULL);
-                       ur->exps = exps_copy(v->sql, ou->exps);
-                       rel_rename_exps(v->sql, ou->exps, ur->exps);
-               }
-
-               /* introduce selects under the set (if needed) */
-               set_processed(ul);
-               set_processed(ur);
-               if (rel_is_ref(rel) || !list_empty(rel->exps)) { /* don't 
generate empty selects */
-                       ul = rel_select(v->sql->sa, ul, NULL);
-                       ul->exps = exps_copy(v->sql, rel->exps);
-                       ur = rel_select(v->sql->sa, ur, NULL);
-                       ur->exps = exps_copy(v->sql, rel->exps);
-               }
-
-               rel = rel_inplace_setop(v->sql, rel, ul, ur, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
-               v->changes++;
-               return rel;
-       }
-       return rel;
-}
-
 static int
 exp_is_rename(sql_exp *e)
 {
@@ -9545,7 +9540,6 @@ rel_optimize_unions_bottomup(visitor *v,
 static sql_rel *
 rel_optimize_unions_topdown(visitor *v, sql_rel *rel)
 {
-       rel = rel_push_select_down_union(v, rel);
        rel = rel_push_project_down_union(v, rel);
        rel = rel_push_join_down_union(v, rel);
        return rel;
diff --git a/sql/test/BugTracker-2015/Tests/crash.Bug-3736.test 
b/sql/test/BugTracker-2015/Tests/crash.Bug-3736.test
--- a/sql/test/BugTracker-2015/Tests/crash.Bug-3736.test
+++ b/sql/test/BugTracker-2015/Tests/crash.Bug-3736.test
@@ -140,29 +140,31 @@ single left outer join (
 | ) [ "b3"."id" NOT NULL HASHCOL , "b3"."increase" NOT NULL, "b3"."%TID%" NOT 
NULL, "%1"."%1", "%2"."%2" NOT NULL, "o"."open_auction_id" NOT NULL as 
"%5"."%5" ]
 ) [ "o"."open_auction_id" NOT NULL * = "%5"."%5" NOT NULL ]
 project (
-| single select (
-| | single join (
-| | | & REF 2 ,
-| | | project (
-| | | | select (
-| | | | | project (
-| | | | | | crossproduct (
-| | | | | | | table("sys"."bidder") [ "bidder"."id" NOT NULL HASHCOL  as 
"b2"."id", "bidder"."increase" NOT NULL as "b2"."increase" ] COUNT ,
-| | | | | | | group by (
-| | | | | | | | join (
-| | | | | | | | | single group by (
-| | | | | | | | | | single project (
-| | | | | | | | | | | & REF 2 
-| | | | | | | | | | ) [ "o"."open_auction_id" NOT NULL ]
-| | | | | | | | | ) [ "o"."open_auction_id" NOT NULL ] [ "o"."open_auction_id" 
NOT NULL ],
-| | | | | | | | | table("sys"."bidder") [ "bidder"."id" NOT NULL HASHCOL  as 
"b2a"."id", "bidder"."open_auction_id" NOT NULL as "b2a"."open_auction_id" ] 
COUNT 
-| | | | | | | | ) [ "b2a"."open_auction_id" NOT NULL = "o"."open_auction_id" 
NOT NULL ]
-| | | | | | | ) [ "o"."open_auction_id" NOT NULL ] [ "sys"."max" no nil 
("b2a"."id" NOT NULL HASHCOL ) as "%3"."%3", "o"."open_auction_id" NOT NULL ]
-| | | | | | ) [  ]
-| | | | | ) [ "o"."open_auction_id" NOT NULL, "b2"."id" NOT NULL HASHCOL , 
"%3"."%3", "b2"."increase" NOT NULL as "%4"."%4" ]
-| | | | ) [ "b2"."id" NOT NULL HASHCOL  = "%3"."%3" ]
-| | | ) [ "%4"."%4" NOT NULL, "o"."open_auction_id" NOT NULL as "%6"."%6" ]
-| | ) [ "o"."open_auction_id" NOT NULL * = "%6"."%6" NOT NULL ]
+| select (
+| | single project (
+| | | single left outer join (
+| | | | & REF 2 ,
+| | | | project (
+| | | | | select (
+| | | | | | project (
+| | | | | | | crossproduct (
+| | | | | | | | table("sys"."bidder") [ "bidder"."id" NOT NULL HASHCOL  as 
"b2"."id", "bidder"."increase" NOT NULL as "b2"."increase" ] COUNT ,
+| | | | | | | | group by (
+| | | | | | | | | join (
+| | | | | | | | | | single group by (
+| | | | | | | | | | | single project (
+| | | | | | | | | | | | & REF 2 
+| | | | | | | | | | | ) [ "o"."open_auction_id" NOT NULL ]
+| | | | | | | | | | ) [ "o"."open_auction_id" NOT NULL ] [ 
"o"."open_auction_id" NOT NULL ],
+| | | | | | | | | | table("sys"."bidder") [ "bidder"."id" NOT NULL HASHCOL  as 
"b2a"."id", "bidder"."open_auction_id" NOT NULL as "b2a"."open_auction_id" ] 
COUNT 
+| | | | | | | | | ) [ "b2a"."open_auction_id" NOT NULL = "o"."open_auction_id" 
NOT NULL ]
+| | | | | | | | ) [ "o"."open_auction_id" NOT NULL ] [ "sys"."max" no nil 
("b2a"."id" NOT NULL HASHCOL ) as "%3"."%3", "o"."open_auction_id" NOT NULL ]
+| | | | | | | ) [  ]
+| | | | | | ) [ "o"."open_auction_id" NOT NULL, "b2"."id" NOT NULL HASHCOL , 
"%3"."%3", "b2"."increase" NOT NULL as "%4"."%4" ]
+| | | | | ) [ "b2"."id" NOT NULL HASHCOL  = "%3"."%3" ]
+| | | | ) [ "%4"."%4" NOT NULL, "o"."open_auction_id" NOT NULL as "%6"."%6" ]
+| | | ) [ "o"."open_auction_id" NOT NULL * = "%6"."%6" NOT NULL ]
+| | ) [ "b"."id" NOT NULL HASHCOL , "b"."open_auction_id" NOT NULL, "b"."date" 
NOT NULL, "b"."time" NOT NULL, "b"."personref" NOT NULL, "b"."increase" NOT 
NULL, "%2"."%2", "%4"."%4" ]
 | ) [ "sys"."<="("sys"."sql_mul"("%2"."%2", double "2"), "%4"."%4") = boolean 
"true" ]
 ) [ "b"."id" NOT NULL HASHCOL , "b"."open_auction_id" NOT NULL, "b"."date" NOT 
NULL, "b"."time" NOT NULL, "b"."personref" NOT NULL, "b"."increase" NOT NULL ]
 
diff --git a/sql/test/miscellaneous/Tests/simple_plans.test 
b/sql/test/miscellaneous/Tests/simple_plans.test
--- a/sql/test/miscellaneous/Tests/simple_plans.test
+++ b/sql/test/miscellaneous/Tests/simple_plans.test
@@ -539,6 +539,28 @@ 3
 user.main
 1
 
+query T nosort
+plan select x, y from (select a as b, a / 3 as c from t1 intersect all select 
a as z, a / 5 as d from t2) x(x,y) where x > 2
+----
+project (
+| intersect (
+| | project (
+| | | project (
+| | | | select (
+| | | | | table("sys"."t1") [ "t1"."a" ] COUNT 
+| | | | ) [ "t1"."a" > int "2" ]
+| | | ) [ "t1"."a" as "b", "sys"."sql_div"("t1"."a", tinyint "3") as "c" ]
+| | ) [ "b" as "x"."x", "c" as "x"."y" ],
+| | project (
+| | | project (
+| | | | select (
+| | | | | table("sys"."t2") [ "t2"."a" ] COUNT 
+| | | | ) [ "t2"."a" > int "2" ]
+| | | ) [ "t2"."a" as "z", "sys"."sql_div"("t2"."a", tinyint "5") as "d" ]
+| | ) [ "z" as "x"."x", "d" as "x"."y" ]
+| ) [ "x"."x", "x"."y" ]
+) [ "x"."x", "x"."y" ]
+
 statement ok
 rollback
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to