Changeset: 3b8aef1b2a8d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3b8aef1b2a8d
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: mbedded
Log Message:

merged


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

Reply via email to