Changeset: 7dfdde501bc4 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/7dfdde501bc4 Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql_statement.h sql/common/sql_types.c sql/server/rel_dump.c sql/server/rel_optimizer.c sql/server/rel_rewriter.h sql/server/rel_select.c sql/server/rel_unnest.c Branch: Jul2021 Log Message:
handle case (like casewhen, coalesce and nullif) special. diffs (133 lines): diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -1268,7 +1268,7 @@ exp_bin(backend *be, sql_exp *e, stmt *l else if (!list_empty(exps)) { unsigned nrcols = 0; - if (strcmp(sql_func_mod(f->func), "calc") == 0 && strcmp(sql_func_imp(f->func), "ifthenelse") == 0) + if (strcmp(sql_func_mod(f->func), "") == 0 && strcmp(sql_func_imp(f->func), "") == 0 && strcmp(f->func->base.name, "case") == 0) return exp2bin_case(be, e, left, right, sel, depth); if (strcmp(sql_func_mod(f->func), "") == 0 && strcmp(sql_func_imp(f->func), "") == 0 && strcmp(f->func->base.name, "casewhen") == 0) return exp2bin_casewhen(be, e, left, right, sel, depth); diff --git a/sql/backends/monet5/sql_statement.h b/sql/backends/monet5/sql_statement.h --- a/sql/backends/monet5/sql_statement.h +++ b/sql/backends/monet5/sql_statement.h @@ -134,8 +134,10 @@ typedef struct stmt { /* which MAL modules can push candidates */ #define can_push_cands(sel, f) \ - (sel && (strcmp(sql_func_mod(f->func), "calc") == 0 || strcmp(sql_func_mod(f->func), "mmath") == 0 || \ - strcmp(sql_func_mod(f->func), "mtime") == 0 || strcmp(sql_func_mod(f->func), "blob") == 0 || \ + (sel && (((strcmp(sql_func_mod(f->func), "calc") == 0 && strcmp(sql_func_imp(f->func), "ifthenelse") != 0)) || \ + strcmp(sql_func_mod(f->func), "mmath") == 0 || \ + strcmp(sql_func_mod(f->func), "mtime") == 0 || \ + strcmp(sql_func_mod(f->func), "blob") == 0 || \ (strcmp(sql_func_mod(f->func), "str") == 0 && batstr_func_has_candidates(sql_func_imp(f->func))))) extern int stmt_key(stmt *s); diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c --- a/sql/common/sql_types.c +++ b/sql/common/sql_types.c @@ -950,10 +950,11 @@ sqltypeinit( sql_allocator *sa) sql_create_func(sa, "least", "calc", "min_no_nil", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); sql_create_func(sa, "greatest", "calc", "max_no_nil", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); sql_create_func(sa, "ifthenelse", "calc", "ifthenelse", TRUE, FALSE, SCALE_FIX, 0, ANY, 3, BIT, ANY, ANY); - /* nullif, coalesce and casewhen don't have a backend implementation */ + /* nullif, coalesce, casewhen and case don't have a backend implementation */ sql_create_func(sa, "nullif", "", "", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); sql_create_func(sa, "coalesce", "", "", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); sql_create_func(sa, "casewhen", "", "", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); + sql_create_func(sa, "case", "", "", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); /* needed for count(*) and window functions without input col */ sql_create_func(sa, "star", "", "", TRUE, FALSE, SCALE_FIX, 0, ANY, 0); diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c --- a/sql/server/rel_dump.c +++ b/sql/server/rel_dump.c @@ -1151,9 +1151,9 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re set_zero_if_empty(exp); } else { int nops = list_length(exps); - if (!strcmp(tname, "sys") && (!strcmp(cname, "ifthenelse") || !strcmp(cname, "casewhen") || !strcmp(cname, "coalesce") || !strcmp(cname, "nullif"))) { + if (!strcmp(tname, "sys") && (!strcmp(cname, "case") || !strcmp(cname, "casewhen") || !strcmp(cname, "coalesce") || !strcmp(cname, "nullif"))) { /* these functions are bound on a different way */ - if ((f = sql_find_func(sql, NULL, cname, !strcmp(cname, "ifthenelse") ? 3 : 2, F_FUNC, NULL))) { + if ((f = sql_find_func(sql, NULL, cname, 2, F_FUNC, NULL))) { if (!execute_priv(sql, f->func)) return sql_error(sql, -1, SQLSTATE(42000) "Function: no privilege to call function '%s%s%s %d'\n", tname ? tname : "", tname ? "." : "", cname, nops); sql_exp *res = exps->t->data; 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 @@ -7603,7 +7603,7 @@ static sql_exp * rel_simplify_predicates(visitor *v, sql_rel *rel, sql_exp *e, int depth) { (void)depth; - if (is_func(e->type) && list_length(e->l) == 3 && is_ifthenelse_func((sql_subfunc*)e->f)) { + if (is_func(e->type) && list_length(e->l) == 3 && is_case_func((sql_subfunc*)e->f) /*is_ifthenelse_func((sql_subfunc*)e->f)*/) { list *args = e->l; sql_exp *ie = args->h->data; @@ -7853,7 +7853,7 @@ split_exp(mvc *sql, sql_exp *e, sql_rel case e_func: if (!is_analytic(e) && !exp_has_sideeffect(e)) { sql_subfunc *f = e->f; - if (e->type == e_func && !f->func->s && is_ifthenelse_func(f)) { + if (e->type == e_func && !f->func->s && is_caselike_func(f) /*is_ifthenelse_func(f)*/) { return e; } else { split_exps(sql, e->l, rel); @@ -7975,7 +7975,7 @@ select_split_exp(mvc *sql, sql_exp *e, s case e_func: if (!is_analytic(e) && !exp_has_sideeffect(e)) { sql_subfunc *f = e->f; - if (e->type == e_func && !f->func->s && is_ifthenelse_func(f)) + if (e->type == e_func && !f->func->s && is_caselike_func(f) /*is_ifthenelse_func(f)*/) return add_exp_too_project(sql, e, rel); } return e; diff --git a/sql/server/rel_rewriter.h b/sql/server/rel_rewriter.h --- a/sql/server/rel_rewriter.h +++ b/sql/server/rel_rewriter.h @@ -16,6 +16,11 @@ #define is_ifthenelse_func(sf) (strcmp((sf)->func->base.name, "ifthenelse") == 0) #define is_isnull_func(sf) (strcmp((sf)->func->base.name, "isnull") == 0) #define is_not_func(sf) (strcmp((sf)->func->base.name, "not") == 0) +#define is_caselike_func(sf) (strcmp((sf)->func->base.name, "case") == 0 || \ + strcmp((sf)->func->base.name, "casewhen") == 0 || \ + strcmp((sf)->func->base.name, "coalesce") == 0 || \ + strcmp((sf)->func->base.name, "nullif") == 0) +#define is_case_func(sf) (strcmp((sf)->func->base.name, "case") == 0) extern sql_exp *rewrite_simplify_exp(visitor *v, sql_rel *rel, sql_exp *e, int depth); extern sql_rel *rewrite_simplify(visitor *v, sql_rel *rel); 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 @@ -3954,11 +3954,9 @@ rel_case(sql_query *query, sql_rel **rel assert(res); list_append(args, res); list *types = sa_list(sql->sa); - if (!opt_cond_exp) - types = append(sa_list(sql->sa), condtype); types = append(append(types, restype), restype); - sql_subfunc *ifthenelse = find_func(sql, NULL, opt_cond_exp?"casewhen":"ifthenelse", list_length(types), F_FUNC, NULL, NULL); - res = exp_op(sql->sa, args, ifthenelse); + sql_subfunc *case_func = find_func(sql, NULL, opt_cond_exp?"casewhen":"case", list_length(types), F_FUNC, NULL, NULL); + res = exp_op(sql->sa, args, case_func); ((sql_subfunc*)res->f)->res->h->data = sql_create_subtype(sql->sa, restype->type, restype->digits, restype->scale); return res; } 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 @@ -3187,7 +3187,7 @@ rewrite_ifthenelse(visitor *v, sql_rel * sf = e->f; /* TODO also handle ifthenelse with more than 3 arguments */ - if (is_ifthenelse_func(sf) && !list_empty(e->l) && list_length(e->l) == 3 && rel_has_freevar(v->sql, rel)) { + if (is_case_func(sf) && !list_empty(e->l) && list_length(e->l) == 3 && rel_has_freevar(v->sql, rel)) { list *l = e->l; /* remove unecessary = true expressions under ifthenelse */ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list