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

Reply via email to