Changeset: c10635f623c2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c10635f623c2
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_statement.c
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        
sql/test/BugDay_2005-11-09_2.9.3/Tests/sql_server_crash.SF-1080024.stable.out
        
sql/test/BugTracker-2009/Tests/case_evaluates_all_branches.SF-2893484.stable.out
        
sql/test/BugTracker-2012/Tests/case_evaluated_too_early.Bug-3186.stable.out
        
sql/test/BugTracker-2019/Tests/duplicates-not-eliminated-long-CASE-stmt.Bug-6697.stable.out
        sql/test/BugTracker-2019/Tests/prepare-types.Bug-6724.stable.out
        sql/test/BugTracker/Tests/case_with_aggr.SF-1876779.stable.out
        sql/test/BugTracker/Tests/case_with_aggr.SF-1876779.stable.out.int128
        sql/test/SQLancer/Tests/sqlancer03.stable.err
        sql/test/Tests/coalesce.stable.out
        sql/test/remote/Tests/partition_elim.stable.out
Branch: default
Log Message:

implemented case/coalesce as var-arg virtual functions. Re-implemented the 
handling of those in
rel_bin


diffs (truncated from 2689 to 300 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
@@ -25,7 +25,7 @@
 
 #define OUTER_ZERO 64
 
-static stmt * exp_bin(backend *be, sql_exp *e, stmt *left, stmt *right, stmt 
*grp, stmt *ext, stmt *cnt, stmt *sel, stmt *cond, int depth, int reduce);
+static stmt * exp_bin(backend *be, sql_exp *e, stmt *left, stmt *right, stmt 
*grp, stmt *ext, stmt *cnt, stmt *sel, int depth, int reduce);
 static stmt * rel_bin(backend *be, sql_rel *rel);
 static stmt * subrel_bin(backend *be, sql_rel *rel, list *refs);
 
@@ -288,7 +288,7 @@ distinct_value_list(backend *be, list *v
        /* create bat append values */
        for (node *n = vals->h; n; n = n->next) {
                sql_exp *e = n->data;
-               stmt *i = exp_bin(be, e, NULL, NULL, NULL, NULL, NULL, NULL, 
NULL, 0, 0);
+               stmt *i = exp_bin(be, e, NULL, NULL, NULL, NULL, NULL, NULL, 0, 
0);
 
                if (exp_is_null(e))
                        *last_null_value = i;
@@ -366,7 +366,7 @@ handle_in_exps(backend *be, sql_exp *ce,
 {
        mvc *sql = be->mvc;
        node *n;
-       stmt *s = NULL, *c = exp_bin(be, ce, left, right, grp, ext, cnt, NULL, 
NULL, 0, 0);
+       stmt *s = NULL, *c = exp_bin(be, ce, left, right, grp, ext, cnt, NULL, 
0, 0);
 
        if(!c)
                return NULL;
@@ -384,7 +384,7 @@ handle_in_exps(backend *be, sql_exp *ce,
 
                for( n = nl->h; n; n = n->next) {
                        sql_exp *e = n->data;
-                       stmt *i = exp_bin(be, use_r?e->r:e, left, right, grp, 
ext, cnt, NULL, NULL, 0, 0);
+                       stmt *i = exp_bin(be, use_r?e->r:e, left, right, grp, 
ext, cnt, NULL, 0, 0);
                        if(!i)
                                return NULL;
 
@@ -406,7 +406,7 @@ handle_in_exps(backend *be, sql_exp *ce,
                        s = sel;
                for( n = nl->h; n; n = n->next) {
                        sql_exp *e = n->data;
-                       stmt *i = exp_bin(be, use_r?e->r:e, left, right, grp, 
ext, cnt, NULL, NULL, 0, 0);
+                       stmt *i = exp_bin(be, use_r?e->r:e, left, right, grp, 
ext, cnt, NULL, 0, 0);
                        if(!i)
                                return NULL;
 
@@ -484,7 +484,7 @@ value_list(backend *be, list *vals, stmt
        l = sa_list(be->mvc->sa);
        for (node *n = vals->h; n; n = n->next) {
                sql_exp *e = n->data;
-               stmt *i = exp_bin(be, e, left, NULL, NULL, NULL, NULL, sel, 
NULL, 0, 0);
+               stmt *i = exp_bin(be, e, left, NULL, NULL, NULL, NULL, sel, 0, 
0);
 
                if (!i)
                        return NULL;
@@ -505,7 +505,7 @@ exp_list(backend *be, list *exps, stmt *
 
        for( n = exps->h; n; n = n->next) {
                sql_exp *e = n->data;
-               stmt *i = exp_bin(be, e, l, r, grp, ext, cnt, sel, NULL, 0, 0);
+               stmt *i = exp_bin(be, e, l, r, grp, ext, cnt, sel, 0, 0);
                if(!i)
                        return NULL;
 
@@ -552,7 +552,7 @@ exp_bin_or(backend *be, sql_exp *e, stmt
                /* propagate the anti flag */
                if (anti)
                        set_anti(c);
-               s = exp_bin(be, c, left, right, grp, ext, cnt, sin, NULL, 
depth, reduce);
+               s = exp_bin(be, c, left, right, grp, ext, cnt, sin, depth, 
reduce);
                if (!s)
                        return s;
 
@@ -579,7 +579,7 @@ exp_bin_or(backend *be, sql_exp *e, stmt
                /* propagate the anti flag */
                if (anti)
                        set_anti(c);
-               s = exp_bin(be, c, left, right, grp, ext, cnt, sin, NULL, 
depth, reduce);
+               s = exp_bin(be, c, left, right, grp, ext, cnt, sin, depth, 
reduce);
                if (!s)
                        return s;
 
@@ -620,8 +620,219 @@ exp_bin_or(backend *be, sql_exp *e, stmt
        return stmt_tunion(be, sel1, sel2);
 }
 
+static stmt *
+exp2bin_case(backend *be, sql_exp *fe, stmt *left, stmt *right, stmt *isel, 
int depth)
+{
+       stmt *res = NULL, *sel = NULL, *ncond = NULL, *ocond = NULL, *cond = 
NULL;
+       int next_cond = 1, single_value = (fe->card <= CARD_ATOM && (!left || 
!left->nrcols));
+       char name[16], *nme = NULL;
+       sql_subtype *bt = sql_bind_localtype("bit");
+       sql_subfunc *not = sql_bind_func(be->mvc->sa, be->mvc->session->schema, 
"not", bt, NULL, F_FUNC);
+       sql_subfunc *or = sql_bind_func(be->mvc->sa, NULL, "or", bt, bt, 
F_FUNC);
+       sql_subfunc *and = sql_bind_func(be->mvc->sa, be->mvc->session->schema, 
"and", bt, bt, F_FUNC);
+       list *exps = fe->l;
+
+       if (single_value) {
+               /* var_x = nil; */
+               nme = number2name(name, sizeof(name), ++be->mvc->label);
+               (void)stmt_var(be, NULL, nme, exp_subtype(fe), 1, 2);
+       }
+
+       for (node *en = exps->h; en; en = en->next) {
+               sql_exp *e = en->data;
+
+               next_cond = next_cond && en->next; /* last else is only a value 
*/
+
+               stmt *es = exp_bin(be, e, left, right, NULL, NULL, NULL, 
!next_cond?sel:NULL, depth+1, 0);
+
+               if (!es)
+                       return NULL;
+               if (!single_value) {
+                       /* create result */
+                       if (!res) {
+                               stmt *l = bin_first_column(be, left);
+                               res = stmt_const(be, l, stmt_atom(be, 
atom_general(be->mvc->sa, exp_subtype(fe), NULL)));
+                       } else if (res && !next_cond) { /* use result too 
update column */
+                               stmt *val = es, *pos = sel;
+
+                               if (val->nrcols == 0)
+                                       val = stmt_const(be, pos, val);
+                               else if (val->cand != sel)
+                                       val = stmt_project(be, sel, val);
+                               res = stmt_replace(be, res, pos, val);
+
+                               assert(cond);
+
+                               cond = stmt_unop(be, cond, not);
+
+                               sql_subfunc *isnull = 
sql_bind_func(be->mvc->sa, be->mvc->session->schema, "isnull", bt, NULL, 
F_FUNC);
+                               cond = stmt_binop(be, cond, stmt_unop(be, cond, 
isnull), or);
+                               if (ocond)
+                                       cond = stmt_binop(be, ocond, cond, and);
+                               ocond = cond;
+                       }
+                       if ((next_cond || (en->next && !en->next->next)) && 
ncond) { /* else if / else */
+                               if (next_cond) {
+                                       ncond = stmt_binop(be, cond, es, and);
+                                       cond = es;
+                               } else {
+                                       ncond = cond;
+                               }
+                       } else if (next_cond && !ncond) {
+                               ncond = cond = es;
+                       }
+                       if (ncond && (next_cond || (en->next && 
!en->next->next))) {
+                               if (!ncond->nrcols)
+                                       ncond = stmt_const(be, 
bin_first_column(be, left), ncond);
+                               sel = stmt_uselect(be, ncond, stmt_bool(be, 1), 
cmp_equal, isel, 0/*anti*/, 0);
+                       }
+               } else {
+                       if (!res) {
+                               /* if_barrier ... */
+                               assert(next_cond);
+                               if (next_cond) {
+                                       if (cond) {
+                                               ncond = stmt_binop(be, cond, 
es, and);
+                                       } else {
+                                               ncond = es;
+                                       }
+                                       cond = es;
+                               }
+                       } else {
+                               /* var_x = s */
+                               (void)stmt_assign(be, NULL, nme, es, 2);
+                               /* endif_barrier */
+                               (void)stmt_control_end(be, res);
+                               res = NULL;
+
+                               if (en->next) {
+                                       cond = stmt_unop(be, cond, not);
+
+                                       sql_subfunc *isnull = 
sql_bind_func(be->mvc->sa, be->mvc->session->schema, "isnull", bt, NULL, 
F_FUNC);
+                                       cond = stmt_binop(be, cond, 
stmt_unop(be, cond, isnull), or);
+                                       if (ocond)
+                                               cond = stmt_binop(be, ocond, 
cond, and);
+                                       ocond = cond;
+                                       if (!en->next->next)
+                                               ncond = cond;
+                               }
+                       }
+                       if (ncond && (next_cond || (en->next && 
!en->next->next))) {
+                               /* if_barrier ... */
+                               res = stmt_cond(be, ncond, NULL, 0, 0);
+                       }
+               }
+               next_cond = !next_cond;
+       }
+       if (single_value)
+               return stmt_var(be, NULL, nme, exp_subtype(fe), 0, 2);
+       return res;
+}
+
+static stmt*
+exp2bin_coalesce(backend *be, sql_exp *fe, stmt *left, stmt *right, stmt 
*isel, int depth)
+{
+       stmt *res = NULL, *sel = NULL, *osel = NULL, *ncond = NULL, *ocond = 
NULL;
+       int single_value = (fe->card <= CARD_ATOM);
+       char name[16], *nme = NULL;
+       sql_subtype *bt = sql_bind_localtype("bit");
+       sql_subfunc *and = sql_bind_func(be->mvc->sa, NULL, "and", bt, bt, 
F_FUNC);
+       sql_subfunc *not = sql_bind_func(be->mvc->sa, be->mvc->session->schema, 
"not", bt, NULL, F_FUNC);
+
+       if (single_value) {
+               /* var_x = nil; */
+               nme = number2name(name, sizeof(name), ++be->mvc->label);
+               (void)stmt_var(be, NULL, nme, exp_subtype(fe), 1, 2);
+       }
+
+       list *exps = fe->l;
+       osel = sel = isel;
+       for (node *en = exps->h; en; en = en->next) {
+               sql_exp *e = en->data;
+               stmt *es = exp_bin(be, e, left, right, NULL, NULL, NULL, sel, 
depth+1, 0);
+
+               if (!es)
+                       return NULL;
+               /* create result */
+               if (!single_value) {
+                       if (!res) {
+                               stmt *l = bin_first_column(be, left);
+                               res = stmt_const(be, l, stmt_atom(be, 
atom_general(be->mvc->sa, exp_subtype(fe), NULL)));
+                       }
+                       if (res) {
+                               if (sel && es->cand != sel) {
+                                       assert(es->cand == NULL);
+                                       es = stmt_project(be, sel, es);
+                                       es->cand = sel;
+                               }
+                               stmt *val = es;
+                               stmt *pos = sel;
+
+                               if (en->next) {
+                                       sql_subfunc *a = 
sql_bind_func(be->mvc->sa, be->mvc->session->schema, "isnotnull", 
tail_type(es), NULL, F_FUNC);
+                                       ncond = stmt_unop(be, es, a);
+                                       if (ncond->nrcols == 0) {
+                                               stmt *l = bin_first_column(be, 
left);
+                                               if (sel && l)
+                                                       l = stmt_project(be, 
sel, l);
+                                               ncond = stmt_const(be, l, 
ncond);
+                                               if (sel)
+                                                       ncond->cand = sel;
+                                       }
+                                       stmt *s = stmt_uselect(be, ncond, 
stmt_bool(be, 1), cmp_equal, NULL, 0/*anti*/, 0);
+                                       val = stmt_project(be, s, es);
+                                       if (pos && ncond->cand == sel)
+                                               pos = sel = stmt_project(be, s, 
pos);
+                                       else
+                                               pos = sel = s;
+                                       val->cand = pos;
+                               }
+                               if (val->nrcols == 0)
+                                       val = stmt_const(be, pos, val);
+                               else if (val->cand != sel)
+                                       val = stmt_project(be, sel, val);
+                               res = stmt_replace(be, res, pos, val);
+                       }
+                       if (en->next) { /* handled then part */
+                               stmt *s = stmt_uselect(be, ncond, stmt_bool(be, 
1), cmp_equal, NULL, 1/*anti*/, 0);
+                               if (osel && ncond->cand == osel)
+                                       osel = sel = stmt_project(be, s, osel);
+                               else
+                                       osel = sel = s;
+                       }
+               } else {
+                       stmt *cond = ocond;
+                       if (en->next) {
+                               sql_subfunc *a = sql_bind_func(be->mvc->sa, 
be->mvc->session->schema, "isnotnull", tail_type(es), NULL, F_FUNC);
+                               ncond = stmt_unop(be, es, a);
+
+                               if (ocond)
+                                       cond = stmt_binop(be, ocond, ncond, 
and);
+                               else
+                                       cond = ncond;
+                       }
+
+                       /* if_barrier ... */
+                       stmt *b = stmt_cond(be, cond, NULL, 0, 0);
+                       /* var_x = s */
+                       (void)stmt_assign(be, NULL, nme, es, 2);
+                       /* endif_barrier */
+                       (void)stmt_control_end(be, b);
+
+                       cond = stmt_unop(be, ncond, not);
+                       if (ocond)
+                               ocond = stmt_binop(be, cond, ocond, and);
+                       else
+                               ocond = cond;
+               }
+       }
+       if (single_value)
+               return stmt_var(be, NULL, nme, exp_subtype(fe), 0, 2);
+       return res;
+}
+
 stmt *
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to