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