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

Reply via email to