Changeset: e2f6ddd4605c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e2f6ddd4605c
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_select.c
Branch: default
Log Message:

At the moment, filter expressions can be pushed down early only if each side 
contains one expression with multi cardinality


diffs (126 lines):

diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -2618,6 +2618,28 @@ exps_intern(list *exps)
        return 0;
 }
 
+sql_exp *
+exps_find_one_multi_exp(list *exps)
+{
+       sql_exp *l = NULL;
+       int skip = 0;
+
+       /* Find one and only 1 expression with card > CARD_ATOM */
+       if (!list_empty(exps)) {
+               for (node *m = exps->h ; m && !skip ; m = m->next) {
+                       sql_exp *e = m->data;
+
+                       if (e->card > CARD_ATOM) {
+                               skip |= l != NULL;
+                               l = e;
+                       }
+               }
+       }
+       if (skip)
+               l = NULL;
+       return l;
+}
+
 const char *
 compare_func( comp_type t, int anti )
 {
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -187,6 +187,7 @@ extern unsigned int exps_card( list *l )
 extern void exps_fix_card( list *exps, unsigned int card);
 extern void exps_setcard( list *exps, unsigned int card);
 extern int exps_intern(list *exps);
+extern sql_exp *exps_find_one_multi_exp(list *exps);
 
 extern const char *compare_func( comp_type t, int anti );
 extern int is_identity( sql_exp *e, sql_rel *r);
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
@@ -1032,27 +1032,8 @@ order_joins(visitor *v, list *rels, list
                                if (is_theta_exp(e->flag)) {
                                        nr = rel_push_join(v->sql, top->l, 
e->l, e->r, e->f, e, 0);
                                } else if (e->flag == cmp_filter || e->flag == 
cmp_or) {
-                                       sql_exp *l = NULL, *r = NULL;
-                                       int skip = 0;
-
-                                       /* Attempt to push down a filter 
expression if possible */
-                                       for (node *m = ((list*)e->l)->h ; m && 
!skip ; m = m->next) {
-                                               sql_exp *nl = m->data;
-
-                                               if (nl->card > CARD_ATOM) {
-                                                       skip |= l != NULL;
-                                                       l = nl;
-                                               }
-                                       }
-                                       for (node *m = ((list*)e->r)->h ; m && 
!skip ; m = m->next) {
-                                               sql_exp *nr = m->data;
-
-                                               if (nr->card > CARD_ATOM) {
-                                                       skip |= r != NULL;
-                                                       r = nr;
-                                               }
-                                       }
-                                       if (l && r && !skip)
+                                       sql_exp *l = 
exps_find_one_multi_exp(e->l), *r = exps_find_one_multi_exp(e->r);
+                                       if (l && r)
                                                nr = rel_push_join(v->sql, 
top->l, l, r, NULL, e, 0);
                                }
                                if (!nr)
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -1460,7 +1460,7 @@ static sql_rel *
 rel_filter(mvc *sql, sql_rel *rel, list *l, list *r, char *sname, char 
*filter_op, int anti, int ff)
 {
        node *n;
-       sql_exp *e = NULL;
+       sql_exp *e = NULL, *ll, *rr;
        sql_subfunc *f = NULL;
        list *tl = sa_list(sql->sa);
        bool found = false;
@@ -1539,11 +1539,14 @@ rel_filter(mvc *sql, sql_rel *rel, list 
                if (exps_card(l) == exps_card(r) || rel->processed)  /* bin 
compare op */
                        return rel_select(sql->sa, rel, e);
 
-               return push_select_exp(sql, rel, e, l->h->data, ff);
-       } else { /* join */
-               return push_join_exp(sql, rel, e, l->h->data, r->h->data, NULL, 
ff);
-       }
-       return rel;
+               if ((ll = exps_find_one_multi_exp(l)))
+                       return push_select_exp(sql, rel, e, ll, ff);
+       } else if ((ll = exps_find_one_multi_exp(l)) && (rr = 
exps_find_one_multi_exp(r))) { /* join */
+               return push_join_exp(sql, rel, e, ll, rr, NULL, ff);
+       }
+       if (is_outerjoin(rel->op))
+               return rel_select(sql->sa, rel, e);
+       return rel_select_add_exp(sql->sa, rel, e);
 }
 
 static sql_rel *
@@ -2036,10 +2039,13 @@ rel_in_exp(sql_query *query, sql_rel *re
 
                        return push_select_exp(sql, rel, e, ls, f);
                } else { /* join */
-                       sql_exp *rs = rlist ? ((list*)e->r)->h->data : e->r;
-                       return push_join_exp(sql, rel, e, ls, rs, NULL, f);
-               }
-       }
+                       sql_exp *rs = rlist ? exps_find_one_multi_exp(e->r) : 
e->r;
+                       if (rs)
+                               return push_join_exp(sql, rel, e, ls, rs, NULL, 
f);
+               }
+       }
+       if (is_outerjoin(rel->op))
+               return rel_select(sql->sa, rel, e);
        return rel_select_add_exp(sql->sa, rel, e);
 }
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to