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 -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org