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

merged with default


diffs (87 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
@@ -1363,7 +1363,7 @@ can_push_func(sql_exp *e, sql_rel *rel, 
                int mustl = 0, mustr = 0, mustf = 0;
                sql_exp *l = e->l, *r = e->r, *f = e->f;
 
-               if (is_project(rel->op) || e->flag == cmp_or || e->flag == 
cmp_in || e->flag == cmp_notin || e->flag == cmp_filter)
+               if ((is_project(rel->op) && e->f) || e->flag == cmp_or || 
e->flag == cmp_in || e->flag == cmp_notin || e->flag == cmp_filter)
                        return 0;
                return ((l->type == e_column || can_push_func(l, rel, &mustl)) 
&& (*must = mustl)) ||
                                (!f && (r->type == e_column || can_push_func(r, 
rel, &mustr)) && (*must = mustr)) ||
@@ -1398,17 +1398,20 @@ can_push_func(sql_exp *e, sql_rel *rel, 
 }
 
 static int
-exps_can_push_func(list *exps, sql_rel *rel)
-{
-       for(node *n = exps->h; n; n = n->next) {
+exps_can_push_func(list *exps, sql_rel *rel, bool *push_left, bool *push_right)
+{
+       for(node *n = exps->h; n && !*push_left && !*push_right; n = n->next) {
                sql_exp *e = n->data;
-               int must = 0, mustl = 0, mustr = 0;
-
-               if (is_joinop(rel->op) && ((can_push_func(e, rel->l, &mustl) && 
mustl) || (can_push_func(e, rel->r, &mustr) && mustr)))
-                       return 1;
-               else if (is_select(rel->op) && can_push_func(e, rel->l, &must) 
&& must)
-                       return 1;
-       }
+               int mustl = 0, mustr = 0;
+
+               if ((is_joinop(rel->op) || is_select(rel->op)) && 
((can_push_func(e, rel->l, &mustl) && mustl)))
+                       *push_left = true;
+               
+               if (is_joinop(rel->op) && can_push_func(e, rel->r, &mustr) && 
mustr)
+                       *push_right = true;
+       }
+       if (*push_left || *push_right)
+               return 1;
        return 0;
 }
 
@@ -1522,19 +1525,20 @@ rel_push_func_down(visitor *v, sql_rel *
        if ((is_select(rel->op) || is_joinop(rel->op)) && rel->l && rel->exps 
&& !(rel_is_ref(rel))) {
                list *exps = rel->exps;
                sql_rel *l = rel->l, *r = rel->r;
+               bool push_left = false, push_right = false;
 
                /* only push down when is useful */
                if ((is_select(rel->op) && list_length(rel->exps) <= 1) || 
rel_is_ref(l) || (is_joinop(rel->op) && rel_is_ref(r)))
                        return rel;
-               if (exps_can_push_func(exps, rel) && exps_need_push_down(exps)) 
{
+               if (exps_can_push_func(exps, rel, &push_left, &push_right) && 
exps_need_push_down(exps)) {
                        sql_rel *nrel, *ol = l, *or = r;
                        visitor nv = { .sql = v->sql, .parent = v->parent, 
.value_based_opt = v->value_based_opt, .storage_based_opt = 
v->storage_based_opt };
 
                        /* we need a full projection, group by's and unions 
cannot be extended
                         * with more expressions */
-                       if (!is_simple_project(l->op) || !l->l)
+                       if (push_left && (!is_simple_project(l->op) || !l->l))
                                rel->l = l = rel_project(v->sql->sa, l, 
rel_projections(v->sql, l, NULL, 1, 1));
-                       if (is_joinop(rel->op) && (!is_simple_project(r->op) || 
!r->l))
+                       if (push_right && (!is_simple_project(r->op)|| !r->l))
                                rel->r = r = rel_project(v->sql->sa, r, 
rel_projections(v->sql, r, NULL, 1, 1));
                        nrel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
 
@@ -1553,14 +1557,15 @@ rel_push_func_down(visitor *v, sql_rel *
        }
        if (is_simple_project(rel->op) && rel->l && rel->exps) {
                sql_rel *pl = rel->l;
-
-               if (is_joinop(pl->op) && exps_can_push_func(rel->exps, rel)) {
+               bool push_left = false, push_right = false;
+
+               if (is_joinop(pl->op) && exps_can_push_func(rel->exps, rel, 
&push_left, &push_right)) {
                        sql_rel *l = pl->l, *r = pl->r;
                        list *nexps = new_exp_list(v->sql->sa);
 
-                       if (!is_simple_project(l->op) || !l->l)
+                       if (push_left && !is_simple_project(l->op))
                                pl->l = l = rel_project(v->sql->sa, l, 
rel_projections(v->sql, l, NULL, 1, 1));
-                       if (is_joinop(rel->op) && (!is_simple_project(r->op) || 
!r->l))
+                       if (push_right && !is_simple_project(r->op))
                                pl->r = r = rel_project(v->sql->sa, r, 
rel_projections(v->sql, r, NULL, 1, 1));
                        for (node *n = rel->exps->h; n; n = n->next) {
                                sql_exp *e = n->data;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to