Changeset: 848a681f010c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/848a681f010c
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_rewriter.c
        sql/server/rel_rewriter.h
Branch: default
Log Message:

There are no aliases on expressions inside joins, so there's no reason to copy 
expressions while trying to push down select expressions


diffs (264 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
@@ -4591,25 +4591,20 @@ rel_push_select_down(visitor *v, sql_rel
                set_processed(jr);
                for (n = exps->h; n;) {
                        node *next = n->next;
-                       sql_exp *e = n->data, *ne = NULL;
-
-                       if (left)
-                               ne = exp_push_down(v->sql, e, jl, jl);
-                       if (ne && ne != e) {
+                       sql_exp *e = n->data;
+
+                       if (left && exp_push_down(v->sql, e, jl)) {
                                if (!is_select(jl->op) || rel_is_ref(jl))
                                        r->l = jl = rel_select(v->sql->sa, jl, 
NULL);
-                               rel_select_add_exp(v->sql->sa, jl, ne);
+                               rel_select_add_exp(v->sql->sa, jl, e);
                                list_remove_node(exps, NULL, n);
                                v->changes++;
-                       } else if (right) {
-                               ne = exp_push_down(v->sql, e, jr, jr);
-                               if (ne && ne != e) {
-                                       if (!is_select(jr->op) || 
rel_is_ref(jr))
-                                               r->r = jr = 
rel_select(v->sql->sa, jr, NULL);
-                                       rel_select_add_exp(v->sql->sa, jr, ne);
-                                       list_remove_node(exps, NULL, n);
-                                       v->changes++;
-                               }
+                       } else if (right && exp_push_down(v->sql, e, jr)) {
+                               if (!is_select(jr->op) || rel_is_ref(jr))
+                                       r->r = jr = rel_select(v->sql->sa, jr, 
NULL);
+                               rel_select_add_exp(v->sql->sa, jr, e);
+                               list_remove_node(exps, NULL, n);
+                               v->changes++;
                        }
                        n = next;
                }
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
@@ -1137,21 +1137,15 @@ rel_select_push_exp_down(mvc *sql, sql_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) {
+               if (left && exp_push_down(sql, e, jl)) {
                        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);
-                       }
+                       r->l = jl = rel_select_add_exp(sql->sa, jl, e);
+               } else if (right && exp_push_down(sql, e, jr)) {
+                       done = 1;
+                       r->r = jr = rel_select_add_exp(sql->sa, jr, e);
                }
        }
        if (!done)
diff --git a/sql/server/rel_rewriter.c b/sql/server/rel_rewriter.c
--- a/sql/server/rel_rewriter.c
+++ b/sql/server/rel_rewriter.c
@@ -207,142 +207,66 @@ rewrite_simplify(visitor *v, sql_rel *re
        return try_remove_empty_select(v, rel);
 }
 
-/* push the expression down, ie translate colum references
-       from relation f into expression of relation t
-*/
+/* push the expression down, ie check if relation r references it */
 
-static sql_exp * _exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t);
+static bool _exp_push_down(mvc *sql, sql_exp *e, sql_rel *r);
 
-static list *
-exps_push_down(mvc *sql, list *exps, sql_rel *f, sql_rel *t)
+static bool
+exps_push_down(mvc *sql, list *exps, sql_rel *r)
 {
        if (list_empty(exps))
-               return exps;
-       for(node *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);
-               n->data = narg;
-       }
-       return exps;
+               return true;
+       for (node *n = exps->h; n; n = n->next)
+               if (!_exp_push_down(sql,  n->data, r))
+                       return false;
+       return true;
 }
 
-static sql_exp *
-_exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t)
+static bool
+_exp_push_down(mvc *sql, sql_exp *e, sql_rel *r)
 {
-       sql_exp *oe = e;
-       sql_exp *ne = NULL, *l, *r, *r2;
+       sql_exp *ne = NULL;
 
        switch(e->type) {
        case e_column:
                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 */
+                       ne = rel_bind_column2(sql, r, e->l, e->r, 0);
+               } else {
+                       ne = rel_bind_column(sql, r, e->r, 0, 1);
                }
-               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_prop_alias(sql->sa, e, ne);
-               return e;
+               if (!ne) {
+                       sql->session->status = 0;
+                       sql->errstr[0] = 0;
+                       return false;
+               }
+               if (ne->type != e_column)
+                       return false;
+               return true;
        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));
+                       return exps_push_down(sql, e->l, r) && 
exps_push_down(sql, e->r, r);
                } 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);
+                       return _exp_push_down(sql, e->l, r) && 
exps_push_down(sql, e->r, r);
                } 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);
-                       }
+                       return _exp_push_down(sql, e->l, r) && 
_exp_push_down(sql, e->r, r) && (!e->f || _exp_push_down(sql, e->f, r));
                }
-               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;
+               return _exp_push_down(sql, e->l, r);
        case e_aggr:
-       case e_func: {
-               list *l = e->l, *nl = NULL;
-
-               if (!list_empty(l)) {
-                       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_func:
+               return exps_push_down(sql, e->l, r);
+       case e_atom:
+               return exps_push_down(sql, e->f, r); /* for atom lists (ie 
e->f) validate the list, otherwise it can be always pushed */
+       case e_psm:
+               return false;
        }
-       case e_atom: {
-               list *l = e->f, *nl = NULL;
-
-               if (!list_empty(l)) {
-                       nl = exps_push_down(sql, l, f, t);
-                       if (!nl)
-                               return NULL;
-                       return exp_values(sql->sa, nl);
-               }
-               return exp_copy(sql, e);
-       }
-       case e_psm:
-               return e;
-       }
-       return NULL;
+       return false;
 }
 
-sql_exp *
-exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t)
+bool
+exp_push_down(mvc *sql, sql_exp *e, sql_rel *r)
 {
-       return _exp_push_down(sql, e, f, t);
+       return _exp_push_down(sql, e, r);
 }
 
 sql_rel *
diff --git a/sql/server/rel_rewriter.h b/sql/server/rel_rewriter.h
--- a/sql/server/rel_rewriter.h
+++ b/sql/server/rel_rewriter.h
@@ -33,7 +33,7 @@ try_remove_empty_select(visitor *v, sql_
        return rel;
 }
 
-extern sql_exp *exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t);
+extern bool exp_push_down(mvc *sql, sql_exp *e, sql_rel *r);
 
 extern sql_rel *rewrite_reset_used(visitor *v, sql_rel *rel);
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to