Changeset: 0a0f39f9b516 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/0a0f39f9b516 Modified Files: sql/server/rel_optimizer.c sql/server/rel_unnest.c Branch: default Log Message:
more subquery fixing diffs (98 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 @@ -113,8 +113,7 @@ static sql_rel * rel_join_order(visitor static void get_relations(visitor *v, sql_rel *rel, list *rels) { - if (!rel_is_ref(rel) && rel->op == op_join && rel->exps == NULL) { - assert(list_empty(rel->attr)); + if (list_empty(rel->attr) && !rel_is_ref(rel) && rel->op == op_join && rel->exps == NULL) { sql_rel *l = rel->l; sql_rel *r = rel->r; @@ -4523,7 +4522,7 @@ rel_push_join_exps_down(visitor *v, sql_ /* push select exps part of join expressions down */ if ((is_innerjoin(rel->op) || is_left(rel->op) || is_right(rel->op) || is_semi(rel->op)) && !list_empty(rel->exps)) { int left = is_innerjoin(rel->op) || is_right(rel->op) || /*is_semi(rel->op)*/ rel->op == op_semi; - int right = is_innerjoin(rel->op) || is_left(rel->op) || is_semi(rel->op); + int right = is_innerjoin(rel->op) || is_left(rel->op) || /*is_semi(rel->op)*/ rel->op == op_semi; sql_rel *jl = rel->l, *ojl = jl, *jr = rel->r, *ojr = jr; set_processed(jl); @@ -4532,14 +4531,13 @@ rel_push_join_exps_down(visitor *v, sql_ node *next = n->next; sql_exp *e = n->data; - if (left && rel_rebind_exp(v->sql, jl, e)) { /* select expressions on left */ + if (left && rel_rebind_exp(v->sql, jl, e) && e->flag != mark_notin && e->flag != mark_in) { /* select expressions on left */ if (!is_select(jl->op) || rel_is_ref(jl)) rel->l = jl = rel_select(v->sql->sa, jl, NULL); rel_select_add_exp(v->sql->sa, jl, e); list_remove_node(rel->exps, NULL, n); v->changes++; - } else if (right && ((rel->op != op_anti && rel->op != op_left) || (e->flag != mark_notin && e->flag != mark_in)) && - rel_rebind_exp(v->sql, jr, e)) { /* select expressions on right */ + } else if (right && rel_rebind_exp(v->sql, jr, e) && e->flag != mark_notin && e->flag != mark_in) { /* select expressions on right */ if (!is_select(jr->op) || rel_is_ref(jr)) rel->r = jr = rel_select(v->sql->sa, jr, NULL); rel_select_add_exp(v->sql->sa, jr, e); @@ -5355,7 +5353,7 @@ find_candidate_join2semi(visitor *v, sql /* generalize possibility : we need the visitor 'step' here */ if (rel_is_ref(rel)) /* if the join has multiple references, it's dangerous to convert it into a semijoin */ return NULL; - if (rel->op == op_join && !list_empty(rel->exps)) { + if (rel->op == op_join && !list_empty(rel->exps) && list_empty(rel->attr)) { sql_rel *l = rel->l, *r = rel->r; int foundr = NO_PROJECTION_FOUND, foundl = NO_PROJECTION_FOUND, found = NO_PROJECTION_FOUND; bool ok = false; @@ -5389,7 +5387,8 @@ find_candidate_join2semi(visitor *v, sql if ((c=find_candidate_join2semi(v, rel->l, swap)) != NULL || (c=find_candidate_join2semi(v, rel->r, swap)) != NULL) - return c; + if (list_empty(c->attr)) + return c; } if (is_topn(rel->op) || is_sample(rel->op)) return find_candidate_join2semi(v, rel->l, swap); diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c --- a/sql/server/rel_unnest.c +++ b/sql/server/rel_unnest.c @@ -3733,14 +3733,34 @@ rewrite_outer2inner_union_(visitor *v, s return rel; } +static bool +vars_depends_on(mvc *sql, sql_rel *rel, list *vars) +{ + if (!vars) + return false; + for(node *n = vars->h; n; n = n->next) { + sql_exp *e = n->data; + + if (exp_has_freevar(sql, e) && rel_rebind_exp(sql, rel, e)) + return true; + } + return false; +} + static sql_rel * rewrite_outer2inner_union(visitor *v, sql_rel *rel) { if (is_outerjoin(rel->op) && !list_empty(rel->exps) && (exps_have_anyequal(rel->exps, ANYEQUAL|NOT_ANYEQUAL) || (exps_have_freevar(v->sql, rel->exps) && exps_have_rel_exp(rel->exps) && exps_have_or_exp(v->sql, rel->exps)))) return rewrite_outer2inner_union_(v, rel); - if (!is_dependent(rel) && is_outerjoin(rel->op) && rel->flag != MERGE_LEFT && !list_empty(rel->exps) && (((/*is_left(rel->op) ||*/ is_full(rel->op)) && rel_has_freevar(v->sql,rel->l)) || - ((/*is_right(rel->op) ||*/ is_full(rel->op)) && rel_has_freevar(v->sql,rel->r)) || exps_have_freevar(v->sql, rel->exps))) + if (!is_dependent(rel) && is_outerjoin(rel->op) && rel->flag != MERGE_LEFT && !list_empty(rel->exps) && ( + ((is_left(rel->op) || is_full(rel->op)) && (exps_have_freevar(v->sql, rel->exps) && vars_depends_on(v->sql, rel->l, rel->exps))) || + ((is_right(rel->op) || is_full(rel->op)) && (exps_have_freevar(v->sql, rel->exps) && vars_depends_on(v->sql, rel->r, rel->exps))))) return rewrite_outer2inner_union_(v, rel); + if (is_full(rel->op) && rel_has_freevar(v->sql, rel->r)) { /* swap */ + sql_rel *s = rel->r; + rel->r = rel->l; + rel->l = s; + } return rel; } _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org