Changeset: e1be56d42ba5 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e1be56d42ba5 Modified Files: sql/server/rel_optimizer.c sql/server/rel_select.c sql/server/rel_select.h sql/server/sql_mvc.c sql/server/sql_mvc.h Branch: default Log Message:
Merge with Jan2014 branch. diffs (216 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 @@ -3098,9 +3098,9 @@ rel_push_select_down_join(int *changes, sql_exp *re = e->r; if (re->card >= CARD_AGGR) { - rel->l = rel_push_join(sql->sa, r, e->l, re, NULL, e); + rel->l = rel_push_join(sql, r, e->l, re, NULL, e); } else { - rel->l = rel_push_select(sql->sa, r, e->l, e); + rel->l = rel_push_select(sql, r, e->l, e); } /* only pushed down selects are counted */ if (r == rel->l) { 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 @@ -1006,16 +1006,16 @@ static char * rel_get_name( sql_rel *rel select expression. */ sql_rel * -rel_push_select(sql_allocator *sa, sql_rel *rel, sql_exp *ls, sql_exp *e) +rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e) { - list *l = rel_bind_path(sa, rel, ls); + list *l = rel_bind_path(sql->sa, rel, ls); node *n; sql_rel *lrel = NULL, *p = NULL; - if (!l) { + if (!l || !sql->pushdown) { /* expression has no clear parent relation, so filter current with it */ - return rel_select(sa, rel, e); + return rel_select(sql->sa, rel, e); } for (n = l->h; n; n = n->next ) { @@ -1039,9 +1039,9 @@ rel_push_select(sql_allocator *sa, sql_r if (!lrel) return NULL; if (p && p->op == op_select && !rel_is_ref(p)) { /* refine old select */ - rel_select_add_exp(sa, p, e); + rel_select_add_exp(sql->sa, p, e); } else { - sql_rel *n = rel_select(sa, lrel, e); + sql_rel *n = rel_select(sql->sa, lrel, e); if (p && p != lrel) { assert(p->op == op_join || p->op == op_left || is_semi(p->op)); @@ -1067,19 +1067,22 @@ rel_push_select(sql_allocator *sa, sql_r join expression. */ sql_rel * -rel_push_join(sql_allocator *sa, 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) { - list *l = rel_bind_path(sa, rel, ls); - list *r = rel_bind_path(sa, rel, rs); + list *l = rel_bind_path(sql->sa, rel, ls); + list *r = rel_bind_path(sql->sa, rel, rs); list *r2 = NULL; node *ln, *rn; sql_rel *lrel = NULL, *rrel = NULL, *rrel2 = NULL, *p = NULL; if (rs2) - r2 = rel_bind_path(sa, rel, rs2); + r2 = rel_bind_path(sql->sa, rel, rs2); if (!l || !r || (rs2 && !r2)) return NULL; + if (!sql->pushdown) + return rel_push_select(sql, rel, ls, e); + p = rel; if (r2) { node *rn2; @@ -1135,11 +1138,11 @@ rel_push_join(sql_allocator *sa, sql_rel /* filter on columns of this relation */ if ((lrel == rrel && (!r2 || lrel == rrel2) && lrel->op != op_join) || rel_is_ref(p)) { if (lrel->op == op_select && !rel_is_ref(lrel)) { - rel_select_add_exp(sa, lrel, e); + rel_select_add_exp(sql->sa, lrel, e); } else if (p && p->op == op_select && !rel_is_ref(p)) { - rel_select_add_exp(sa, p, e); + rel_select_add_exp(sql->sa, p, e); } else { - sql_rel *n = rel_select(sa, lrel, e); + sql_rel *n = rel_select(sql->sa, lrel, e); if (p && p != lrel) { if (p->l == lrel) @@ -1153,7 +1156,7 @@ rel_push_join(sql_allocator *sa, sql_rel return rel; } - rel_join_add_exp( sa, p, e); + rel_join_add_exp( sql->sa, p, e); return rel; } @@ -2188,14 +2191,14 @@ rel_filter_exp_(mvc *sql, sql_rel *rel, return rel; } /* push select into the given relation */ - return rel_push_select(sql->sa, rel, L, e); + return rel_push_select(sql, rel, L, e); } else { /* join */ if (is_semi(rel->op) || is_outerjoin(rel->op)) { rel_join_add_exp(sql->sa, rel, e); return rel; } /* push join into the given relation */ - return rel_push_join(sql->sa, rel, L, R, rs2, e); + return rel_push_join(sql, rel, L, R, rs2, e); } } @@ -2254,22 +2257,22 @@ rel_compare_exp_(mvc *sql, sql_rel *rel, return rel; } if (is_left(rel->op) && rel_find_exp(rel->r, ls)) { - rel->r = rel_push_select(sql->sa, rel->r, L, e); + rel->r = rel_push_select(sql, rel->r, L, e); return rel; } else if (is_right(rel->op) && rel_find_exp(rel->l, ls)) { - rel->l = rel_push_select(sql->sa, rel->l, L, e); + rel->l = rel_push_select(sql, rel->l, L, e); return rel; } } /* push select into the given relation */ - return rel_push_select(sql->sa, rel, L, e); + return rel_push_select(sql, rel, L, e); } else { /* join */ if (is_semi(rel->op) || is_outerjoin(rel->op)) { rel_join_add_exp(sql->sa, rel, e); return rel; } /* push join into the given relation */ - return rel_push_join(sql->sa, rel, L, R, rs2, e); + return rel_push_join(sql, rel, L, R, rs2, e); } } @@ -2820,15 +2823,21 @@ rel_logical_exp(mvc *sql, sql_rel *rel, rr = rel_dup(lr); if (is_outerjoin(rel->op)) { + int pushdown = sql->pushdown; + exps = rel->exps; - - lr -> exps = NULL; + sql->pushdown = 0; + + lr = rel_select_copy(sql->sa, lr, sa_list(sql->sa)); lr = rel_logical_exp(sql, lr, lo, f); lexps = lr?lr->exps:NULL; - - rr -> exps = NULL; + lr = lr->l; + + rr = rel_select_copy(sql->sa, rr, sa_list(sql->sa)); rr = rel_logical_exp(sql, rr, ro, f); rexps = rr?rr->exps:NULL; + rr = rr->l; + sql->pushdown = pushdown; } else { lr = rel_logical_exp(sql, lr, lo, f); rr = rel_logical_exp(sql, rr, ro, f); diff --git a/sql/server/rel_select.h b/sql/server/rel_select.h --- a/sql/server/rel_select.h +++ b/sql/server/rel_select.h @@ -58,8 +58,8 @@ extern sql_exp * rel_value_exp2(mvc *sql extern sql_rel *rel_crossproduct(sql_allocator *sa, sql_rel *l, sql_rel *r, operator_type join); extern void rel_join_add_exp(sql_allocator *sa, sql_rel *rel, sql_exp *e); -extern sql_rel *rel_push_select(sql_allocator *sa, sql_rel *rel, sql_exp *ls, sql_exp *e); -extern sql_rel *rel_push_join(sql_allocator *sa, sql_rel *rel, sql_exp *ls, sql_exp *rs, sql_exp *rs2, sql_exp *e); +extern sql_rel *rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e); +extern sql_rel *rel_push_join(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, sql_exp *rs2, sql_exp *e); /* TODO rename to exp_check_type + move to rel_exp.mx */ extern sql_exp *rel_check_type(mvc *sql, sql_subtype *t, sql_exp *exp, int tpe); extern int rel_convert_types(mvc *sql, sql_exp **L, sql_exp **R, int scale_fixing, int tpe); diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c --- a/sql/server/sql_mvc.c +++ b/sql/server/sql_mvc.c @@ -440,6 +440,7 @@ mvc_create(int clientid, backend_stack s store_unlock(); m->type = Q_PARSE; + m->pushdown = 1; m->result_id = 0; m->results = NULL; @@ -504,6 +505,7 @@ mvc_reset(mvc *m, bstream *rs, stream *w m->label = 0; m->cascade_action = NULL; m->type = Q_PARSE; + m->pushdown = 1; for(i=0;i<MAXSTATS;i++) m->opt_stats[i] = 0; diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h --- a/sql/server/sql_mvc.h +++ b/sql/server/sql_mvc.h @@ -118,6 +118,7 @@ typedef struct mvc { sql_session *session; int type; /* query type */ + int pushdown; /* AND or OR query handling */ int label; /* numbers for relational projection labels */ list *cascade_action; /* protection against recursive cascade actions */ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list