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

Reply via email to