Changeset: e1feb741fa00 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e1feb741fa00
Removed Files:
        sql/test/subquery/Tests/subquery6.sql
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_unnest.c
        sql/test/subquery/Tests/subquery6.test
Branch: default
Log Message:

Merged with Oct2020


diffs (199 lines):

diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -2589,7 +2589,7 @@ is_identity( sql_exp *e, sql_rel *r)
                return 0;
        case e_func: {
                sql_subfunc *f = e->f;
-               return (strcmp(f->func->base.name, "identity") == 0);
+               return !f->func->s && strcmp(f->func->base.name, "identity") == 
0;
        }
        default:
                return 0;
@@ -2750,12 +2750,12 @@ exp_flatten(mvc *sql, sql_exp *e)
                sql_arg *res = (f->func->res)?(f->func->res->h->data):NULL;
 
                /* TODO handle date + x months */
-               if (strcmp(f->func->base.name, "sql_add") == 0 && 
list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) {
+               if (!f->func->s && strcmp(f->func->base.name, "sql_add") == 0 
&& list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) {
                        atom *l1 = exp_flatten(sql, l->h->data);
                        atom *l2 = exp_flatten(sql, l->h->next->data);
                        if (l1 && l2)
                                return atom_add(l1,l2);
-               } else if (strcmp(f->func->base.name, "sql_sub") == 0 && 
list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) {
+               } else if (!f->func->s && strcmp(f->func->base.name, "sql_sub") 
== 0 && list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) {
                        atom *l1 = exp_flatten(sql, l->h->data);
                        atom *l2 = exp_flatten(sql, l->h->next->data);
                        if (l1 && l2)
@@ -2821,7 +2821,7 @@ exp_sum_scales(sql_subfunc *f, sql_exp *
 int
 exp_aggr_is_count(sql_exp *e)
 {
-       if (e->type == e_aggr && strcmp(((sql_subfunc *)e->f)->func->base.name, 
"count") == 0)
+       if (e->type == e_aggr && !((sql_subfunc *)e->f)->func->s && 
strcmp(((sql_subfunc *)e->f)->func->base.name, "count") == 0)
                return 1;
        return 0;
 }
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
@@ -4039,7 +4039,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;
@@ -4845,7 +4845,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;
@@ -5055,7 +5055,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);
 
@@ -5082,8 +5082,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);
@@ -5126,7 +5126,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);
@@ -5170,7 +5170,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;
@@ -5448,7 +5448,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;
@@ -5616,6 +5616,8 @@ rel_push_project_down_union(visitor *v, 
                        rel_projections(v->sql, rel, NULL, 1, 1));
                if (need_distinct)
                        set_distinct(rel);
+               if (is_single(u))
+                       set_single(rel);
                v->changes++;
                rel->l = rel_merge_projects(v, rel->l);
                rel->r = rel_merge_projects(v, rel->r);
@@ -7971,7 +7973,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;
@@ -8585,7 +8587,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_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -1497,11 +1497,12 @@ static sql_rel *
        list *exps = rel_projections(sql, rel, NULL, 1, 1);
        sql_exp *e;
 
-       if (list_length(exps) == 0) {
+       if (list_empty(exps)) {
                *exp = NULL;
                return rel;
        }
-       rel = rel_project(sql->sa, rel, exps);
+       if (!is_simple_project(rel->op) || !list_empty(rel->r))
+               rel = rel_project(sql->sa, rel, exps);
        e = rel->exps->h->data;
        e = exp_column(sql->sa, exp_relname(e), exp_name(e), exp_subtype(e), 
rel->card, has_nil(e), is_intern(e));
        e = exp_unop(sql->sa, e, sql_bind_func(sql, "sys", "identity", 
exp_subtype(e), NULL, F_FUNC));
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
@@ -1988,18 +1988,27 @@ rewrite_or_exp(visitor *v, sql_rel *rel)
 {
        if ((is_select(rel->op) || is_join(rel->op) || is_semi(rel->op)) && 
!list_empty(rel->exps)) {
                for(node *n=rel->exps->h; n; n=n->next) {
-                       sql_exp *e = n->data;
+                       sql_exp *e = n->data, *id;
 
                        if (is_compare(e->type) && e->flag == cmp_or) {
                                /* check for exp_is_rel */
                                if (exps_have_rel_exp(e->l) || 
exps_have_rel_exp(e->r)) {
                                        /* rewrite into setop */
+                                       list_remove_node(rel->exps, NULL, n); 
/* remove or expression */
+                                       if (is_select(rel->op) && 
list_empty(rel->exps)) { /* remove empty select if that's the case */
+                                               sql_rel *l = rel->l;
+                                               rel->l = NULL;
+                                               rel_destroy(rel);
+                                               rel = l;
+                                       }
+                                       rel = rel_add_identity(v->sql, rel, 
&id); /* identity function needed */
+                                       (void) id;
+                                       assert(id);
+
                                        sql_rel *l = rel;
                                        sql_rel *r = rel_dup(rel);
                                        list *exps = rel_projections(v->sql, 
rel, NULL, 1, 1);
 
-                                       list_remove_node(rel->exps, NULL, n); 
/* remove or expression */
-
                                        l = rel_select(v->sql->sa, l, NULL);
                                        l->exps = e->l;
                                        if (!(l = rewrite_or_exp(v, l)))
diff --git a/sql/test/subquery/Tests/subquery6.test 
b/sql/test/subquery/Tests/subquery6.test
--- a/sql/test/subquery/Tests/subquery6.test
+++ b/sql/test/subquery/Tests/subquery6.test
@@ -479,6 +479,12 @@ False
 False
 False
 
+statement error
+select 1 where (select 1 union all select 2) in (1)
+
+statement error
+select (select 1 union all select 2) in (1)
+
 statement ok
 DROP TABLE tbl_ProductSales
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to