Changeset: b5f6b702d95f for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/b5f6b702d95f Modified Files: sql/server/rel_select.c Branch: Jul2021 Log Message:
Attempt to push down between expressions earlier. This is needed for updates with single join cases. Small cleanup diffs (155 lines): 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 @@ -1461,7 +1461,7 @@ 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)! */ +push_select_exp(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, int f) { if (is_outerjoin(rel->op)) { if ((is_left(rel->op) || is_full(rel->op)) && rel_find_exp(rel->l, ls)) { @@ -1472,15 +1472,15 @@ push_select_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, rel->r, L, e, f); + 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, L, e, f); + 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, L, e, f); + return rel_push_select(sql, rel, ls, e, f); } static sql_rel * @@ -1502,7 +1502,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 *L = l->h->data, *R = r->h->data, *e = NULL; + sql_exp *e = NULL; sql_subfunc *f = NULL; list *tl = sa_list(sql->sa); bool found = false; @@ -1577,9 +1577,9 @@ 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, L, ff); + return push_select_exp(sql, rel, e, l->h->data, ff); } else { /* join */ - return push_join_exp(sql, rel, e, L, R, NULL, ff); + return push_join_exp(sql, rel, e, l->h->data, r->h->data, NULL, ff); } return rel; } @@ -1600,19 +1600,26 @@ rel_filter_exp_(mvc *sql, sql_rel *rel, } static sql_rel * -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) +rel_select_push_exp_down(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, sql_exp *rs, sql_exp *rs2, int f) { if (!is_join(rel->op) && !is_select(rel->op)) return rel_select(sql->sa, rel, e); if ((rs->card <= CARD_ATOM || (rs2 && ls->card <= CARD_ATOM)) && (exp_is_atom(rs) || (rs2 && exp_is_atom(ls)) || 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 && (ls->card == rs2->card || rs->card == rs2->card)) || rel->processed) /* bin compare op */ + int ls_is_col = ls->card > CARD_ATOM ? 1 : 0; + int rs_is_col = rs->card > CARD_ATOM ? 1 : 0; + int rs2_is_col = rs2 && rs2->card > CARD_ATOM ? 1 : 0; + int ncols = ls_is_col + rs_is_col + rs2_is_col; + + /* later on we could improve this to pushdown more between cases */ + if (rel->processed || ncols > 1 || exp_has_freevar(sql, rs) || exp_has_freevar(sql, ls) || (rs2 && exp_has_freevar(sql, rs2))) /* bin compare op */ return rel_select(sql->sa, rel, e); - return push_select_exp(sql, rel, e, ls, L, f); + sql_exp *col_exp = ls_is_col || !ncols ? ls : rs_is_col ? rs : rs2; + return push_select_exp(sql, rel, e, col_exp, f); } else { /* join */ - return push_join_exp(sql, rel, e, L, R, rs2, f); + return push_join_exp(sql, rel, e, ls, rs, rs2, f); } return rel; } @@ -1676,7 +1683,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_select_push_exp_down(sql, rel, e, ls, ls, rs, rs, rs2, f); + return rel_select_push_exp_down(sql, rel, e, ls, rs, rs2, f); } static sql_rel * @@ -2081,7 +2088,7 @@ rel_in_exp(sql_query *query, sql_rel *re if ((exp_card(ls) == rcard) || rel->processed) /* bin compare op */ return rel_select(sql->sa, rel, e); - return push_select_exp(sql, rel, e, ls, ls, f); + 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); @@ -2683,7 +2690,7 @@ rel_logical_exp(sql_query *query, sql_re set_anti(le); set_has_no_nil(le); set_semantics(le); - return rel_select_push_exp_down(sql, rel, le, le->l, le->l, le->r, le->r, NULL, f); + return rel_select_push_exp_down(sql, rel, le, le->l, le->r, NULL, f); } case SQL_NOT: { if (not_symbol_can_be_propagated(sql, sc->data.sym)) { @@ -2697,7 +2704,7 @@ rel_logical_exp(sql_query *query, sql_re if (!le || !(le = exp_check_type(sql, &bt, rel, le, type_equal))) return NULL; le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 0), cmp_equal); - return rel_select_push_exp_down(sql, rel, le, le->l, le->l, le->r, le->r, NULL, f); + return rel_select_push_exp_down(sql, rel, le, le->l, le->r, NULL, f); } case SQL_ATOM: { /* TRUE or FALSE */ @@ -2714,7 +2721,7 @@ rel_logical_exp(sql_query *query, sql_re if (!e || or != rel) return NULL; e = exp_compare(sql->sa, e, exp_atom_bool(sql->sa, 1), cmp_equal); - return rel_select_push_exp_down(sql, rel, e, e, e, e, e, NULL, f); + return rel_select_push_exp_down(sql, rel, e, e->l, e->r, NULL, f); } case SQL_IDENT: case SQL_COLUMN: { @@ -2730,7 +2737,7 @@ rel_logical_exp(sql_query *query, sql_re if (!e || or != rel) return NULL; e = exp_compare(sql->sa, e, exp_atom_bool(sql->sa, 1), cmp_equal); - return rel_select_push_exp_down(sql, rel, e, e, e, e, e, NULL, f); + return rel_select_push_exp_down(sql, rel, e, e->l, e->r, NULL, f); } case SQL_UNION: case SQL_EXCEPT: @@ -2760,7 +2767,7 @@ rel_logical_exp(sql_query *query, sql_re if (!le) return NULL; le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 1), cmp_equal); - return rel_select_push_exp_down(sql, rel, le, le->l, le->l, le->r, le->r, NULL, f); + return rel_select_push_exp_down(sql, rel, le, le->l, le->r, NULL, f); } else { sq = rel_crossproduct(sql->sa, rel, sq, (f==sql_sel || sq->single)?op_left:op_join); } @@ -2778,7 +2785,7 @@ rel_logical_exp(sql_query *query, sql_re if (!(le = exp_check_type(sql, &bt, rel, le, type_equal))) return NULL; le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 1), cmp_equal); - return rel_select_push_exp_down(sql, rel, le, le->l, le->l, le->r, le->r, NULL, f); + return rel_select_push_exp_down(sql, rel, le, le->l, le->r, NULL, f); } } /* never reached, as all switch cases have a `return` */ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list