Changeset: f40f3ab03237 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f40f3ab03237 Modified Files: sql/server/rel_rel.c sql/server/rel_select.c sql/server/sql_mvc.c sql/server/sql_mvc.h Branch: mbedded Log Message:
merged diffs (truncated from 387 to 300 lines): 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 @@ -1218,15 +1218,14 @@ rel_bind_path_(mvc *sql, sql_rel *rel, s } static list * -rel_bind_path(mvc *sql, sql_rel *rel, sql_exp *e) +rel_bind_path(mvc *sql, sql_rel *rel, sql_exp *e, list *path) { - list *path = sa_list(sql->sa); if (!path) return NULL; if (e->type == e_convert) - e = e->l; - if (e->type == e_column) { + path = rel_bind_path(sql, rel, e->l, path); + else if (e->type == e_column) { if (rel) { if (!rel_bind_path_(sql, rel, e, path)) { /* something is wrong */ @@ -1275,15 +1274,14 @@ rel_select_push_exp_down(mvc *sql, sql_r sql_rel * rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e, int f) { - list *l = rel_bind_path(sql, rel, ls); + list *l = rel_bind_path(sql, rel, ls, sa_list(sql->sa)); node *n; sql_rel *lrel = NULL, *p = NULL; - if (!l || !sql->pushdown || is_sql_or(f)) { - /* expression has no clear parent relation, so filter current - with it */ + if (!l) + return NULL; + if (is_sql_or(f)) /* expression has no clear parent relation, so filter current with it */ return rel_select(sql->sa, rel, e); - } for (n = l->h; n; n = n->next ) { lrel = n->data; @@ -1331,18 +1329,18 @@ rel_push_select(mvc *sql, sql_rel *rel, sql_rel * 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); + list *l = rel_bind_path(sql, rel, ls, sa_list(sql->sa)); + list *r = rel_bind_path(sql, rel, rs, sa_list(sql->sa)); list *r2 = NULL; node *ln, *rn; sql_rel *lrel = NULL, *rrel = NULL, *rrel2 = NULL, *p = NULL; if (rs2) - r2 = rel_bind_path(sql, rel, rs2); + r2 = rel_bind_path(sql, rel, rs2, sa_list(sql->sa)); if (!l || !r || (rs2 && !r2)) return NULL; - if (!sql->pushdown || is_sql_or(f)) + if (is_sql_or(f)) return rel_push_select(sql, rel, ls, e, f); p = rel; 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 @@ -1575,6 +1575,29 @@ rel_convert_types(mvc *sql, sql_rel *ll, } static sql_rel * +push_select_exp(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, sql_exp *L, int f) /* 'e' is an expression where the right is a constant(s)! */ +{ + if (is_outerjoin(rel->op)) { + if ((is_left(rel->op) || is_full(rel->op)) && rel_find_exp(rel->l, ls)) { + rel_join_add_exp(sql->sa, rel, e); + return rel; + } else if ((is_right(rel->op) || is_full(rel->op)) && rel_find_exp(rel->r, ls)) { + rel_join_add_exp(sql->sa, rel, e); + return rel; + } + if (is_left(rel->op) && rel_find_exp(rel->r, ls)) { + rel->r = rel_push_select(sql, rel->r, L, e, f); + return rel; + } else if (is_right(rel->op) && rel_find_exp(rel->l, ls)) { + rel->l = rel_push_select(sql, rel->l, L, e, f); + return rel; + } + } + /* push select into the given relation */ + return rel_push_select(sql, rel, L, e, f); +} + +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; @@ -1653,24 +1676,7 @@ 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); - if (/*is_semi(rel->op) ||*/ is_outerjoin(rel->op)) { - if ((is_left(rel->op) || is_full(rel->op)) && rel_find_exp(rel->l, l->h->data)) { - rel_join_add_exp(sql->sa, rel, e); - return rel; - } else if ((is_right(rel->op) || is_full(rel->op)) && rel_find_exp(rel->r, l->h->data)) { - rel_join_add_exp(sql->sa, rel, e); - return rel; - } - if (is_left(rel->op) && rel_find_exp(rel->r, l->h->data)) { - rel->r = rel_push_select(sql, rel->r, L, e, ff); - return rel; - } else if (is_right(rel->op) && rel_find_exp(rel->l, l->h->data)) { - rel->l = rel_push_select(sql, rel->l, L, e, ff); - return rel; - } - } - /* push select into the given relation */ - return rel_push_select(sql, rel, L, e, ff); + return push_select_exp(sql, rel, e, l->h->data, L, ff); } else { /* join */ sql_rel *r; if (/*is_semi(rel->op) ||*/ (is_outerjoin(rel->op) && !is_processed((rel)))) { @@ -1699,31 +1705,14 @@ rel_filter_exp_(mvc *sql, sql_rel *rel, } static sql_rel * -rel_compare_push_exp(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, sql_exp *L, sql_exp *rs, sql_exp *R, sql_exp *rs2, int f) +rel_select_push_exp_down(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, sql_exp *L, sql_exp *rs, sql_exp *R, sql_exp *rs2, int f) { if (rs->card <= CARD_ATOM && (exp_is_atom(rs) || exp_has_freevar(sql, rs) || exp_has_freevar(sql, ls)) && (!rs2 || (rs2->card <= CARD_ATOM && (exp_is_atom(rs2) || exp_has_freevar(sql, rs2))))) { if ((ls->card == rs->card && !rs2) || rel->processed) /* bin compare op */ return rel_select(sql->sa, rel, e); - if (/*is_semi(rel->op) ||*/ is_outerjoin(rel->op)) { - if ((is_left(rel->op) || is_full(rel->op)) && rel_find_exp(rel->l, ls)) { - rel_join_add_exp(sql->sa, rel, e); - return rel; - } else if ((is_right(rel->op) || is_full(rel->op)) && rel_find_exp(rel->r, ls)) { - rel_join_add_exp(sql->sa, rel, e); - return rel; - } - if (is_left(rel->op) && rel_find_exp(rel->r, ls)) { - rel->r = rel_push_select(sql, rel->r, L, e, f); - return rel; - } else if (is_right(rel->op) && rel_find_exp(rel->l, ls)) { - rel->l = rel_push_select(sql, rel->l, L, e, f); - return rel; - } - } - /* push select into the given relation */ - return rel_push_select(sql, rel, L, e, f); + return push_select_exp(sql, rel, e, ls, L, f); } else { /* join */ sql_rel *r; if (/*is_semi(rel->op) ||*/ (is_outerjoin(rel->op) && !is_processed((rel)))) { @@ -1799,7 +1788,7 @@ rel_compare_exp_(sql_query *query, sql_r else return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function"); } - return rel_compare_push_exp(sql, rel, e, ls, L, rs, R, rs2, f); + return rel_select_push_exp_down(sql, rel, e, ls, L, rs, R, rs2, f); } static sql_rel * @@ -2171,29 +2160,6 @@ rel_in_value_exp(sql_query *query, sql_r } static sql_rel * -push_select_exp(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, int f) /* 'e' is an expression where the right is a constant(s)! */ -{ - if (is_outerjoin(rel->op)) { - if ((is_left(rel->op) || is_full(rel->op)) && rel_find_exp(rel->l, ls)) { - rel_join_add_exp(sql->sa, rel, e); - return rel; - } else if ((is_right(rel->op) || is_full(rel->op)) && rel_find_exp(rel->r, ls)) { - rel_join_add_exp(sql->sa, rel, e); - return rel; - } - if (is_left(rel->op) && rel_find_exp(rel->r, ls)) { - rel->r = rel_push_select(sql, rel->r, ls, e, f); - return rel; - } else if (is_right(rel->op) && rel_find_exp(rel->l, ls)) { - rel->l = rel_push_select(sql, rel->l, ls, e, f); - return rel; - } - } - /* push select into the given relation */ - return rel_push_select(sql, rel, ls, e, f); -} - -static sql_rel * rel_in_exp(sql_query *query, sql_rel *rel, symbol *sc, int f) { mvc *sql = query->sql; @@ -2204,7 +2170,7 @@ rel_in_exp(sql_query *query, sql_rel *re return NULL; if (e->type == e_cmp) /* it's a exp_in or cmp_equal of constants, push down early on if possible */ - return push_select_exp(sql, rel, e, e->l, f); + return rel_select_push_exp_down(sql, rel, e, e->l, e->l, e->r, e->r, NULL, f); return rel_select_add_exp(sql->sa, rel, e); } @@ -2531,10 +2497,8 @@ rel_logical_exp(sql_query *query, sql_re case SQL_OR: { list *exps = NULL, *lexps = NULL, *rexps = NULL; - symbol *lo = sc->data.lval->h->data.sym; symbol *ro = sc->data.lval->h->next->data.sym; - sql_rel *lr, *rr; if (!rel) @@ -2544,23 +2508,16 @@ rel_logical_exp(sql_query *query, sql_re rr = rel_dup(lr); if (is_outerjoin(rel->op) && !is_processed(rel)) { - int pushdown = sql->pushdown; - exps = rel->exps; - sql->pushdown = 0; lr = rel_select_copy(sql->sa, lr, sa_list(sql->sa)); lr = rel_logical_exp(query, lr, lo, f | sql_or); - if (!lr) { - sql->pushdown = pushdown; + if (!lr) return NULL; - } rr = rel_select_copy(sql->sa, rr, sa_list(sql->sa)); rr = rel_logical_exp(query, rr, ro, f | sql_or); - if (!rr) { - sql->pushdown = pushdown; + if (!rr) return NULL; - } if (lr->l == rr->l) { lexps = lr->exps; lr = lr->l; @@ -2568,7 +2525,6 @@ rel_logical_exp(sql_query *query, sql_re rr = rr->l; } rel = NULL; - sql->pushdown = pushdown; } else { lr = rel_logical_exp(query, lr, lo, f | sql_or); if (!lr) @@ -2753,7 +2709,7 @@ rel_logical_exp(sql_query *query, sql_re if (!e1) return NULL; e2 = exp_compare(sql->sa, e1, exp_atom_bool(sql->sa, 1), cmp_equal); - return rel_compare_push_exp(sql, rel, e2, le, le, re1, re1, re2, f); + return rel_select_push_exp_down(sql, rel, e2, le, le, re1, re1, re2, f); } else if (sc->token == SQL_NOT_BETWEEN) { rel = rel_compare_exp_(query, rel, le, re1, re2, 3|CMP_BETWEEN|flag, 1, 0, f); } else { @@ -2765,7 +2721,7 @@ rel_logical_exp(sql_query *query, sql_re case SQL_IS_NOT_NULL: /* is (NOT) NULL */ { - sql_exp *le = rel_value_exp(query, &rel, sc->data.sym, f, ek), *ls = le; + sql_exp *le = rel_value_exp(query, &rel, sc->data.sym, f, ek); if (!le) return NULL; @@ -2773,10 +2729,10 @@ rel_logical_exp(sql_query *query, sql_re return NULL; set_has_no_nil(le); le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, (sc->token == SQL_IS_NULL) ? 1 : 0), cmp_equal); - return push_select_exp(sql, rel, le, ls, f); + return rel_select_push_exp_down(sql, rel, le, le->l, le->l, le->r, le->r, NULL, f); } case SQL_NOT: { - sql_exp *le, *ls; + sql_exp *le; switch (sc->data.sym->token) { case SQL_IN: sc->data.sym->token = SQL_NOT_IN; @@ -2787,25 +2743,25 @@ rel_logical_exp(sql_query *query, sql_re default: break; } - ls = le = rel_value_exp(query, &rel, sc->data.sym, f|sql_farg, ek); + le = rel_value_exp(query, &rel, sc->data.sym, f|sql_farg, ek); if (!le) return NULL; if (!(le = rel_unop_(sql, rel, le, NULL, "not", card_value))) return NULL; le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 1), cmp_equal); - return push_select_exp(sql, rel, le, ls, f); + return rel_select_push_exp_down(sql, rel, le, le->l, le->l, le->r, le->r, NULL, f); } case SQL_ATOM: { /* TRUE or FALSE */ AtomNode *an = (AtomNode *) sc; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list