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