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