Changeset: cac3b978d415 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cac3b978d415
Modified Files:
monetdb5/optimizer/opt_mergetable.c
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql_statement.c
sql/backends/monet5/sql_statement.h
sql/test/BugTracker-2017/Tests/wrong_aggregation_count.Bug-6257.stable.out
Branch: Jun2020
Log Message:
make sure the joins with candidates can also be shared
diffs (truncated from 485 to 300 lines):
diff --git a/monetdb5/optimizer/opt_mergetable.c
b/monetdb5/optimizer/opt_mergetable.c
--- a/monetdb5/optimizer/opt_mergetable.c
+++ b/monetdb5/optimizer/opt_mergetable.c
@@ -87,6 +87,16 @@ nr_of_bats(MalBlkPtr mb, InstrPtr p)
return cnt;
}
+static int
+nr_of_nilbats(MalBlkPtr mb, InstrPtr p)
+{
+ int j,cnt=0;
+ for(j=p->retc; j<p->argc; j++)
+ if (getArgType(mb,p,j) == TYPE_bat)
+ cnt++;
+ return cnt;
+}
+
/* some mat's have intermediates (with intermediate result variables), therefor
* we pass the old output mat variable */
inline static int
@@ -796,7 +806,7 @@ mat_projection(MalBlkPtr mb, InstrPtr p,
}
static int
-mat_join2(MalBlkPtr mb, InstrPtr p, matlist_t *ml, int m, int n)
+mat_join2(MalBlkPtr mb, InstrPtr p, matlist_t *ml, int m, int n, int lc, int
rc)
{
int tpe = getArgType(mb,p, 0), j,k, nr = 1;
InstrPtr l = newInstruction(mb, matRef, packRef);
@@ -832,6 +842,10 @@ mat_join2(MalBlkPtr mb, InstrPtr p, matl
getArg(q,1) = newTmpVariable(mb, tpe);
getArg(q,2) = getArg(mat[m].mi,k);
getArg(q,3) = getArg(mat[n].mi,j);
+ if (lc>=0)
+ getArg(q,4) = getArg(mat[lc].mi,k);
+ if (rc>=0)
+ getArg(q,5) = getArg(mat[rc].mi,j);
pushInstruction(mb,q);
if(propagatePartnr(ml, getArg(mat[m].mi, k),
getArg(q,0), nr) ||
@@ -851,6 +865,7 @@ mat_join2(MalBlkPtr mb, InstrPtr p, matl
int mv = (m>=0)?m:n;
int av = (m<0);
int bv = (m>=0);
+ int mc = (lc>=0)?lc:rc;
for(k=1; k<mat[mv].mi->argc; k++) {
InstrPtr q = copyInstruction(p);
@@ -864,6 +879,8 @@ mat_join2(MalBlkPtr mb, InstrPtr p, matl
getArg(q,0) = newTmpVariable(mb, tpe);
getArg(q,1) = newTmpVariable(mb, tpe);
getArg(q,p->retc+av) = getArg(mat[mv].mi, k);
+ if (mc>=0)
+ getArg(q,p->retc+2+av) = getArg(mat[mc].mi, k);
pushInstruction(mb,q);
if(propagatePartnr(ml, getArg(mat[mv].mi, k),
getArg(q,av), k) ||
@@ -1985,6 +2002,7 @@ OPTmergetableImplementation(Client cntxt
for( i=0; i<oldtop; i++){
int bats = 0;
+ int nilbats = 0;
InstrPtr r, cp;
p = old[i];
@@ -2011,6 +2029,7 @@ OPTmergetableImplementation(Client cntxt
continue;
}
bats = nr_of_bats(mb, p);
+ nilbats = nr_of_nilbats(mb, p);
/* (l,r) Join (L, R, ..)
* 2 -> (l,r) equi/theta joins (l,r)
@@ -2018,11 +2037,13 @@ OPTmergetableImplementation(Client cntxt
* NxM -> (l,r) filter-joins (l1,..,ln,r1,..,rm)
*/
if (match > 0 && isMatJoinOp(p) &&
- p->argc >= 3 && p->retc == 2 && bats >= 2) {
- if (bats == 2) {
+ p->argc >= 5 && p->retc == 2 && bats+nilbats >= 4) {
+ if (bats+nilbats == 4) {
m = is_a_mat(getArg(p,p->retc), &ml);
n = is_a_mat(getArg(p,p->retc+1), &ml);
- if(mat_join2(mb, p, &ml, m, n)) {
+ o = is_a_mat(getArg(p,p->retc+2), &ml);
+ e = is_a_mat(getArg(p,p->retc+3), &ml);
+ if(mat_join2(mb, p, &ml, m, n, o, e)) {
msg =
createException(MAL,"optimizer.mergetable",SQLSTATE(HY013) MAL_MALLOC_FAIL);
goto cleanup;
}
@@ -2035,13 +2056,13 @@ OPTmergetableImplementation(Client cntxt
actions++;
continue;
}
- if (match > 0 && isMatLeftJoinOp(p) && p->argc >= 3 && p->retc
== 2 &&
- match == 1 && bats == 2) {
+ if (match > 0 && isMatLeftJoinOp(p) && p->argc >= 5 && p->retc
== 2 &&
+ (match == 1 || match == 2) && bats+nilbats ==
4) {
m = is_a_mat(getArg(p,p->retc), &ml);
- n = -1;
+ o = is_a_mat(getArg(p,p->retc+2), &ml);
- if (m >= 0) {
- if(mat_join2(mb, p, &ml, m, n)) {
+ if ((match == 1 && m >= 0) || (match == 2 && m >= 0 &&
o >= 0)) {
+ if(mat_join2(mb, p, &ml, m, -1, o, -1)) {
msg =
createException(MAL,"optimizer.mergetable",SQLSTATE(HY013) MAL_MALLOC_FAIL);
goto cleanup;
}
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
@@ -2467,9 +2467,7 @@ rel2bin_semijoin(backend *be, sql_rel *r
mvc *sql = be->mvc;
list *l;
node *en = NULL, *n;
- stmt *left = NULL, *right = NULL, *join = NULL, *jl, *jr, *c;
- int semi_used = 0;
- int semi_disabled = mvc_debug_on(sql, 2048);
+ stmt *left = NULL, *right = NULL, *join = NULL, *jl, *jr, *c, *lcand =
NULL;
if (rel->op == op_anti && !list_empty(rel->exps) &&
list_length(rel->exps) == 1 && ((sql_exp*)rel->exps->h->data)->flag ==
mark_notin)
return rel2bin_antijoin(be, rel, refs);
@@ -2487,63 +2485,42 @@ rel2bin_semijoin(backend *be, sql_rel *r
* first cheap join(s) (equality or idx)
* second selects/filters
*/
- if (!semi_disabled && rel->op != op_anti && rel->exps &&
list_length(rel->exps) == 1) {
- sql_exp *e = rel->exps->h->data;
-
- if (e->type == e_cmp && (e->flag == cmp_equal || e->flag ==
mark_in) && !e->anti && !e->f) {
- stmt *r, *l = exp_bin(be, e->l, left, NULL, NULL, NULL,
NULL, NULL);
- int swap = 0;
-
- if (!l) {
- swap = 1;
- l = exp_bin(be, e->l, right, NULL, NULL, NULL,
NULL, NULL);
- }
- r = exp_bin(be, e->r, left, right, NULL, NULL, NULL,
NULL);
-
- if (swap) {
- stmt *t = l;
- l = r;
- r = t;
- }
-
- if (!l || !r)
- return NULL;
- join = stmt_semijoin(be, column(be, l), column(be, r),
left->cand, right->cand, is_semantics(e));
- if (join)
- join = stmt_result(be, join, 0);
- if (!join)
- return NULL;
- semi_used = 1;
- }
- }
-
- if (!semi_used) {
- left = subrel_project(be, left, refs, rel->l);
- right = subrel_project(be, right, refs, rel->r);
- }
-
- if (!semi_used && rel->exps) {
+ if (!list_empty(rel->exps)) {
int idx = 0;
list *jexps = sa_list(sql->sa);
list *lje = sa_list(sql->sa);
list *rje = sa_list(sql->sa);
list *exps = sa_list(sql->sa);
+ int equality_only = 1;
/* get equi-joins/filters first */
if (list_length(rel->exps) > 1) {
for( en = rel->exps->h; en; en = en->next ) {
sql_exp *e = en->data;
- if (e->type == e_cmp && (e->flag == cmp_equal
|| e->flag == cmp_filter))
+ if (e->type == e_cmp && (e->flag == cmp_equal
|| e->flag == cmp_filter)) {
list_append(jexps, e);
+ equality_only &= (e->flag == cmp_equal);
+ }
}
for( en = rel->exps->h; en; en = en->next ) {
sql_exp *e = en->data;
- if (e->type != e_cmp || (e->flag != cmp_equal
&& e->flag != cmp_filter))
+ if (e->type != e_cmp || (e->flag != cmp_equal
&& e->flag != cmp_filter)) {
list_append(jexps, e);
+ equality_only &= (e->flag == mark_in ||
e->flag == mark_notin);
+ }
}
rel->exps = jexps;
+ } else {
+ sql_exp *e = rel->exps->h->data;
+ equality_only &= (e->type == e_cmp && (e->flag ==
cmp_equal || e->flag == mark_in || e->flag == mark_notin));
}
+ if (!equality_only || list_length(rel->exps) > 1) {
+ left = subrel_project(be, left, refs, rel->l);
+ equality_only = 0;
+ }
+ right = subrel_project(be, right, refs, rel->r);
+
for( en = rel->exps->h; en; en = en->next ) {
int join_idx = sql->opt_stats[0];
sql_exp *e = en->data;
@@ -2563,7 +2540,29 @@ rel2bin_semijoin(backend *be, sql_rel *r
(join && e->flag == cmp_filter)))
break;
- s = exp_bin(be, en->data, left, right, NULL, NULL,
NULL, NULL);
+ if (equality_only) {
+ stmt *r, *l = exp_bin(be, e->l, left, NULL,
NULL, NULL, NULL, NULL);
+ int swap = 0;
+
+ if (!l) {
+ swap = 1;
+ l = exp_bin(be, e->l, right, NULL,
NULL, NULL, NULL, NULL);
+ }
+ r = exp_bin(be, e->r, left, right, NULL, NULL,
NULL, NULL);
+
+ if (swap) {
+ stmt *t = l;
+ l = r;
+ r = t;
+ }
+
+ if (!l || !r)
+ return NULL;
+ s = stmt_join_cand(be, column(be, l),
column(be, r), left->cand, NULL/*right->cand*/, e->anti, e->flag,
is_semantics(e));
+ lcand = left->cand;
+ } else {
+ s = exp_bin(be, e, left, right, NULL, NULL,
NULL, NULL);
+ }
if (!s) {
assert(sql->session->status == -10); /* Stack
overflow errors shouldn't terminate the server */
return NULL;
@@ -2599,14 +2598,13 @@ rel2bin_semijoin(backend *be, sql_rel *r
stmt *r = bin_first_column(be, right);
join = stmt_join(be, l, r, 0, cmp_all, 0);
}
- } else if (!semi_used) {
+ } else {
stmt *l = bin_first_column(be, left);
stmt *r = bin_first_column(be, right);
join = stmt_join(be, l, r, 0, cmp_all, 0);
}
- if (!semi_used)
- jl = stmt_result(be, join, 0);
- if (!semi_used && en) {
+ jl = stmt_result(be, join, 0);
+ if (en) {
stmt *sub, *sel = NULL;
list *nl;
@@ -2656,15 +2654,16 @@ rel2bin_semijoin(backend *be, sql_rel *r
/* construct relation */
l = sa_list(sql->sa);
- if (!semi_used) {
- /* We did a full join, thats too much.
- Reduce this using difference and intersect */
- c = stmt_mirror(be, left->op4.lval->h->data);
- if (rel->op == op_anti) {
- join = stmt_tdiff(be, c, jl);
- } else {
+ /* We did a full join, thats too much.
+ Reduce this using difference and intersect */
+ c = stmt_mirror(be, left->op4.lval->h->data);
+ if (rel->op == op_anti) {
+ join = stmt_tdiff(be, c, jl);
+ } else {
+ if (lcand)
+ join = stmt_semijoin(be, c, jl, lcand,
NULL/*right->cand*/, 0);
+ else
join = stmt_tinter(be, c, jl);
- }
}
/* project all the left columns */
diff --git a/sql/backends/monet5/sql_statement.c
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -1898,7 +1898,7 @@ stmt_tinter(backend *be, stmt *op1, stmt
}
stmt *
-stmt_join(backend *be, stmt *op1, stmt *op2, int anti, comp_type cmptype, int
is_semantics)
+stmt_join_cand(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand,
int anti, comp_type cmptype, int is_semantics)
{
MalBlkPtr mb = be->mb;
InstrPtr q = NULL;
@@ -1922,8 +1922,14 @@ stmt_join(backend *be, stmt *op1, stmt *
q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
q = pushArgument(mb, q, op1->nr);
q = pushArgument(mb, q, op2->nr);
- q = pushNil(mb, q, TYPE_bat);
- q = pushNil(mb, q, TYPE_bat);
+ if (!lcand)
+ q = pushNil(mb, q, TYPE_bat);
+ else
+ q = pushArgument(mb, q, lcand->nr);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list