Changeset: 6b71caf91f34 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/6b71caf91f34
Modified Files:
        monetdb5/modules/kernel/aggr.c
        monetdb5/optimizer/opt_mergetable.c
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
        sql/backends/monet5/sql_subquery.c
Branch: pushcands
Log Message:

more push down of candidates, into slice and firstn.


diffs (truncated from 361 to 300 lines):

diff --git a/monetdb5/modules/kernel/aggr.c b/monetdb5/modules/kernel/aggr.c
--- a/monetdb5/modules/kernel/aggr.c
+++ b/monetdb5/modules/kernel/aggr.c
@@ -42,7 +42,7 @@ AGGRgrouped(bat *retval1, bat *retval2, 
        if (b == NULL ||
                (gid != NULL && g == NULL) ||
                (eid != NULL && e == NULL) ||
-               (sid != NULL && s == NULL) ||
+               (sid != NULL && !is_bat_nil(*sid) && s == NULL) ||
                (quantile != NULL && q == NULL)) {
                if (b)
                        BBPunfix(b->batCacheid);
@@ -1004,7 +1004,8 @@ AGGRgroup_str_concat(bat *retval1, const
        sep = sepid ? BATdescriptor(*sepid) : NULL;
 
        if (b == NULL || (gid != NULL && g == NULL) || (eid != NULL && e == 
NULL) ||
-               (sid != NULL && s == NULL) || (sepid != NULL && sep == NULL)) {
+               (sid != NULL && !is_bat_nil(*sid) && s == NULL) ||
+               (sepid != NULL && sep == NULL)) {
                if (b)
                        BBPunfix(b->batCacheid);
                if (g)
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
@@ -1869,6 +1869,8 @@ mat_topn(MalBlkPtr mb, InstrPtr p, matli
                        if (ml->v[m].type != mat_tpn || is_slice)
                                getArg(q,1) = getArg(r,0);
                        pushInstruction(mb,q);
+
+                       ml->v[piv].pushed = 1;
                }
 
                ml->v[piv].type = mat_slc;
@@ -2332,7 +2334,7 @@ OPTmergetableImplementation(Client cntxt
                if (match == 1 && getModuleId(p) == algebraRef &&
                    getFunctionId(p) == projectRef &&
                   (m=is_a_mat(getArg(p,1), &ml)) >= 0 &&
-                  (ml.v[m].type == mat_ext)) {
+                  (ml.v[m].type == mat_ext || ml.v[m].type == mat_slc)) {
                        assert(ml.v[m].pushed);
                        cp = copyInstruction(p);
                        if(!cp) {
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
@@ -1455,7 +1455,7 @@ exp_bin(backend *be, sql_exp *e, rel_bin
                        }
                }
                if (right)
-                       s = stmt_aggr(be, as, left->cand, input_group, 
is_right_groupby ? right->ext : NULL, a, 1, need_no_nil(e) /* ignore nil*/, 
!zero_if_empty(e));
+                       s = stmt_aggr(be, as, 
!need_distinct(e)?left->cand:NULL, input_group, is_right_groupby ? right->ext : 
NULL, a, 1, need_no_nil(e) /* ignore nil*/, !zero_if_empty(e));
                else
                        s = stmt_aggr(be, as, left?left->cand:NULL, NULL, NULL, 
a, 1, need_no_nil(e) /* ignore nil*/, !zero_if_empty(e));
                if (find_prop(e->p, PROP_COUNT)) /* propagate count == 0 ipv 
NULL in outer joins */
@@ -3539,11 +3539,6 @@ rel2bin_project(backend *be, sql_rel *re
                sub = used_cands(sub);
                psub = used_cands(psub);
        }
-       if (psub->cand && rel->r) { /* for now we first handle the candidates */
-               if (sub)
-                       sub = subrel_project(be, sub, refs, rel, false);
-               psub = subrel_project(be, psub, refs, rel, false);
-       }
        pl = psub->cols;
        stmt_set_nrcols(psub);
 
@@ -3570,9 +3565,9 @@ rel2bin_project(backend *be, sql_rel *re
                                continue;
                        orderbycolstmt = column(be, orderbycolstmt);
                        if (!limit) {   /* topn based on a single column */
-                               limit = stmt_limit(be, orderbycolstmt, NULL, 
NULL, stmt_atom_lng(be, 0), l, distinct, is_ascending(orderbycole), 
nulls_last(orderbycole), last, 1);
+                               limit = stmt_limit(be, orderbycolstmt, 
sub->cand, NULL, stmt_atom_lng(be, 0), l, distinct, is_ascending(orderbycole), 
nulls_last(orderbycole), last, true, false);
                        } else {        /* topn based on 2 columns */
-                               limit = stmt_limit(be, orderbycolstmt, lpiv, 
lgid, stmt_atom_lng(be, 0), l, distinct, is_ascending(orderbycole), 
nulls_last(orderbycole), last, 1);
+                               limit = stmt_limit(be, orderbycolstmt, lpiv, 
lgid, stmt_atom_lng(be, 0), l, distinct, is_ascending(orderbycole), 
nulls_last(orderbycole), last, true, false);
                        }
                        if (!limit)
                                return NULL;
@@ -3587,6 +3582,7 @@ rel2bin_project(backend *be, sql_rel *re
                for ( n=pl->h ; n; n = n->next)
                        list_append(npl, stmt_project(be, limit, column(be, 
n->data)));
                psub->cols = npl;
+               psub->cand = NULL;
                stmt_set_nrcols(psub);
 
                /* also rebuild sub as multiple orderby expressions may use the 
sub table (ie aren't part of the result columns) */
@@ -3596,6 +3592,7 @@ rel2bin_project(backend *be, sql_rel *re
                        list_append(npl, stmt_project(be, limit, column(be, 
n->data)));
                }
                sub->cols = npl;
+               sub->cand = NULL;
                stmt_set_nrcols(sub);
        }
        if (need_distinct(rel)) {
@@ -3616,6 +3613,9 @@ rel2bin_project(backend *be, sql_rel *re
                list *oexps = rel->r;
                stmt *orderby_ids = NULL, *orderby_grp = NULL;
 
+               /* TODO push cands into sort - project */
+               sub = subrel_project(be, sub, refs, rel, false);
+               psub = subrel_project(be, psub, refs, rel, false);
                for (en = oexps->h; en; en = en->next) {
                        stmt *orderby = NULL;
                        sql_exp *orderbycole = en->data;
@@ -3819,7 +3819,6 @@ rel2bin_topn(backend *be, sql_rel *rel, 
        } else {
                sub = subrel_bin(be, rl, refs);
        }
-       sub = subrel_project(be, sub, refs, rl, false);
        if (!sub)
                return NULL;
 
@@ -3830,7 +3829,6 @@ rel2bin_topn(backend *be, sql_rel *rel, 
                stmt *limit = NULL, *sc = sub->cols->h->data;
                const char *cname = column_name(sql->sa, sc);
                const char *tname = table_name(sql->sa, sc);
-               list *newl = sa_list(sql->sa);
                int oldvtop = be->mb->vtop, oldstop = be->mb->stop, oldvid = 
be->mb->vid;
 
                if (le)
@@ -3852,20 +3850,15 @@ rel2bin_topn(backend *be, sql_rel *rel, 
                if (!l || !o)
                        return NULL;
 
-               sc = column(be, sc);
-               limit = stmt_limit(be, stmt_alias(be, sc, tname, cname), NULL, 
NULL, o, l, 0,0,0,0,0);
-
-               for (node *n = sub->cols->h ; n; n = n->next) {
-                       stmt *sc = n->data;
-                       const char *cname = column_name(sql->sa, sc);
-                       const char *tname = table_name(sql->sa, sc);
-
+               if (sub->cand) {
+                       limit = stmt_limit(be, sub->cand, NULL, NULL, o, l, 
0,0,0,0,false, true);
+               } else {
                        sc = column(be, sc);
-                       sc = stmt_project(be, limit, sc);
-                       list_append(newl, stmt_alias(be, sc, tname, cname));
-               }
-               sub->cols = newl;
-               stmt_set_nrcols(sub);
+                       limit = stmt_limit(be, stmt_alias(be, sc, tname, 
cname), NULL, NULL, o, l, 0,0,0,0,false, false);
+               }
+               /* Now we project, limit early reduces data access */
+               sub = create_rel_bin_stmt(be->mvc->sa, rel, sub->cols, limit);
+               sub = subrel_project(be, sub, refs, rl, false);
        }
        return sub;
 }
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
@@ -1060,7 +1060,7 @@ stmt_result(backend *be, stmt *s, int nr
 
 /* limit maybe atom nil */
 stmt *
-stmt_limit(backend *be, stmt *col, stmt *piv, stmt *gid, stmt *offset, stmt 
*limit, int distinct, int dir, int nullslast, int last, int order)
+stmt_limit(backend *be, stmt *col /* or cands */, stmt *piv, stmt *gid, stmt 
*offset, stmt *limit, int distinct, int dir, int nullslast, int last, bool 
order, bool col_is_cand)
 {
        MalBlkPtr mb = be->mb;
        InstrPtr q = NULL;
@@ -1068,7 +1068,7 @@ stmt_limit(backend *be, stmt *col, stmt 
 
        if (col->nr < 0 || offset->nr < 0 || limit->nr < 0)
                return NULL;
-       if (piv && (piv->nr < 0 || gid->nr < 0))
+       if (gid && (piv->nr < 0 || gid->nr < 0))
                return NULL;
 
        c = (col) ? col->nr : 0;
@@ -1146,7 +1146,7 @@ stmt_limit(backend *be, stmt *col, stmt 
                        return NULL;
                len = getDestVar(q);
 
-               q = newStmt(mb, algebraRef, subsliceRef);
+               q = newStmt(mb, algebraRef, col_is_cand?sliceRef:subsliceRef);
                q = pushArgument(mb, q, c);
                q = pushArgument(mb, q, offset->nr);
                q = pushArgument(mb, q, len);
@@ -1164,7 +1164,7 @@ stmt_limit(backend *be, stmt *col, stmt 
                l = getDestVar(q);
        }
 
-       stmt *ns = stmt_create(be->mvc->sa, piv?st_limit2:st_limit);
+       stmt *ns = stmt_create(be->mvc->sa, gid?st_limit2:st_limit);
        if (ns == NULL) {
                freeInstruction(q);
                return NULL;
@@ -3514,7 +3514,7 @@ stmt_func(backend *be, stmt *ops, stmt *
 }
 
 stmt *
-stmt_aggr(backend *be, stmt *op1, stmt *op1_cand, stmt *grp, stmt *ext, 
sql_subfunc *op, int reduce, int no_nil, int nil_if_empty)
+stmt_aggr(backend *be, stmt *op1, stmt *cand, stmt *grp, stmt *ext, 
sql_subfunc *op, int reduce, int no_nil, int nil_if_empty)
 {
        MalBlkPtr mb = be->mb;
        InstrPtr q = NULL;
@@ -3525,6 +3525,9 @@ stmt_aggr(backend *be, stmt *op1, stmt *
        bool abort_on_error;
        int *stmt_nr = NULL;
        int avg = 0, pushed = 0;
+       int can_push = 0;
+       int i;
+       node *n;
 
        if (op1->nr < 0)
                return NULL;
@@ -3533,6 +3536,16 @@ stmt_aggr(backend *be, stmt *op1, stmt *
        mod = op->func->mod;
        aggrfunc = op->func->imp;
 
+       can_push = (grp && strcmp(mod,"aggr")==0) ||
+                      strcmp(aggrfunc, "avg")==0 || strcmp(aggrfunc, 
"prod")==0 || strcmp(aggrfunc, "sum")==0 ||
+                  strcmp(aggrfunc, "min")==0 || strcmp(aggrfunc, "max")==0;
+       if (cand && !can_push) {
+               for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
+                       stmt *op = n->data;
+                       if (cand && op->cand != cand && op->nrcols)
+                               n->data = stmt_project_column_on_cand(be, cand, 
op);
+               }
+       }
        if (strcmp(aggrfunc, "avg") == 0)
                avg = 1;
        if (avg || strcmp(aggrfunc, "sum") == 0 || strcmp(aggrfunc, "prod") == 0
@@ -3601,13 +3614,7 @@ stmt_aggr(backend *be, stmt *op1, stmt *
 
        if (op1->type != st_list) {
                q = pushArgument(mb, q, op1->nr);
-               if (op1_cand && op1->cand == op1_cand)
-                       pushed = 1;
        } else {
-               int i;
-               node *n;
-
-               /* TODO check all pushed */
                for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
                        stmt *op = n->data;
 
@@ -3615,17 +3622,28 @@ stmt_aggr(backend *be, stmt *op1, stmt *
                                q = pushArgument(mb, q, stmt_nr[i]);
                        else
                                q = pushArgument(mb, q, op->nr);
-                       if (op1_cand && op->cand == op1_cand && op->nrcols)
-                               pushed = 1;
                }
        }
        if (grp) {
                q = pushArgument(mb, q, grp->nr);
                q = pushArgument(mb, q, ext->nr);
-               /* push candidates */
-               if (op1_cand && !pushed)
-                       q = pushArgument(mb, q, op1_cand->nr);
-               else if (avg)
+       }
+       if (can_push && cand) { /* properly push candidates when needed */
+               for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
+                       stmt *op = n->data;
+
+                       if (op->nrcols) {
+                               if (op->cand != cand)
+                                       q = pushArgument(mb, q, cand->nr);
+                               else
+                                       q = pushNil(mb, q, TYPE_bat);
+                       }
+               }
+               pushed = 1;
+       }
+       if (grp) {
+               /* avg api needs nil candidates when we don't push it */
+               if (!pushed && avg)
                        q = pushNil(mb, q, TYPE_bat);
                if (q == NULL)
                        return NULL;
diff --git a/sql/backends/monet5/sql_statement.h 
b/sql/backends/monet5/sql_statement.h
--- a/sql/backends/monet5/sql_statement.h
+++ b/sql/backends/monet5/sql_statement.h
@@ -244,7 +244,7 @@ extern stmt *stmt_result(backend *be, st
  * last:     intermediate step or last step
  * order:    is order important or not (firstn vs slice)
  */
-extern stmt *stmt_limit(backend *sa, stmt *c, stmt *piv, stmt *gid, stmt 
*offset, stmt *limit, int distinct, int dir, int nullslast, int last, int 
order);
+extern stmt *stmt_limit(backend *sa, stmt *c /* or cand */, stmt *piv, stmt 
*gid, stmt *offset, stmt *limit, int distinct, int dir, int nullslast, int 
last, bool order, bool col_is_cand);
 extern stmt *stmt_sample(backend *be, stmt *s, stmt *sample, stmt *seed);
 extern stmt *stmt_order(backend *be, stmt *s, int direction, int nullslast);
 extern stmt *stmt_reorder(backend *be, stmt *s, int direction, int nullslast, 
stmt *orderby_ids, stmt *orderby_grp);
diff --git a/sql/backends/monet5/sql_subquery.c 
b/sql/backends/monet5/sql_subquery.c
--- a/sql/backends/monet5/sql_subquery.c
+++ b/sql/backends/monet5/sql_subquery.c
@@ -240,7 +240,7 @@ SQLall_grp(Client cntxt, MalBlkPtr mb, M
        if (sp)
                s = BATdescriptor(*sp);
 
-       if (!l || !g || !e || (sp && !s)) {
+       if (!l || !g || !e || (sp && !is_bat_nil(*sp) && !s)) {
                if (l)
                        BBPunfix(l->batCacheid);
                if (g)
@@ -353,7 +353,7 @@ SQLnil_grp(Client cntxt, MalBlkPtr mb, M
        if (sp)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to