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