Changeset: fbc32c87feb1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/fbc32c87feb1
Modified Files:
clients/Tests/MAL-signatures-hge.test
clients/Tests/MAL-signatures.test
sql/backends/monet5/rel_bin.c
Branch: groupjoin
Log Message:
fixed antijoin, handle or's again
diffs (240 lines):
diff --git a/clients/Tests/MAL-signatures-hge.test
b/clients/Tests/MAL-signatures-hge.test
--- a/clients/Tests/MAL-signatures-hge.test
+++ b/clients/Tests/MAL-signatures-hge.test
@@ -3499,6 +3499,11 @@ command algebra.markjoin(X_0:bat[:any_1]
ALGmarkjoin;
Left mark join with candidate lists, produces left output and mark flag;
algebra
+markselect
+command algebra.markselect(X_0:bat[:oid], X_1:bat[:bit], X_2:bat[:any_1],
X_3:bat[:any_1], X_4:bit) (X_5:bat[:oid], X_6:bat[:bit])
+ALGmarkselect;
+Group on group-ids, return aggregated anyequal or allnotequal
+algebra
not_like
command algebra.not_like(X_0:str, X_1:str, X_2:str, X_3:bit):bit
PCREnotlike;
@@ -3519,6 +3524,11 @@ command algebra.outerjoin(X_0:bat[:any_1
ALGouterjoin;
Left outer join with candidate lists
algebra
+outerselect
+command algebra.outerselect(X_0:bat[:oid], X_1:bat[:bit], X_2:bat[:bit])
(X_3:bat[:oid], X_4:bat[:bit])
+ALGouterselect;
+Per input lid return atleast one row, if none of the predicates (p) hold,
return a nil, else 'all' true cases.
+algebra
project
pattern algebra.project(X_0:bat[:any_1], X_1:any_3):bat[:any_3]
ALGprojecttail;
diff --git a/clients/Tests/MAL-signatures.test
b/clients/Tests/MAL-signatures.test
--- a/clients/Tests/MAL-signatures.test
+++ b/clients/Tests/MAL-signatures.test
@@ -2934,6 +2934,11 @@ command algebra.markjoin(X_0:bat[:any_1]
ALGmarkjoin;
Left mark join with candidate lists, produces left output and mark flag;
algebra
+markselect
+command algebra.markselect(X_0:bat[:oid], X_1:bat[:bit], X_2:bat[:any_1],
X_3:bat[:any_1], X_4:bit) (X_5:bat[:oid], X_6:bat[:bit])
+ALGmarkselect;
+Group on group-ids, return aggregated anyequal or allnotequal
+algebra
not_like
command algebra.not_like(X_0:str, X_1:str, X_2:str, X_3:bit):bit
PCREnotlike;
@@ -2954,6 +2959,11 @@ command algebra.outerjoin(X_0:bat[:any_1
ALGouterjoin;
Left outer join with candidate lists
algebra
+outerselect
+command algebra.outerselect(X_0:bat[:oid], X_1:bat[:bit], X_2:bat[:bit])
(X_3:bat[:oid], X_4:bat[:bit])
+ALGouterselect;
+Per input lid return atleast one row, if none of the predicates (p) hold,
return a nil, else 'all' true cases.
+algebra
project
pattern algebra.project(X_0:bat[:any_1], X_1:any_3):bat[:any_3]
ALGprojecttail;
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
@@ -622,11 +622,15 @@ 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, depth,
reduce, push);
+ s = exp_bin(be, c, left, right, grp, ext, cnt, reduce?sin:NULL,
depth, reduce, push);
if (!s)
return s;
- if (!sin && sel1 && sel1->nrcols == 0 && s->nrcols == 0) {
+ if (!reduce && sin) {
+ sql_subfunc *f = sql_bind_func(be->mvc, "sys",
anti?"or":"and", bt, bt, F_FUNC, true);
+ assert(f);
+ s = stmt_binop(be, sin, s, NULL, f);
+ } else if (!sin && sel1 && sel1->nrcols == 0 && s->nrcols == 0)
{
sql_subfunc *f = sql_bind_func(be->mvc, "sys",
anti?"or":"and", bt, bt, F_FUNC, true);
assert(f);
s = stmt_binop(be, sel1, s, sin, f);
@@ -649,11 +653,15 @@ 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, depth,
reduce, push);
+ s = exp_bin(be, c, left, right, grp, ext, cnt, reduce?sin:NULL,
depth, reduce, push);
if (!s)
return s;
- if (!sin && sel2 && sel2->nrcols == 0 && s->nrcols == 0) {
+ if (!reduce && sin) {
+ sql_subfunc *f = sql_bind_func(be->mvc, "sys",
anti?"or":"and", bt, bt, F_FUNC, true);
+ assert(f);
+ s = stmt_binop(be, sin, s, NULL, f);
+ } else if (!sin && sel2 && sel2->nrcols == 0 && s->nrcols == 0)
{
sql_subfunc *f = sql_bind_func(be->mvc, "sys",
anti?"or":"and", bt, bt, F_FUNC, true);
assert(f);
s = stmt_binop(be, sel2, s, sin, f);
@@ -685,6 +693,11 @@ exp_bin_or(backend *be, sql_exp *e, stmt
predicate = stmt_const(be, predicate, stmt_bool(be, 1));
sel2 = stmt_uselect(be, predicate, sel2, cmp_equal, NULL,
0/*anti*/, 0);
}
+ if (!reduce) {
+ sql_subfunc *f = sql_bind_func(be->mvc, "sys",
anti?"and":"or", bt, bt, F_FUNC, true);
+ assert(f);
+ return stmt_binop(be, sel1, sel2, NULL, f);
+ }
if (anti)
return stmt_project(be, stmt_tinter(be, sel1, sel2, false),
sel1);
return stmt_tunion(be, sel1, sel2);
@@ -3152,7 +3165,7 @@ rel2bin_antijoin(backend *be, sql_rel *r
mvc *sql = be->mvc;
list *l, *jexps = NULL, *sexps = NULL;
node *en = NULL, *n;
- stmt *left = NULL, *right = NULL, *join = NULL, *sel = NULL;
+ stmt *left = NULL, *right = NULL, *join = NULL, *sel = NULL, *sub =
NULL;
if (rel->l) /* first construct the left sub relation */
left = subrel_bin(be, rel->l, refs);
@@ -3219,67 +3232,59 @@ rel2bin_antijoin(backend *be, sql_rel *r
en = en->next;
}
if (en) {
- /* we do not project, as we need the left in original lenght
for the null check */
stmt *jl = stmt_result(be, join, 0);
stmt *jr = stmt_result(be, join, 1);
stmt *nulls = NULL;
- /* but we project before the select operation */
-
- if (li && stmt_has_null(li))
+
+ if (li && stmt_has_null(li)) {
nulls = stmt_selectnil(be, li);
+ }
+ /* construct relation */
+ list *nl = sa_list(sql->sa);
+ /* first project after equi-joins */
+ for (n = left->op4.lval->h; n; n = n->next) {
+ stmt *c = n->data;
+ const char *rnme = table_name(sql->sa, c);
+ const char *nme = column_name(sql->sa, c);
+ stmt *s = stmt_project(be, jl, column(be, c));
+
+ s = stmt_alias(be, s, rnme, nme);
+ list_append(nl, s);
+ }
+ for (n = right->op4.lval->h; n; n = n->next) {
+ stmt *c = n->data;
+ const char *rnme = table_name(sql->sa, c);
+ const char *nme = column_name(sql->sa, c);
+ stmt *s = stmt_project(be, jr, column(be, c));
+
+ s = stmt_alias(be, s, rnme, nme);
+ list_append(nl, s);
+ }
+ sub = stmt_list(be, nl);
+
+ /* continue with non equi-joins */
for (; en; en = en->next) {
- sql_exp *e = en->data;
- stmt *ls = exp_bin(be, e->l, left, NULL, NULL, NULL,
NULL, NULL, 1, 0, 0), *rs;
- bool ll = ls?true:false, rr = true;
- bool swap = false;
- assert(e->type == e_cmp);
-
- /* handle or exps */
- if (e->flag == cmp_or) {
- printf ("todo\n");
- continue;
+ stmt *s = exp_bin(be, en->data, sub, NULL, NULL, NULL,
NULL, NULL /* sel */, 0, 0/* just the project call not the select*/, 0);
+
+ /* ifthenelse if (not(predicate)) then false else true
(needed for antijoin) */
+ sql_subtype *bt = sql_bind_localtype("bit");
+ sql_subfunc *not = sql_bind_func(be->mvc, "sys", "not",
bt, NULL, F_FUNC, true);
+ s = stmt_unop(be, s, NULL, not);
+ s = sql_Nop_(be, "ifthenelse", s, stmt_bool(be, 0),
stmt_bool(be, 1), NULL);
+
+ if (s->nrcols == 0) {
+ stmt *l = bin_find_smallest_column(be, sub);
+ s = stmt_uselect(be, stmt_const(be, l, s),
stmt_bool(be, 1), cmp_equal, sel, 0, 0);
+ } else {
+ s = stmt_uselect(be, s, stmt_bool(be, 1),
cmp_equal, sel, 0, 0);
}
- if (!ls) {
- swap = true;
- ls = exp_bin(be, e->l, right, NULL, NULL, NULL,
NULL, NULL, 1, 0, 0);
- }
- if (!ls)
+ if (!s) {
+ assert(sql->session->status == -10); /* Stack
overflow errors shouldn't terminate the server */
return NULL;
-
- if (!(rs = exp_bin(be, e->r, left, NULL, NULL, NULL,
NULL, NULL, 1, 0, 0)))
- rr = false;
- if (!rs) {
- if (!(rs = exp_bin(be, e->r, right, NULL, NULL,
NULL, NULL, NULL, 1, 0, 0)))
- return NULL;
- rr = false;
}
- if (!rs)
- return NULL;
-
- if (swap) {
- stmt *t = ls;
- ls = rs;
- rs = t;
- bool tt = ll;
- ll = rr;
- rr = tt;
- }
- if (ls->nrcols == 0)
- ls = stmt_const(be,
bin_find_smallest_column(be, ll?left:right), ls);
- if (rs->nrcols == 0)
- rs = stmt_const(be,
bin_find_smallest_column(be, rr?left:right), rs);
-
- if (stmt_has_null(ls)) {
- stmt *nn = stmt_selectnil(be, ls);
- if (nulls)
- nulls = stmt_tunion(be, nulls, nn);
- else
- nulls = nn;
- }
- stmt *l = stmt_project(be, ll?jl:jr, ls);
- stmt *r = stmt_project(be, rr?jl:jr, rs);
- sel = stmt_uselect(be, l, r, e->flag, sel, 0, 0);
+
+ sel = s;
}
stmt *c = stmt_mirror(be, bin_find_smallest_column(be, left));
if (nulls) {
@@ -3287,11 +3292,13 @@ rel2bin_antijoin(backend *be, sql_rel *r
c = stmt_project(be, nonilcand, c);
}
if (join && sel) {
+ /* recreate join output */
jl = stmt_project(be, sel, jl);
join = stmt_tdiff(be, c, jl, NULL);
}
if (nulls)
join = stmt_project(be, join, c);
+
} else if (list_empty(jexps)) {
stmt *jl = stmt_result(be, join, 0);
stmt *c = stmt_mirror(be, bin_find_smallest_column(be, left));
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]