Changeset: 77ff6e9bae1e for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=77ff6e9bae1e Added Files: sql/test/miscellaneous/Tests/vessels.sql sql/test/miscellaneous/Tests/vessels.stable.err sql/test/miscellaneous/Tests/vessels.stable.out Modified Files: sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_psm.c sql/server/rel_rel.c sql/server/rel_rel.h sql/server/rel_select.c sql/server/rel_unnest.c sql/server/sql_parser.y sql/test/BugTracker-2015/Tests/window_function_crash.Bug-3861.stable.err sql/test/miscellaneous/Tests/All sql/test/pg_regress/Tests/arrays.stable.err sql/test/subquery/Tests/subquery4.stable.err sql/test/subquery/Tests/subquery6.sql sql/test/subquery/Tests/subquery6.stable.err sql/test/subquery/Tests/subquery6.stable.out Branch: default Log Message:
Merged with Jun2020 diffs (truncated from 968 to 300 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 @@ -155,8 +155,6 @@ exp_compare(sql_allocator *sa, sql_exp * if (e == NULL) return NULL; e->card = MAX(l->card,r->card); - if (e->card == CARD_ATOM && !exp_is_atom(l)) - e->card = CARD_AGGR; e->l = l; e->r = r; e->flag = cmptype; @@ -169,12 +167,10 @@ exp_compare2(sql_allocator *sa, sql_exp sql_exp *e = exp_create(sa, e_cmp); if (e == NULL) return NULL; + assert(f); e->card = MAX(MAX(l->card,r->card),f->card); - if (e->card == CARD_ATOM && !exp_is_atom(l)) - e->card = CARD_AGGR; e->l = l; e->r = r; - assert(f); e->f = f; e->flag = cmptype; return e; @@ -252,30 +248,19 @@ exp_in_func(mvc *sql, sql_exp *le, sql_e } sql_exp * -exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp *oe, const char *compareop, int quantifier) +exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, const char *compareop, int quantifier) { - sql_subfunc *cmp_func = NULL; + sql_subfunc *cmp_func = sql_bind_func(sql->sa, NULL, compareop, exp_subtype(le), exp_subtype(le), F_FUNC); sql_exp *e; - - if (!oe) { - cmp_func = sql_bind_func(sql->sa, NULL, compareop, exp_subtype(le), exp_subtype(le), F_FUNC); - assert(cmp_func); - e = exp_binop(sql->sa, le, re, cmp_func); - } else { - list *types = sa_list(sql->sa), *args = sa_list(sql->sa); - append(types, exp_subtype(le)); - append(types, exp_subtype(le)); - append(types, exp_subtype(le)); - append(args, le); - append(args, re); - append(args, oe); - cmp_func = sql_bind_func_(sql->sa, NULL, compareop, types, F_FUNC); - assert(cmp_func); - e = exp_op(sql->sa, args, cmp_func); - } + + assert(cmp_func); + e = exp_binop(sql->sa, le, re, cmp_func); if (e) { e->flag = quantifier; - e->card = le->card; + if (quantifier) + e->card = le->card; /* At ANY and ALL operators, the cardinality on the right side is ignored */ + else + e->card = MAX(le->card, re->card); } return e; } @@ -314,8 +299,6 @@ exp_op( sql_allocator *sa, list *l, sql_ if (e == NULL) return NULL; e->card = exps_card(l); - if (!l || list_length(l) == 0) - e->card = CARD_ATOM; /* unop returns a single atom */ e->l = l; e->f = f; e->semantics = f->func->semantics; @@ -336,8 +319,6 @@ exp_rank_op( sql_allocator *sa, list *l, if (e == NULL) return NULL; e->card = exps_card(l); - if (!l || list_length(l) == 0) - e->card = CARD_ATOM; /* unop returns a single atom */ e->l = l; e->r = append(append(sa_list(sa), gbe), obe); e->f = f; diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h --- a/sql/server/rel_exp.h +++ b/sql/server/rel_exp.h @@ -36,7 +36,7 @@ extern sql_exp *exp_filter(sql_allocator extern sql_exp *exp_or(sql_allocator *sa, list *l, list *r, int anti); extern sql_exp *exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype); extern sql_exp *exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple); -extern sql_exp *exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp *oe, const char *compareop, int quantifier); +extern sql_exp *exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, const char *compareop, int quantifier); #define exp_fromtype(e) ((list*)e->r)->h->data #define exp_totype(e) ((list*)e->r)->h->next->data diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c --- a/sql/server/rel_psm.c +++ b/sql/server/rel_psm.c @@ -16,6 +16,15 @@ #include "rel_updates.h" #include "sql_privileges.h" +#define psm_zero_or_one(exp) \ + do { \ + if (exp && exp->card > CARD_AGGR) { \ + sql_subfunc *zero_or_one = sql_bind_func(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(exp), NULL, F_AGGR); \ + assert(zero_or_one); \ + exp = exp_aggr1(sql->sa, exp, zero_or_one, 0, 0, CARD_ATOM, has_nil(exp)); \ + } \ + } while(0) + static list *sequential_block(sql_query *query, sql_subtype *restype, list *restypelist, dlist *blk, char *opt_name, int is_func); sql_rel * @@ -94,13 +103,9 @@ psm_set_exp(sql_query *query, dnode *n) if (!resolve_variable_on_scope(sql, s, sname, vname, &var, &a, &tpe, &level, "SET")) return NULL; - if (!(e = rel_value_exp2(query, &rel, val, sql_sel | sql_psm_set, ek))) + if (!(e = rel_value_exp2(query, &rel, val, sql_sel | sql_psm, ek))) return NULL; - if (e->card > CARD_AGGR) { - sql_subfunc *zero_or_one = sql_bind_func(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(e), NULL, F_AGGR); - assert(zero_or_one); - e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, has_nil(e)); - } + psm_zero_or_one(e); if (!(e = rel_check_type(sql, tpe, rel, e, type_cast))) return NULL; @@ -255,14 +260,14 @@ rel_psm_while_do( sql_query *query, sql_ sql_rel *rel = NULL; exp_kind ek = {type_value, card_value, FALSE}; - cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel, ek); + cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel | sql_psm, ek); + psm_zero_or_one(cond); n = n->next; whilestmts = sequential_block(query, res, restypelist, n->data.lval, n->next->data.sval, is_func); if (sql->session->status || !cond || !whilestmts) return NULL; - assert(!rel); return exp_while( sql->sa, cond, whilestmts ); } return NULL; @@ -287,7 +292,8 @@ psm_if_then_else( sql_query *query, sql_ sql_rel *rel = NULL; exp_kind ek = {type_value, card_value, FALSE}; - cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel, ek); + cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel | sql_psm, ek); + psm_zero_or_one(cond); n = n->next; ifstmts = sequential_block(query, res, restypelist, n->data.lval, NULL, is_func); n = n->next; @@ -296,7 +302,6 @@ psm_if_then_else( sql_query *query, sql_ if (sql->session->status || !cond || !ifstmts) return NULL; - assert(!rel); return append(sa_list(sql->sa), exp_if( sql->sa, cond, ifstmts, elsestmts)); } else { /* else */ symbol *e = elseif->data.sym; @@ -320,7 +325,8 @@ rel_psm_if_then_else( sql_query *query, sql_rel *rel = NULL; exp_kind ek = {type_value, card_value, FALSE}; - cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel, ek); + cond = rel_logical_value_exp(query, &rel, n->data.sym, sql_sel | sql_psm, ek); + psm_zero_or_one(cond); n = n->next; ifstmts = sequential_block(query, res, restypelist, n->data.lval, NULL, is_func); n = n->next; @@ -328,7 +334,6 @@ rel_psm_if_then_else( sql_query *query, if (sql->session->status || !cond || !ifstmts) return NULL; - assert(!rel); return exp_if( sql->sa, cond, ifstmts, elsestmts); } return NULL; @@ -366,30 +371,28 @@ rel_psm_case( sql_query *query, sql_subt list *else_stmt = NULL; sql_rel *rel = NULL; exp_kind ek = {type_value, card_value, FALSE}; - sql_exp *v = rel_value_exp(query, &rel, case_value, sql_sel, ek); + sql_exp *v = rel_value_exp(query, &rel, case_value, sql_sel | sql_psm, ek); + psm_zero_or_one(v); if (!v) return NULL; - if (rel) - return sql_error(sql, 02, SQLSTATE(42000) "CASE: No SELECT statements allowed within the CASE condition"); - if (else_statements) { - if (!(else_stmt = sequential_block(query, res, restypelist, else_statements, NULL, is_func))) - return NULL; - } + if (else_statements && !(else_stmt = sequential_block(query, res, restypelist, else_statements, NULL, is_func))) + return NULL; + n = when_statements->h; while(n) { dnode *m = n->data.sym->data.lval->h; - sql_exp *cond=0, *when_value = rel_value_exp(query, &rel, m->data.sym, sql_sel, ek); + sql_exp *cond=0, *when_value = rel_value_exp(query, &rel, m->data.sym, sql_sel | sql_psm, ek); list *if_stmts = NULL; sql_exp *case_stmt = NULL; - if (!when_value || rel || + psm_zero_or_one(when_value); + if (!when_value || (cond = rel_binop_(sql, rel, v, when_value, NULL, "=", card_value)) == NULL || (if_stmts = sequential_block(query, res, restypelist, m->next->data.lval, NULL, is_func)) == NULL ) { - if (rel) - return sql_error(sql, 02, SQLSTATE(42000) "CASE: No SELECT statements allowed within the CASE condition"); return NULL; } + psm_zero_or_one(cond); case_stmt = exp_if(sql->sa, cond, if_stmts, NULL); list_append(case_stmts, case_stmt); n = n->next; @@ -404,23 +407,21 @@ rel_psm_case( sql_query *query, sql_subt dlist *else_statements = n->next->data.lval; list *else_stmt = NULL; - if (else_statements) { - if (!(else_stmt = sequential_block(query, res, restypelist, else_statements, NULL, is_func))) - return NULL; - } + if (else_statements && !(else_stmt = sequential_block(query, res, restypelist, else_statements, NULL, is_func))) + return NULL; + n = whenlist->h; while(n) { dnode *m = n->data.sym->data.lval->h; sql_rel *rel = NULL; exp_kind ek = {type_value, card_value, FALSE}; - sql_exp *cond = rel_logical_value_exp(query, &rel, m->data.sym, sql_sel, ek); + sql_exp *cond = rel_logical_value_exp(query, &rel, m->data.sym, sql_sel | sql_psm, ek); list *if_stmts = NULL; sql_exp *case_stmt = NULL; - if (!cond || rel || + psm_zero_or_one(cond); + if (!cond || (if_stmts = sequential_block(query, res, restypelist, m->next->data.lval, NULL, is_func)) == NULL ) { - if (rel) - return sql_error(sql, 02, SQLSTATE(42000) "CASE: No SELECT statements allowed within the CASE condition"); return NULL; } case_stmt = exp_if(sql->sa, cond, if_stmts, NULL); @@ -1447,7 +1448,9 @@ psm_analyze(sql_query *query, char *anal append(exps, mm_exp = exp_atom_int(sql->sa, minmax)); append(tl, exp_subtype(mm_exp)); if (sample) { - sample_exp = rel_value_exp(query, NULL, sample, 0, ek); + sql_rel *rel = NULL; + sample_exp = rel_value_exp(query, &rel, sample, sql_sel | sql_psm, ek); + psm_zero_or_one(sample_exp); if (!sample_exp || !(sample_exp = rel_check_type(sql, sql_bind_localtype("lng"), NULL, sample_exp, type_cast))) return NULL; } else { 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 @@ -2307,3 +2307,25 @@ rel_visitor_bottomup(mvc *sql, sql_rel * { return rel_visitor(sql, rel, rel_rewriter, changes, false); } + +static sql_exp * +exp_check_has_analytics(mvc *sql, sql_rel *rel, sql_exp *e, int depth, int *changes) +{ + (void)sql; (void)rel; (void)depth; + if (e && e->type == e_func) { + sql_subfunc *f = e->f; + + if (f && f->func && f->func->type == F_ANALYTIC) + (*changes)++; + } + return e; +} + +int +exps_have_analytics(mvc *sql, list *exps) +{ + int changes = 0; + (void)exps_exp_visitor(sql, NULL, exps, 0, &exp_check_has_analytics, &changes, 1); + return changes; +} + diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h --- a/sql/server/rel_rel.h +++ b/sql/server/rel_rel.h @@ -26,7 +26,7 @@ #define sql_outer (1 << 10) //ORed #define sql_group_totals (1 << 11) //ORed _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list