Changeset: 5a5aa119e2f9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/5a5aa119e2f9
Modified Files:
sql/server/rel_rewriter.c
sql/server/rel_unnest.c
Branch: sqloptimizer
Log Message:
Merged with default
diffs (truncated from 1625 to 300 lines):
diff --git a/cmake/monetdb-packages.cmake b/cmake/monetdb-packages.cmake
--- a/cmake/monetdb-packages.cmake
+++ b/cmake/monetdb-packages.cmake
@@ -23,7 +23,7 @@ include(monetdb-wix-packages)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
get_os_release_info(LINUX_DISTRO LINUX_DISTRO_VERSION)
- if (${LINUX_DISTRO} STREQUAL "debian")
+ if ("${LINUX_DISTRO}" STREQUAL "debian")
monetdb_debian_extra_files()
endif()
endif()
diff --git a/sql/server/rel_rewriter.c b/sql/server/rel_rewriter.c
--- a/sql/server/rel_rewriter.c
+++ b/sql/server/rel_rewriter.c
@@ -188,7 +188,7 @@ rewrite_simplify_exp(visitor *v, sql_rel
if (is_func(l->type) && exp_is_false(r) &&
(is_anyequal_func(((sql_subfunc*)l->f)) ||
is_exists_func(((sql_subfunc*)l->f)))) {
sql_subfunc *sf = l->f;
if (is_anyequal_func(sf))
- return exp_in_func(v->sql, l, r, !is_anyequal(sf),
0);
+ return exp_in_func(v->sql,
((list*)l->l)->h->data, ((list*)l->l)->h->next->data, !is_anyequal(sf), 0);
if (is_exists_func(sf))
return exp_exists(v->sql,
((list*)l->l)->h->data, !is_exists(sf));
return l;
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -3500,6 +3500,9 @@ static sql_exp *
if (is_sql_groupby(f)) {
char *uaname = SA_NEW_ARRAY(sql->ta, char,
strlen(aname) + 1);
return sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate function '%s' not allowed in GROUP BY clause", toUpperCopy(uaname,
aname), aname);
+ } else if (is_sql_aggr(f) && groupby->grouped) {
+ char *uaname = SA_NEW_ARRAY(sql->ta, char,
strlen(aname) + 1);
+ return sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate functions cannot be nested", toUpperCopy(uaname, aname));
} else if (is_sql_values(f)) {
char *uaname = SA_NEW_ARRAY(sql->ta, char,
strlen(aname) + 1);
return sql_error(sql, 02, SQLSTATE(42000) "%s:
aggregate functions not allowed on an unique value", toUpperCopy(uaname,
aname));
@@ -3583,8 +3586,10 @@ static sql_exp *
if (exp && !is_groupby_col(res, exp)) {
if (is_sql_groupby(sql_state))
return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate function '%s' not allowed in GROUP BY
clause", aname);
- if (0 && is_sql_aggr(sql_state))
- return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate function calls cannot be nested");
+ if (is_sql_aggr(sql_state) && groupby->grouped)
{
+ char *uaname = SA_NEW_ARRAY(sql->ta,
char, strlen(aname) + 1);
+ return sql_error(sql, 02,
SQLSTATE(42000) "%s: aggregate functions cannot be nested", toUpperCopy(uaname,
aname));
+ }
if (is_sql_values(sql_state))
return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate functions not allowed on an unique value");
if (is_sql_update_set(sql_state) ||
is_sql_psm(f))
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
@@ -1358,6 +1358,8 @@ push_up_join(mvc *sql, sql_rel *rel, lis
if (is_outerjoin(j->op) && j->exps &&
!list_empty(rel->attr)) {
visitor v = { .sql = sql };
rel->r = j = rewrite_outer2inner_union(&v, j);
+ if (!j)
+ return NULL;
return rel;
}
@@ -3368,19 +3370,7 @@ rewrite_exists(visitor *v, sql_rel *rel,
if (!is_project(sq->op) || (is_set(sq->op) &&
list_length(sq->exps) > 1) || (is_simple_project(sq->op) && !list_empty(sq->r)))
sq = rel_project(v->sql->sa, sq,
rel_projections(v->sql, sq, NULL, 1, 1));
le = rel_reduce2one_exp(v->sql, sq);
- if (is_project(sq->op) && is_freevar(le)) {
- sql_exp *re, *jc, *null;
-
- re = rel_bound_exp(v->sql, sq);
- sq->exps = sa_list(v->sql->sa);
- re = rel_project_add_exp(v->sql, sq, re);
- jc = rel_unop_(v->sql, NULL, re, "sys",
"isnull", card_value);
- set_has_no_nil(jc);
- null = exp_null(v->sql->sa, exp_subtype(le));
- le = rel_nop_(v->sql, NULL, jc, null, le, NULL,
"sys", "ifthenelse", card_value);
- } else {
- le = exp_ref(v->sql, le);
- }
+ le = exp_ref(v->sql, le);
if (is_project(rel->op) || depth > 0 ||
is_outerjoin(rel->op)) {
sql_subfunc *ea = NULL;
@@ -3842,10 +3832,41 @@ include_tid(sql_rel *r)
}
static sql_rel *
+add_null_projects(visitor *v, sql_rel *prel, sql_rel *irel, bool end)
+{
+ list *l = NULL;
+ node *n = prel->exps->h;
+ sql_rel *nilrel = rel_project(v->sql->sa, irel, rel_projections(v->sql,
irel, NULL, 1, 1));
+ int nr = prel->nrcols - nilrel->nrcols;
+ if (end) {
+ for(node *m = nilrel->exps->h; n && m; n = n->next, m = m->next)
+ ;
+ } else {
+ l = sa_list(v->sql->sa);
+ }
+ for(; nr; n = n->next, nr--) {
+ sql_exp *e = n->data, *ne;
+ sql_subtype *tp = exp_subtype(e);
+
+ if (!tp)
+ return sql_error(v->sql, 10, SQLSTATE(42000) "Cannot
rewrite subquery because of parameter with unknown type");
+ ne = exp_atom(v->sql->sa, atom_general(v->sql->sa, tp, NULL));
+ exp_setname(v->sql->sa, ne, exp_relname(e), exp_name(e));
+ if (end)
+ append(nilrel->exps, ne);
+ else
+ append(l, ne);
+ }
+ if (!end)
+ nilrel->exps = list_merge(l, nilrel->exps, NULL);
+ nilrel->nrcols = list_length(nilrel->exps);
+ return nilrel;
+}
+
+static sql_rel *
rewrite_outer2inner_union(visitor *v, sql_rel *rel)
{
if (is_outerjoin(rel->op) && !is_rewrite_outer_used(rel->used) &&
rel->flag != MERGE_LEFT) {
- sql_exp *f = exp_atom_bool(v->sql->sa, 0);
int nrcols = rel->nrcols;
nrcols = include_tid(rel->l);
@@ -3862,14 +3883,11 @@ rewrite_outer2inner_union(visitor *v, sq
rel_project(v->sql->sa, rel_dup(prel),
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
rel_setop_set_exps(v->sql, except,
rel_projections(v->sql, rel->l, NULL, 1, 1), false);
set_processed(except);
- sql_rel *nrel = rel_crossproduct(v->sql->sa, except,
rel_dup(rel->r), op_left);
- set_processed(nrel);
- nrel->used |= rewrite_outer_used;
- rel_join_add_exp(v->sql->sa, nrel, f);
- nrel = rel_setop(v->sql->sa,
- prel,
- rel_project(v->sql->sa, nrel,
rel_projections(v->sql, nrel, NULL, 1, 1)),
- op_union);
+ sql_rel *nilrel = add_null_projects(v, prel, except,
true);
+ if (!nilrel)
+ return NULL;
+
+ sql_rel *nrel = rel_setop(v->sql->sa, prel, nilrel,
op_union);
rel_setop_set_exps(v->sql, nrel,
rel_projections(v->sql, rel, NULL, 1, 1), false);
set_processed(nrel);
if(is_single(rel))
@@ -3888,14 +3906,11 @@ rewrite_outer2inner_union(visitor *v, sq
rel_project(v->sql->sa, rel_dup(prel),
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
rel_setop_set_exps(v->sql, except,
rel_projections(v->sql, rel->r, NULL, 1, 1), false);
set_processed(except);
- sql_rel *nrel = rel_crossproduct(v->sql->sa,
rel_dup(rel->l), except, op_right);
- set_processed(nrel);
- nrel->used |= rewrite_outer_used;
- rel_join_add_exp(v->sql->sa, nrel, f);
- nrel = rel_setop(v->sql->sa,
- prel,
- rel_project(v->sql->sa, nrel,
rel_projections(v->sql, nrel, NULL, 1, 1)),
- op_union);
+ sql_rel *nilrel = add_null_projects(v, prel, except,
false);
+ if (!nilrel)
+ return NULL;
+
+ sql_rel *nrel = rel_setop(v->sql->sa, prel, nilrel,
op_union);
rel_setop_set_exps(v->sql, nrel,
rel_projections(v->sql, rel, NULL, 1, 1), false);
set_processed(nrel);
if(is_single(rel))
@@ -3914,30 +3929,23 @@ rewrite_outer2inner_union(visitor *v, sq
rel_project(v->sql->sa, rel_dup(prel),
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
rel_setop_set_exps(v->sql, except,
rel_projections(v->sql, rel->l, NULL, 1, 1), false);
set_processed(except);
- sql_rel *lrel = rel_crossproduct(v->sql->sa, except,
rel_dup(rel->r), op_left);
- set_processed(lrel);
- lrel->used |= rewrite_outer_used;
- rel_join_add_exp(v->sql->sa, lrel, f);
+ sql_rel *lrel = add_null_projects(v, prel, except,
true);
+ if (!lrel)
+ return NULL;
except = rel_setop(v->sql->sa,
rel_project(v->sql->sa,
rel_dup(rel->r), rel_projections(v->sql, rel->r, NULL, 1, 1)),
rel_project(v->sql->sa, rel_dup(prel),
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
rel_setop_set_exps(v->sql, except,
rel_projections(v->sql, rel->r, NULL, 1, 1), false);
set_processed(except);
- sql_rel *rrel = rel_crossproduct(v->sql->sa,
rel_dup(rel->l), except, op_right);
- set_processed(rrel);
- rrel->used |= rewrite_outer_used;
- rel_join_add_exp(v->sql->sa, rrel, f);
- lrel = rel_setop(v->sql->sa,
- rel_project(v->sql->sa, lrel,
rel_projections(v->sql, lrel, NULL, 1, 1)),
- rel_project(v->sql->sa, rrel,
rel_projections(v->sql, rrel, NULL, 1, 1)),
- op_union);
+ sql_rel *rrel = add_null_projects(v, prel, except,
false);
+ if (!rrel)
+ return NULL;
+
+ lrel = rel_setop(v->sql->sa, lrel, rrel, op_union);
rel_setop_set_exps(v->sql, lrel,
rel_projections(v->sql, rel, NULL, 1, 1), false);
set_processed(lrel);
- lrel = rel_setop(v->sql->sa,
- rel_project(v->sql->sa, prel,
rel_projections(v->sql, rel, NULL, 1, 1)),
- rel_project(v->sql->sa, lrel,
rel_projections(v->sql, lrel, NULL, 1, 1)),
- op_union);
+ lrel = rel_setop(v->sql->sa, prel, lrel, op_union);
rel_setop_set_exps(v->sql, lrel,
rel_projections(v->sql, rel, NULL, 1, 1), false);
set_processed(lrel);
if(is_single(rel))
@@ -3999,8 +4007,9 @@ flatten_values(visitor *v, sql_rel *rel)
if (vals) {
if (i == 0)
append(exps, exp_ref(v->sql,
e));
- sql_exp *v = list_fetch(vals, i);
- append(nrel->exps, v);
+ sql_exp *val = list_fetch(vals, i);
+ exp_setname(v->sql->sa, val,
exp_relname(e), exp_name(e));
+ append(nrel->exps, val);
rel_set_exps(nrel, nrel->exps);
}
}
@@ -4011,6 +4020,8 @@ flatten_values(visitor *v, sql_rel *rel)
}
cur = nrel;
}
+ if (is_single(rel))
+ set_single(cur);
rel_destroy(rel);
rel = cur;
v->changes++;
@@ -4022,7 +4033,6 @@ flatten_values(visitor *v, sql_rel *rel)
static inline sql_rel *
rewrite_values(visitor *v, sql_rel *rel)
{
- int single = is_single(rel);
if (!is_simple_project(rel->op) || list_empty(rel->exps) ||
is_rewrite_values_used(rel->used))
return rel;
@@ -4036,50 +4046,9 @@ rewrite_values(visitor *v, sql_rel *rel)
return rel;
}
sql_exp *e = rel->exps->h->data;
-
- if (!is_values(e) || list_length(exp_get_values(e))<=1)
- return rel;
-
- if (is_values(e) && exps_have_rel_exp(rel->exps))
- return flatten_values(v, rel);
-
- if (!exps_have_freevar(v->sql, rel->exps))
+ if (!is_values(e) || (!exps_have_rel_exp(rel->exps) &&
!exps_have_freevar(v->sql, rel->exps)))
return rel;
-
- list *exps = sa_list(v->sql->sa);
- sql_rel *cur = NULL;
- list *vals = exp_get_values(e);
- if (vals) {
- for(int i = 0; i<list_length(vals); i++) {
- sql_rel *nrel = rel_project(v->sql->sa, NULL,
sa_list(v->sql->sa));
- set_processed(nrel);
- for(node *n = rel->exps->h; n; n = n->next) {
- sql_exp *e = n->data;
- list *vals = exp_get_values(e);
-
- if (vals) {
- if (i == 0)
- append(exps, exp_ref(v->sql,
e));
- sql_exp *v = list_fetch(vals, i);
- append(nrel->exps, v);
- rel_set_exps(nrel, nrel->exps);
- }
- }
- if (cur) {
- nrel = rel_setop(v->sql->sa, cur, nrel,
op_union);
- rel_setop_set_exps(v->sql, nrel, exps, false);
- set_processed(nrel);
- }
- cur = nrel;
- }
- rel_destroy(rel);
- rel = cur;
- rel->used |= rewrite_values_used;
- if (single)
- set_single(rel);
- v->changes++;
- }
- return rel;
+ return flatten_values(v, rel);
}
static inline sql_rel *
@@ -4104,20 +4073,18 @@ rewrite_rel(visitor *v, sql_rel *rel)
sql_rel *ir = exp_rel_get_rel(v->sql->sa, e);
rel = rewrite_outer2inner_union(v, rel);
- if (or == rel)
+ if (!rel || or == rel)
return rel;
/* change referenced project into join with outer(ir) */
sql_rel *nr = rel->l;
assert(is_project(nr->op));
if (!rel_is_ref(nr))
nr = nr->l;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]