Changeset: f028949e1bcc for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f028949e1bcc
Modified Files:
        sql/server/rel_optimizer.c
        sql/test/SQLancer/Tests/sqlancer05.sql
Branch: Oct2020
Log Message:

fixed problem with join_order optimizer, it lost 'select' expressions

fixed problem with push semijoin optimizer, checks for rewriting were incorrect.


diffs (97 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
@@ -919,11 +919,6 @@ order_joins(visitor *v, list *rels, list
                        ln = list_find(n_rels, cje->l, (fcmp)&rel_has_exp);
                        rn = list_find(n_rels, cje->r, (fcmp)&rel_has_exp);
 
-                       if (ln || rn) {
-                               /* remove the expression from the lists */
-                               list_remove_data(sdje, cje);
-                               list_remove_data(exps, cje);
-                       }
                        if (ln && rn) {
                                assert(0);
                                /* create a selection on the current */
@@ -941,8 +936,14 @@ order_joins(visitor *v, list *rels, list
                                }
                                if (!r) {
                                        fnd = 1; /* not really, but this bails 
out */
+                                       list_remove_data(sdje, cje); /* handle 
later as select */
                                        continue;
                                }
+
+                               /* remove the expression from the lists */
+                               list_remove_data(sdje, cje);
+                               list_remove_data(exps, cje);
+
                                list_remove_data(rels, r);
                                append(n_rels, r);
 
@@ -4819,28 +4820,29 @@ rel_push_semijoin_down_or_up(visitor *v,
                lop = l->op;
                ll = l->l;
                lr = l->r;
-               /* semijoin shouldn't be based on right relation of join */
+
+               /* check which side is used and other exps are atoms or from 
right of semijoin */
                for(n = exps->h; n; n = n->next) {
                        sql_exp *sje = n->data;
 
-                       if (sje->type != e_cmp)
+                       if (sje->type != e_cmp || is_complex_exp(sje->flag))
                                return rel;
-                       if (right &&
-                               (is_complex_exp(sje->flag) ||
-                               rel_has_exp(lr, sje->l) < 0 ||
-                               rel_has_exp(lr, sje->r) < 0 ||
-                                       (sje->f && rel_has_exp(lr, sje->f) < 
0))) {
+                       /* sje->l from ll and sje->r/f from semijoin r ||
+                        * sje->l from semijoin r and sje->r/f from ll ||
+                        * sje->l from lr and sje->r/f from semijoin r ||
+                        * sje->l from semijoin r and sje->r/f from lr */
+                       if (left &&
+                          ((rel_has_exp(ll, sje->l) >= 0 && 
rel_has_exp(rel->r, sje->r) >= 0 && (!sje->f || rel_has_exp(rel->r, sje->f) >= 
0)) ||
+                           (rel_has_exp(rel->r, sje->l) >= 0 && 
rel_has_exp(ll, sje->r) >= 0 && (!sje->f || rel_has_exp(ll, sje->f) >= 0))))
                                right = 0;
-                       }
-                       if (right)
+                       else
                                left = 0;
-                       if (!right && left &&
-                               (is_complex_exp(sje->flag) ||
-                               rel_has_exp(ll, sje->l) < 0 ||
-                               rel_has_exp(ll, sje->r) < 0 ||
-                                       (sje->f && rel_has_exp(ll, sje->f) < 
0))) {
+                       if (right &&
+                          ((rel_has_exp(lr, sje->l) >= 0 && 
rel_has_exp(rel->r, sje->r) >= 0 && (!sje->f || rel_has_exp(rel->r, sje->f) >= 
0)) ||
+                           (rel_has_exp(rel->r, sje->l) >= 0 && 
rel_has_exp(lr, sje->r) >= 0 && (!sje->f || rel_has_exp(lr, sje->f) >= 0))))
                                left = 0;
-                       }
+                       else
+                               right = 0;
                        if (!right && !left)
                                return rel;
                }
@@ -5514,7 +5516,7 @@ rel_push_project_down(visitor *v, sql_re
                        }
                        return rel;
                } else if (list_check_prop_all(rel->exps, 
(prop_check_func)&exp_is_useless_rename)) {
-                       if ((is_project(l->op) && list_length(l->exps) == 
list_length(rel->exps)) || is_set(l->op) || is_select(l->op) 
+                       if ((is_project(l->op) && list_length(l->exps) == 
list_length(rel->exps)) || is_set(l->op) || is_select(l->op)
                                || is_join(l->op) || is_semi(l->op) || 
is_topn(l->op) || is_sample(l->op)) {
                                rel->l = NULL;
                                rel_destroy(rel);
diff --git a/sql/test/SQLancer/Tests/sqlancer05.sql 
b/sql/test/SQLancer/Tests/sqlancer05.sql
--- a/sql/test/SQLancer/Tests/sqlancer05.sql
+++ b/sql/test/SQLancer/Tests/sqlancer05.sql
@@ -53,8 +53,7 @@ 1394786866
 1112194034
 2140251980
 
-SELECT 1 FROM (select time '12:43:09' from t0) as v0(c0) RIGHT OUTER JOIN 
(SELECT INTERVAL '2' SECOND FROM t0) AS sub0 ON 
-TIME '07:04:19' BETWEEN CASE 'b' WHEN 'a' THEN v0.c0 ELSE v0.c0 END AND v0.c0;
+SELECT 1 FROM (select time '12:43:09' from t0) as v0(c0) RIGHT OUTER JOIN 
(SELECT INTERVAL '2' SECOND FROM t0) AS sub0 ON TIME '07:04:19' BETWEEN CASE 
'b' WHEN 'a' THEN v0.c0 ELSE v0.c0 END AND v0.c0;
        --8 rows of 1
 create view v0(c0, c1) as (select all time '12:43:09', interval '1251003346' 
second from t0) with check option;
 SELECT count(ALL - (CAST(NULL AS INT))) FROM v0 RIGHT OUTER JOIN (SELECT 
INTERVAL '1380374779' SECOND FROM t0) AS sub0 ON 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to