Changeset: ac58ee899ed3 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ac58ee899ed3 Modified Files: sql/server/rel_optimizer.c sql/server/rel_outer_join_optimizer.h sql/server/rel_rel.c sql/server/rel_rel.h sql/server/rel_rewriter.c sql/server/rel_rewriter.h sql/server/rel_select.c Branch: default Log Message:
Push select expression as down as possible early on, except when it is behind an 'or' diffs (truncated from 773 to 300 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 @@ -1004,7 +1004,7 @@ order_joins(mvc *sql, list *rels, list * if (exp_is_join_exp(e) == 0) { sql_rel *nr = NULL; if (e->flag == cmp_equal) - nr = rel_push_join(sql, top->l, e->l, e->r, NULL, e); + nr = rel_push_join(sql, top->l, e->l, e->r, NULL, e, 0); if (!nr) rel_join_add_exp(sql->sa, top->l, e); } else @@ -1327,142 +1327,6 @@ exp_rename(mvc *sql, sql_exp *e, sql_rel return exp_propagate(sql->sa, ne, e); } -/* push the expression down, ie translate colum references - from relation f into expression of relation t -*/ - -static sql_exp * _exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t); - -static list * -exps_push_down(mvc *sql, list *exps, sql_rel *f, sql_rel *t) -{ - node *n; - list *nl = new_exp_list(sql->sa); - - for(n = exps->h; n; n = n->next) { - sql_exp *arg = n->data, *narg = NULL; - - narg = _exp_push_down(sql, arg, f, t); - if (!narg) - return NULL; - narg = exp_propagate(sql->sa, narg, arg); - append(nl, narg); - } - return nl; -} - -static sql_exp * -_exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t) -{ - sql_exp *oe = e; - sql_exp *ne = NULL, *l, *r, *r2; - - switch(e->type) { - case e_column: - if (is_union(f->op)) { - int p = list_position(f->exps, rel_find_exp(f, e)); - - return list_fetch(t->exps, p); - } - if (e->l) { - ne = rel_bind_column2(sql, f, e->l, e->r, 0); - /* if relation name matches expressions relation name, find column based on column name alone */ - } - if (!ne && !e->l) - ne = rel_bind_column(sql, f, e->r, 0, 1); - if (!ne || ne->type != e_column) - return NULL; - e = NULL; - if (ne->l && ne->r) - e = rel_bind_column2(sql, t, ne->l, ne->r, 0); - if (!e && ne->r && !ne->l) - e = rel_bind_column(sql, t, ne->r, 0, 1); - sql->session->status = 0; - sql->errstr[0] = 0; - if (e && oe) - e = exp_propagate(sql->sa, e, oe); - /* if the upper exp was an alias, keep this */ - if (e && exp_relname(ne)) - exp_setname(sql->sa, e, exp_relname(ne), exp_name(ne)); - return e; - case e_cmp: - if (e->flag == cmp_or || e->flag == cmp_filter) { - list *l, *r; - - l = exps_push_down(sql, e->l, f, t); - if (!l) - return NULL; - r = exps_push_down(sql, e->r, f, t); - if (!r) - return NULL; - if (e->flag == cmp_filter) - return exp_filter(sql->sa, l, r, e->f, is_anti(e)); - return exp_or(sql->sa, l, r, is_anti(e)); - } else if (e->flag == cmp_in || e->flag == cmp_notin) { - list *r; - - l = _exp_push_down(sql, e->l, f, t); - if (!l) - return NULL; - r = exps_push_down(sql, e->r, f, t); - if (!r) - return NULL; - return exp_in(sql->sa, l, r, e->flag); - } else { - l = _exp_push_down(sql, e->l, f, t); - if (!l) - return NULL; - r = _exp_push_down(sql, e->r, f, t); - if (!r) - return NULL; - if (e->f) { - r2 = _exp_push_down(sql, e->f, f, t); - if (l && r && r2) - ne = exp_compare2(sql->sa, l, r, r2, e->flag); - } else if (l && r) { - if (l->card < r->card) - ne = exp_compare(sql->sa, r, l, swap_compare((comp_type)e->flag)); - else - ne = exp_compare(sql->sa, l, r, e->flag); - } - } - if (!ne) - return NULL; - return exp_propagate(sql->sa, ne, e); - case e_convert: - l = _exp_push_down(sql, e->l, f, t); - if (l) - return exp_convert(sql->sa, l, exp_fromtype(e), exp_totype(e)); - return NULL; - case e_aggr: - case e_func: { - list *l = e->l, *nl = NULL; - - if (!l) { - return e; - } else { - nl = exps_push_down(sql, l, f, t); - if (!nl) - return NULL; - } - if (e->type == e_func) - return exp_op(sql->sa, nl, e->f); - else - return exp_aggr(sql->sa, nl, e->f, need_distinct(e), need_no_nil(e), e->card, has_nil(e)); - } - case e_atom: - case e_psm: - return e; - } - return NULL; -} - -static sql_exp * -exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t) -{ - return _exp_push_down(sql, e, f, t); -} - static int math_unsafe(sql_subfunc *f) { @@ -4712,9 +4576,9 @@ rel_push_select_down_join(mvc *sql, sql_ re->card = ne->card; if (re->card >= CARD_AGGR) { - nr = rel_push_join(sql, r, e->l, re, NULL, e); + nr = rel_push_join(sql, r, e->l, re, NULL, e, 0); } else { - nr = rel_push_select(sql, r, e->l, e); + nr = rel_push_select(sql, r, e->l, e, 0); } if (nr) rel->l = nr; diff --git a/sql/server/rel_outer_join_optimizer.h b/sql/server/rel_outer_join_optimizer.h --- a/sql/server/rel_outer_join_optimizer.h +++ b/sql/server/rel_outer_join_optimizer.h @@ -46,9 +46,9 @@ rel_outer2inner_join(mvc *sql, sql_rel * re->card = ne->card; if (re->card >= CARD_AGGR) { - nr = rel_push_join(sql, r, e->l, re, NULL, e); + nr = rel_push_join(sql, r, e->l, re, NULL, e, 0); } else { - nr = rel_push_select(sql, r, e->l, e); + nr = rel_push_select(sql, r, e->l, e, 0); } if (nr) rel->l = nr; diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c --- a/sql/server/rel_rel.c +++ b/sql/server/rel_rel.c @@ -14,7 +14,7 @@ #include "rel_unnest.h" #include "sql_semantic.h" #include "sql_mvc.h" - +#include "rel_rewriter.h" void rel_set_exps(sql_rel *rel, list *exps) @@ -1240,17 +1240,46 @@ rel_bind_path(mvc *sql, sql_rel *rel, sq return path; } +static sql_rel * +rel_select_push_exp_down(mvc *sql, sql_rel *rel, sql_exp *e) +{ + sql_rel *r = rel->l, *jl = r->l, *jr = r->r; + int left = r->op == op_join || r->op == op_left; + int right = r->op == op_join || r->op == op_right; + int done = 0; + sql_exp *ne = NULL; + + assert(is_select(rel->op)); + if (!is_full(r->op) && !is_single(r)) { + if (left) + ne = exp_push_down(sql, e, jl, jl); + if (ne && ne != e) { + done = 1; + r->l = jl = rel_select_add_exp(sql->sa, jl, ne); + } else if (right) { + ne = exp_push_down(sql, e, jr, jr); + if (ne && ne != e) { + done = 1; + r->r = jr = rel_select_add_exp(sql->sa, jr, ne); + } + } + } + if (!done) + rel_select_add_exp(sql->sa, rel, e); + return rel; +} + /* ls is the left expression of the select, rs is a simple atom, e is the select expression. */ sql_rel * -rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e) +rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e, int f) { list *l = rel_bind_path(sql, rel, ls); node *n; sql_rel *lrel = NULL, *p = NULL; - if (!l || !sql->pushdown) { + if (!l || !sql->pushdown || is_sql_or(f)) { /* expression has no clear parent relation, so filter current with it */ return rel_select(sql->sa, rel, e); @@ -1276,7 +1305,7 @@ rel_push_select(mvc *sql, sql_rel *rel, if (!lrel) return NULL; if (p && is_select(p->op) && !rel_is_ref(p)) { /* refine old select */ - rel_select_add_exp(sql->sa, p, e); + p = rel_select_push_exp_down(sql, p, e); } else { sql_rel *n = rel_select(sql->sa, lrel, e); @@ -1300,7 +1329,7 @@ rel_push_select(mvc *sql, sql_rel *rel, join expression. */ sql_rel * -rel_push_join(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, sql_exp *rs2, sql_exp *e) +rel_push_join(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, sql_exp *rs2, sql_exp *e, int f) { list *l = rel_bind_path(sql, rel, ls); list *r = rel_bind_path(sql, rel, rs); @@ -1313,8 +1342,8 @@ rel_push_join(mvc *sql, sql_rel *rel, sq if (!l || !r || (rs2 && !r2)) return NULL; - if (!sql->pushdown) - return rel_push_select(sql, rel, ls, e); + if (!sql->pushdown || is_sql_or(f)) + return rel_push_select(sql, rel, ls, e, f); p = rel; if (r2) { @@ -1371,9 +1400,9 @@ rel_push_join(mvc *sql, sql_rel *rel, sq /* filter on columns of this relation */ if ((lrel == rrel && (!r2 || lrel == rrel2) && lrel->op != op_join) || rel_is_ref(p)) { if (is_select(lrel->op) && !rel_is_ref(lrel)) { - rel_select_add_exp(sql->sa, lrel, e); + lrel = rel_select_push_exp_down(sql, lrel, e); } else if (p && is_select(p->op) && !rel_is_ref(p)) { - rel_select_add_exp(sql->sa, p, e); + p = rel_select_push_exp_down(sql, p, e); } else { sql_rel *n = rel_select(sql->sa, lrel, e); diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h --- a/sql/server/rel_rel.h +++ b/sql/server/rel_rel.h @@ -30,6 +30,7 @@ #define sql_values (1 << 14) //ORed #define psm_call (1 << 15) //ORed #define sql_merge (1 << 16) //ORed +#define sql_or (1 << 17) //ORed #define is_sql_from(X) ((X & sql_from) == sql_from) #define is_sql_where(X) ((X & sql_where) == sql_where) @@ -48,6 +49,7 @@ #define is_sql_values(X) ((X & sql_values) == sql_values) #define is_psm_call(X) ((X & psm_call) == psm_call) #define is_sql_merge(X) ((X & sql_merge) == sql_merge) +#define is_sql_or(X) ((X & sql_or) == sql_or) _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list