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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list