Changeset: bbd8d70e4268 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bbd8d70e4268
Modified Files:
        sql/server/rel_optimizer.c
Branch: Nov2019
Log Message:

Perform rel_push_semijoin_down and rel_push_join_down optimizers after 
rel_join_order, so semijoins will be always pushed bellow regular joins


diffs (183 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
@@ -1374,7 +1374,7 @@ static sql_exp *
                if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) {
                        list *l, *r;
 
-                       l = exps_push_down(sql, e->l, f, t);
+                       l = exps_push_down(sql, e->l, f, t);
                        if (!l)
                                return NULL;
                        r = exps_push_down(sql, e->r, f, t);
@@ -1448,7 +1448,6 @@ exp_push_down(mvc *sql, sql_exp *e, sql_
        return _exp_push_down(sql, e, f, t);
 }
 
-
 /* some projections results are order dependend (row_number etc) */
 static int 
 project_unsafe(sql_rel *rel, int allow_identity)
@@ -1760,13 +1759,13 @@ rel_push_count_down(int *changes, mvc *s
        if (!is_groupby(rel->op))
                return rel;
 
-               r = rel->l;
+       r = rel->l;
 
        if (is_groupby(rel->op) && !rel_is_ref(rel) &&
-            r && !r->exps && r->op == op_join && !(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_exp *nce, *oce;
+               r && !r->exps && r->op == op_join && !(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_exp *nce, *oce;
                sql_rel *gbl, *gbr;             /* Group By */
                sql_rel *cp;                    /* Cross Product */
                sql_subfunc *mult;
@@ -1780,7 +1779,7 @@ rel_push_count_down(int *changes, mvc *s
                rname = exp_relname(oce);
                name  = exp_name(oce);
 
-               args = new_exp_list(sql->sa);
+               args = new_exp_list(sql->sa);
                srel = r->l;
                {
                        sql_subaggr *cf = sql_bind_aggr(sql->sa, 
sql->session->schema, "count", NULL);
@@ -6069,7 +6068,7 @@ exps_remove_dictexps(mvc *sql, list *exp
 static sql_rel *
 rel_remove_join(int *changes, mvc *sql, sql_rel *rel)
 {
-       if (is_join(rel->op) && !is_outerjoin(rel->op) && /* DISABLES CODE */ 
(0)) {
+       if (is_join(rel->op) && !is_outerjoin(rel->op)) {
                sql_rel *l = rel->l;
                sql_rel *r = rel->r;
                int lconst = 0, rconst = 0;
@@ -6100,7 +6099,7 @@ rel_remove_join(int *changes, mvc *sql, 
                        list_merge(rel->exps, r->exps, (fdup)NULL);
                }
        }
-       if (is_join(rel->op) && /* DISABLES CODE */ (0)) {
+       if (is_join(rel->op)) {
                sql_rel *l = rel->l;
                sql_rel *r = rel->r;
                int ldict = 0, rdict = 0;
@@ -6137,7 +6136,7 @@ rel_remove_join(int *changes, mvc *sql, 
         * where non of the project_cols are from B and x=y is a foreign key 
join (B is the unique side)
         * and there are no filters on B
         */
-       if (/* DISABLES CODE */ (0) && is_project(rel->op)) {
+       if (is_project(rel->op)) {
                sql_rel *j = rel->l;
 
                if (is_join(j->op)) {
@@ -8354,7 +8353,7 @@ add_nulls(mvc *sql, sql_rel *rel, sql_re
 static sql_rel *
 rel_split_outerjoin(int *changes, mvc *sql, sql_rel *rel)
 {
-       if (/* DISABLES CODE */ (0) && (rel->op == op_left || rel->op == 
op_right || rel->op == op_full) &&
+       if ((rel->op == op_left || rel->op == op_right || rel->op == op_full) &&
            list_length(rel->exps) == 1 && exps_nr_of_or(rel->exps) == 
list_length(rel->exps)) { 
                sql_rel *l = rel->l, *nl, *nll, *nlr;
                sql_rel *r = rel->r, *nr;
@@ -9153,13 +9152,13 @@ optimize_rel(mvc *sql, sql_rel *rel, int
         * also joins between a relation and a DICT (which isn't used)
         * could be removed.
         * */
-       if (gp.cnt[op_join] && gp.cnt[op_project])
+       if (gp.cnt[op_join] && gp.cnt[op_project] && /* DISABLES CODE */ (0))
                rel = rewrite(sql, rel, &rel_remove_join, &changes); 
 
        if (gp.cnt[op_join] || 
-           gp.cnt[op_left] || gp.cnt[op_right] || gp.cnt[op_full] || 
-           gp.cnt[op_semi] || gp.cnt[op_anti] ||
-           gp.cnt[op_select]) {
+               gp.cnt[op_left] || gp.cnt[op_right] || gp.cnt[op_full] || 
+               gp.cnt[op_semi] || gp.cnt[op_anti] ||
+               gp.cnt[op_select]) {
                rel = rewrite(sql, rel, &rel_find_range, &changes);
                if (value_based_opt) {
                        rel = rel_project_reduce_casts(&changes, sql, rel);
@@ -9179,38 +9178,15 @@ optimize_rel(mvc *sql, sql_rel *rel, int
 
        rel = rewrite(sql, rel, &rel_rewrite_types, &changes); 
 
-       if (gp.cnt[op_anti] || gp.cnt[op_semi]) {
-               /* rewrite semijoin (A, join(A,B)) into semijoin (A,B) */
-               rel = rewrite(sql, rel, &rel_rewrite_semijoin, &changes);
-               /* push semijoin through join */
-               rel = rewrite(sql, rel, &rel_push_semijoin_down, &changes);
-               /* antijoin(a, union(b,c)) -> antijoin(antijoin(a,b), c) */
-               rel = rewrite(sql, rel, &rel_rewrite_antijoin, &changes);
-               if (level <= 0)
-                       rel = rewrite_topdown(sql, rel, &rel_semijoin_use_fk, 
&changes);
-       }
-
-       if (gp.cnt[op_left] || gp.cnt[op_right] || gp.cnt[op_full]) 
+       if ((gp.cnt[op_left] || gp.cnt[op_right] || gp.cnt[op_full]) && /* 
DISABLES CODE */ (0)) 
                rel = rewrite_topdown(sql, rel, &rel_split_outerjoin, &changes);
 
        if (gp.cnt[op_select] || gp.cnt[op_project]) 
                if (level == 1) /* only once */
                        rel = rewrite(sql, rel, &rel_merge_rse, &changes); 
 
-       if (gp.cnt[op_select] && gp.cnt[op_join]) {
-               if (/* DISABLES CODE */ (0)) rel = rewrite_topdown(sql, rel, 
&rel_push_select_down_join, &changes); 
-               rel = rewrite(sql, rel, &rel_remove_empty_select, &e_changes); 
-       }
-
-       if (gp.cnt[op_join] && gp.cnt[op_groupby]) {
-               rel = rewrite_topdown(sql, rel, &rel_push_count_down, &changes);
-               if (level <= 0)
-                       rel = rewrite_topdown(sql, rel, &rel_push_join_down, 
&changes); 
-
-               /* push_join_down introduces semijoins */
-               /* rewrite semijoin (A, join(A,B)) into semijoin (A,B) */
-               rel = rewrite(sql, rel, &rel_rewrite_semijoin, &changes);
-       }
+       if (gp.cnt[op_select] && gp.cnt[op_join] && /* DISABLES CODE */ (0))
+               rel = rewrite_topdown(sql, rel, &rel_push_select_down_join, 
&changes); 
 
        if (gp.cnt[op_select])
                rel = rewrite_topdown(sql, rel, &rel_push_select_down_union, 
&changes); 
@@ -9218,6 +9194,9 @@ optimize_rel(mvc *sql, sql_rel *rel, int
        if (gp.cnt[op_union] && gp.cnt[op_select])
                rel = rewrite(sql, rel, &rel_remove_union_partitions, 
&changes); 
 
+       if (gp.cnt[op_select])
+               rel = rewrite(sql, rel, &rel_remove_empty_select, &e_changes); 
+
        if (gp.cnt[op_groupby]) {
                rel = rewrite_topdown(sql, rel, &rel_push_aggr_down, &changes);
                rel = rewrite_topdown(sql, rel, &rel_push_groupby_down, 
&changes);
@@ -9240,6 +9219,28 @@ optimize_rel(mvc *sql, sql_rel *rel, int
                rel = rewrite(sql, rel, &rel_merge_identical_joins, &e_changes);
        }
 
+       /* Important -> Re-write semijoins after rel_join_order */
+       if ((gp.cnt[op_join] || gp.cnt[op_semi] || gp.cnt[op_anti]) && 
gp.cnt[op_groupby]) {
+               rel = rewrite_topdown(sql, rel, &rel_push_count_down, &changes);
+               if (level <= 0)
+                       rel = rewrite_topdown(sql, rel, &rel_push_join_down, 
&changes); 
+
+               /* push_join_down introduces semijoins */
+               /* rewrite semijoin (A, join(A,B)) into semijoin (A,B) */
+               rel = rewrite(sql, rel, &rel_rewrite_semijoin, &changes);
+       }
+
+       if (gp.cnt[op_anti] || gp.cnt[op_semi]) {
+               /* rewrite semijoin (A, join(A,B)) into semijoin (A,B) */
+               rel = rewrite(sql, rel, &rel_rewrite_semijoin, &changes);
+               /* push semijoin through join */
+               rel = rewrite(sql, rel, &rel_push_semijoin_down, &changes);
+               /* antijoin(a, union(b,c)) -> antijoin(antijoin(a,b), c) */
+               rel = rewrite(sql, rel, &rel_rewrite_antijoin, &changes);
+               if (level <= 0)
+                       rel = rewrite_topdown(sql, rel, &rel_semijoin_use_fk, 
&changes);
+       }
+
        /* Important -> Make sure rel_push_select_down gets called after 
rel_join_order,
           because pushing down select expressions makes rel_join_order more 
difficult */
        if (gp.cnt[op_select] || gp.cnt[op_semi]) {
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to