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 -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org