Changeset: 5358f7d002a3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5358f7d002a3
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/rel_unnest.c
        sql/test/subquery/Tests/subquery6.sql
        sql/test/subquery/Tests/subquery6.stable.err
Branch: Oct2020
Log Message:

Disable some optimizations for single unions and joins for correctness of the 
results


diffs (145 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
@@ -4087,7 +4087,7 @@ rel_push_aggr_down(visitor *v, sql_rel *
                if (u->op == op_project)
                        u = u->l;
 
-               if (!u || !is_union(u->op) || need_distinct(u) || !u->exps || 
rel_is_ref(u))
+               if (!u || !is_union(u->op) || need_distinct(u) || is_single(u) 
|| !u->exps || rel_is_ref(u))
                        return rel;
 
                ul = u->l;
@@ -4893,7 +4893,7 @@ rel_push_semijoin_down_or_up(visitor *v,
                        l = l->l;
                */
 
-               if (!is_join(l->op) || is_full(l->op) || rel_is_ref(l))
+               if (!is_join(l->op) || is_full(l->op) || rel_is_ref(l) || 
is_single(l))
                        return rel;
 
                lop = l->op;
@@ -5103,7 +5103,7 @@ rel_push_join_down_union(visitor *v, sql
                if (is_semi(rel->op) && is_union(l->op) && je && 
!find_prop(je->p, PROP_JOINIDX))
                        return rel;
 
-               if ((is_union(l->op) && !need_distinct(l)) && !is_union(r->op)){
+               if ((is_union(l->op) && !need_distinct(l) && !is_single(l)) && 
!is_union(r->op)){
                        sql_rel *nl, *nr;
                        sql_rel *ll = rel_dup(l->l), *lr = rel_dup(l->r);
 
@@ -5130,8 +5130,8 @@ rel_push_join_down_union(visitor *v, sql
                        nr = rel_project(v->sql->sa, nr, 
rel_projections(v->sql, nr, NULL, 1, 1));
                        v->changes++;
                        return rel_inplace_setop(v->sql, rel, nl, nr, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
-               } else if (is_union(l->op) && !need_distinct(l) &&
-                          is_union(r->op) && !need_distinct(r)) {
+               } else if (is_union(l->op) && !need_distinct(l) && 
!is_single(l) &&
+                          is_union(r->op) && !need_distinct(r) && 
!is_single(r)) {
                        sql_rel *nl, *nr;
                        sql_rel *ll = rel_dup(l->l), *lr = rel_dup(l->r);
                        sql_rel *rl = rel_dup(r->l), *rr = rel_dup(r->r);
@@ -5174,7 +5174,7 @@ rel_push_join_down_union(visitor *v, sql
                        v->changes++;
                        return rel_inplace_setop(v->sql, rel, nl, nr, op_union, 
rel_projections(v->sql, rel, NULL, 1, 1));
                } else if (!is_union(l->op) &&
-                          is_union(r->op) && !need_distinct(r) &&
+                          is_union(r->op) && !need_distinct(r) && 
!is_single(r) &&
                           !is_semi(rel->op)) {
                        sql_rel *nl, *nr;
                        sql_rel *rl = rel_dup(r->l), *rr = rel_dup(r->r);
@@ -5218,7 +5218,7 @@ rel_push_join_down_union(visitor *v, sql
                 *
                 * */
                } else if (!is_union(l->op) &&
-                          is_union(r->op) && !need_distinct(r) &&
+                          is_union(r->op) && !need_distinct(r) && 
!is_single(r) &&
                           is_semi(rel->op) && rel_is_join_on_pkey(rel)) {
                        /* use first join expression, to find part nr */
                        sql_exp *je = rel->exps->h->data;
@@ -5496,7 +5496,7 @@ rel_push_select_down_union(visitor *v, s
                if (u->op == op_project)
                        u = u->l;
 
-               if (!u || !is_union(u->op) || need_distinct(u) || !u->exps || 
rel_is_ref(u))
+               if (!u || !is_union(u->op) || need_distinct(u) || is_single(u) 
|| !u->exps || rel_is_ref(u))
                        return rel;
 
                ul = u->l;
@@ -5628,7 +5628,7 @@ rel_push_project_down_union(visitor *v, 
                sql_rel *ul = u->l;
                sql_rel *ur = u->r;
 
-               if (!u || !is_union(u->op) || need_distinct(u) || !u->exps || 
rel_is_ref(u) || project_unsafe(rel,0))
+               if (!u || !is_union(u->op) || need_distinct(u) || is_single(u) 
|| !u->exps || rel_is_ref(u) || project_unsafe(rel,0))
                        return rel;
                /* don't push project down union of single values */
                if ((is_project(ul->op) && !ul->l) || (is_project(ur->op) && 
!ur->l))
@@ -7966,7 +7966,7 @@ rel_split_project(visitor *v, sql_rel *r
 
        if (!rel)
                return NULL;
-       if (is_project(rel->op) && list_length(rel->exps) && 
(is_groupby(rel->op) || rel->l) && !need_distinct(rel)) {
+       if (is_project(rel->op) && list_length(rel->exps) && 
(is_groupby(rel->op) || rel->l) && !need_distinct(rel) && !is_single(rel)) {
                list *exps = rel->exps;
                node *n;
                int funcs = 0;
@@ -8580,7 +8580,7 @@ rel_rewrite_antijoin(visitor *v, sql_rel
                sql_rel *r = rel->r;
 
                if (l && !rel_is_ref(l) &&
-                   r && !rel_is_ref(r) && is_union(r->op)) {
+                   r && !rel_is_ref(r) && is_union(r->op) && !is_single(r)) {
                        sql_rel *rl = rel_dup(r->l), *nl;
                        sql_rel *rr = rel_dup(r->r);
 
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
@@ -1993,6 +1993,14 @@ rewrite_or_exp(visitor *v, sql_rel *rel)
                                        list *exps = rel_projections(v->sql, 
rel, NULL, 1, 1);
 
                                        list_remove_node(rel->exps, n); /* 
remove or expression */
+                                       if (is_select(rel->op) && 
list_empty(rel->exps)) {
+                                               sql_rel *ll = rel->l;
+                                               rel->l = NULL;
+                                               rel_destroy(rel);
+                                               rel = ll;
+                                               l = rel;
+                                               r = rel_dup(rel);
+                                       }
 
                                        l = rel_select(v->sql->sa, l, NULL);
                                        l->exps = e->l;
diff --git a/sql/test/subquery/Tests/subquery6.sql 
b/sql/test/subquery/Tests/subquery6.sql
--- a/sql/test/subquery/Tests/subquery6.sql
+++ b/sql/test/subquery/Tests/subquery6.sql
@@ -309,6 +309,12 @@ select (select not exists (select sum(i1
        -- False
        -- False
 
+select 1 where (select 1 union all select 2) in (1);
+       --error, more than one row returned by a subquery used as an expression
+
+select (select 1 union all select 2) in (1);
+       --error, more than one row returned by a subquery used as an expression
+
 DROP TABLE tbl_ProductSales;
 DROP TABLE another_T;
 DROP TABLE integers;
diff --git a/sql/test/subquery/Tests/subquery6.stable.err 
b/sql/test/subquery/Tests/subquery6.stable.err
--- a/sql/test/subquery/Tests/subquery6.stable.err
+++ b/sql/test/subquery/Tests/subquery6.stable.err
@@ -102,6 +102,12 @@ MAPI  = (monetdb) /var/tmp/mtest-6957/.s
 QUERY = select (select sum(i1.i) > (select sum(i1.i + i2.i)) from integers i2) 
from integers i1;
 ERROR = !SELECT: subquery uses ungrouped column from outer query
 CODE  = 42000
+MAPI  = (monetdb) /var/tmp/mtest-151373/.s.monetdb.33332
+QUERY = select 1 where (select 1 union all select 2) in (1);
+ERROR = !GDK reported error: BATsubcross: more than one match
+MAPI  = (monetdb) /var/tmp/mtest-151373/.s.monetdb.33332
+QUERY = select (select 1 union all select 2) in (1);
+ERROR = !GDK reported error: BATsubcross: more than one match
 
 # 11:45:43 >  
 # 11:45:43 >  "Done."
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to