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