Changeset: 85e9226abd1f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=85e9226abd1f
Removed Files:
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-prologue.sql
Modified Files:
sql/server/rel_optimizer.c
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-prologue.test
Branch: default
Log Message:
Merged with Oct2020
diffs (182 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
@@ -1659,13 +1659,32 @@ rel_push_count_down(visitor *v, sql_rel
return rel;
}
+static bool
+check_projection_on_foreignside(sql_rel *r, list *pexps, int fk_left)
+{
+ /* projection columns from the foreign side */
+ if (list_empty(pexps))
+ return true;
+ for (node *n = pexps->h; n; n = n->next) {
+ sql_exp *pe = n->data;
+
+ if (pe && is_atom(pe->type))
+ continue;
+ if (pe && !is_alias(pe->type))
+ return false;
+ /* check for columns from the pk side, then keep the join with
the pk */
+ if ((fk_left && rel_find_exp(r->r, pe)) || (!fk_left &&
rel_find_exp(r->l, pe)))
+ return false;
+ }
+ return true;
+}
+
static sql_rel *
-rel_simplify_project_fk_join(mvc *sql, sql_rel *r, list *pexps, int *changes)
+rel_simplify_project_fk_join(mvc *sql, sql_rel *r, list *pexps, list
*orderexps, int *changes)
{
sql_rel *rl = r->l;
sql_rel *rr = r->r;
sql_exp *je, *le, *nje, *re;
- node *n;
int fk_left = 1;
/* check for foreign key join */
@@ -1695,22 +1714,11 @@ rel_simplify_project_fk_join(mvc *sql, s
#endif
/* primary side must be a full table */
if ((fk_left && (!is_left(r->op) && !is_full(r->op)) &&
!is_basetable(rr->op)) ||
- (!fk_left && (!is_right(r->op) && !is_full(r->op)) &&
!is_basetable(rl->op)))
+ (!fk_left && (!is_right(r->op) && !is_full(r->op)) &&
!is_basetable(rl->op)))
return r;
- /* projection columns from the foreign side */
- for (n = pexps->h; n; n = n->next) {
- sql_exp *pe = n->data;
-
- if (pe && is_atom(pe->type))
- continue;
- if (pe && !is_alias(pe->type))
- return r;
- /* check for columns from the pk side, then keep the join with
the pk */
- if ((fk_left && rel_find_exp(r->r, pe)) ||
- (!fk_left && rel_find_exp(r->l, pe)))
- return r;
- }
+ if (!check_projection_on_foreignside(r, pexps, fk_left) ||
!check_projection_on_foreignside(r, orderexps, fk_left))
+ return r;
/* rewrite, ie remove pkey side if possible */
le = (sql_exp*)je->l, re = (sql_exp*)je->l;
@@ -1733,7 +1741,7 @@ rel_simplify_project_fk_join(mvc *sql, s
}
static sql_rel *
-rel_simplify_count_fk_join(mvc *sql, sql_rel *r, list *gexps, int *changes)
+rel_simplify_count_fk_join(mvc *sql, sql_rel *r, list *gexps, list *gcols, int
*changes)
{
sql_rel *rl = r->l;
sql_rel *rr = r->r;
@@ -1760,18 +1768,21 @@ rel_simplify_count_fk_join(mvc *sql, sql
/* primary side must be a full table */
if ((fk_left && (!is_left(r->op) && !is_full(r->op)) &&
!is_basetable(rr->op)) ||
- (!fk_left && (!is_right(r->op) && !is_full(r->op)) &&
!is_basetable(rl->op)))
+ (!fk_left && (!is_right(r->op) && !is_full(r->op)) &&
!is_basetable(rl->op)))
return r;
if (fk_left && is_join(rl->op) && !rel_is_ref(rl)) {
- rl = rel_simplify_count_fk_join(sql, rl, gexps, changes);
+ rl = rel_simplify_count_fk_join(sql, rl, gexps, gcols, changes);
r->l = rl;
}
if (!fk_left && is_join(rr->op) && !rel_is_ref(rr)) {
- rr = rel_simplify_count_fk_join(sql, rr, gexps, changes);
+ rr = rel_simplify_count_fk_join(sql, rr, gexps, gcols, changes);
r->r = rr;
}
+ if (!check_projection_on_foreignside(r, gcols, fk_left))
+ return r;
+
/* rewrite, ie remove pkey side if possible */
le = (sql_exp*)je->l, re = (sql_exp*)je->l;
@@ -1794,7 +1805,7 @@ rel_simplify_count_fk_join(mvc *sql, sql
/*
* Handle (left/right/outer/natural) join fk-pk rewrites
- * 1 group by ( fk-pk-join () ) [ count(*) ] -> groub py ( fk )
+ * 1 group by ( fk-pk-join () ) [ count(*) ] -> group by ( fk )
* 2 project ( fk-pk-join () ) [ fk-column ] -> project (fk table)[
fk-column ]
* 3 project ( fk1-pk1-join( fk2-pk2-join()) [ fk-column, pk1 column ] ->
project (fk1-pk1-join)[ fk-column, pk1 column ]
*/
@@ -1803,13 +1814,13 @@ rel_simplify_fk_joins(visitor *v, sql_re
{
sql_rel *r = NULL;
- if (rel->op == op_project)
+ if (is_simple_project(rel->op))
r = rel->l;
- while (rel->op == op_project && r && r->exps && list_length(r->exps) ==
1 && is_join(r->op) && !(rel_is_ref(r))) {
+ while (is_simple_project(rel->op) && r && list_length(r->exps) == 1 &&
is_join(r->op) && !(rel_is_ref(r))) {
sql_rel *or = r;
- r = rel_simplify_project_fk_join(v->sql, r, rel->exps,
&v->changes);
+ r = rel_simplify_project_fk_join(v->sql, r, rel->exps, rel->r,
&v->changes);
if (r == or)
return rel;
rel->l = r;
@@ -1819,16 +1830,15 @@ rel_simplify_fk_joins(visitor *v, sql_re
return rel;
r = rel->l;
- while(r && r->op == op_project)
+ while(r && is_simple_project(r->op))
r = r->l;
- while (is_groupby(rel->op) && !rel_is_ref(rel) &&
- r && r->exps && is_join(r->op) && list_length(r->exps) == 1 &&
!(rel_is_ref(r)) &&
- /* currently only single count aggregation is handled, no other
projects or aggregation */
- list_length(rel->exps) == 1 &&
exp_aggr_is_count(rel->exps->h->data)) {
+ while (is_groupby(rel->op) && !rel_is_ref(rel) && r && is_join(r->op)
&& list_length(r->exps) == 1 && !(rel_is_ref(r)) &&
+ /* currently only single count aggregation is handled, no
other projects or aggregation */
+ list_length(rel->exps) == 1 &&
exp_aggr_is_count(rel->exps->h->data)) {
sql_rel *or = r;
- r = rel_simplify_count_fk_join(v->sql, r, rel->exps,
&v->changes);
+ r = rel_simplify_count_fk_join(v->sql, r, rel->exps, rel->r,
&v->changes);
if (r == or)
return rel;
rel->l = r;
diff --git
a/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-prologue.test
b/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-prologue.test
---
a/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-prologue.test
+++
b/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-prologue.test
@@ -423,3 +423,32 @@ 22
3
21
+statement ok
+start transaction
+
+statement ok
+CREATE TABLE "myt" ("myid" int NOT NULL,"great" varchar(32),CONSTRAINT
"mypkey" PRIMARY KEY ("myid"))
+
+statement ok
+insert into myt values (1, 'a'),(2, 'b'),(3, 'c'),(4, 'd')
+
+statement ok
+CREATE TABLE "testme" ("good" int,"myid" int NOT NULL,"hello"
varchar(32),CONSTRAINT "givemeapkey" PRIMARY KEY ("myid"),CONSTRAINT "myfkey"
FOREIGN KEY ("good") REFERENCES "myt" ("myid"))
+
+statement ok
+insert into testme values (1, 1, 'a'),(2, 2, 'b'),(3, 3, 'c'),(4, 4, 'd')
+
+query I nosort
+select testme.myid from testme inner join "myt" on testme.good = "myt".myid
where testme.hello = 'd' order by "myt".great limit 10
+----
+4
+
+query I rowsort
+select count(*) from testme inner join "myt" on testme.good = "myt".myid where
testme.hello = 'd' group by "myt".great
+----
+1
+
+statement ok
+rollback
+
+
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list