Changeset: 70aa9cfcdcb8 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=70aa9cfcdcb8
Modified Files:
monetdb5/optimizer/opt_mergetable.c
sql/server/rel_optimizer.c
Branch: default
Log Message:
merger
diffs (137 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
@@ -1294,7 +1294,7 @@ mat_pack_topn(MalBlkPtr mb, InstrPtr slc
for(k=1; k < mat[attr].mi->argc; k++) {
InstrPtr q = newInstruction(mb, ASSIGNsymbol);
setModuleId(q, algebraRef);
- setFunctionId(q, leftjoinRef);
+ setFunctionId(q, leftfetchjoinRef);
getArg(q, 0) = newTmpVariable(mb, tpe);
q = pushArgument(mb, q, getArg(slc, k));
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -4456,11 +4456,106 @@ rel_reduce_groupby_exps(int *changes, mv
*
* ie select a, count(distinct b) from c where ... groupby a;
* No other aggregations should be present
+ *
+ * Rewrite the more general case, good for parallel execution
+ *
+ * groupby(R) [e,f] [ aggr1 a distinct, aggr2 b distinct, aggr3 c, aggr4 d]
+ *
+ * into
+ *
+ * groupby(
+ * groupby(R) [e,f,a,b] [ a, b, aggr3 c, aggr4 d]
+ * ) [e,f]( aggr1 a distinct, aggr2 b distinct, aggr3_phase2 c, aggr4_phase2 d)
*/
static sql_rel *
+rel_groupby_distinct2(int *changes, mvc *sql, sql_rel *rel)
+{
+ list *ngbes = sa_list(sql->sa), *gbes, *naggrs = sa_list(sql->sa),
*aggrs = sa_list(sql->sa);
+ sql_rel *l;
+ node *n;
+
+ gbes = rel->r;
+ if (!gbes)
+ return rel;
+
+ /* check if each aggr is, rewritable (max,min,sum,count)
+ * and only has one argument */
+ for (n = gbes->h; n; n = n->next) {
+ sql_exp *e = n->data;
+ sql_subaggr *af = e->f;
+
+ if (e->type == e_aggr &&
+ (strcmp(af->aggr->base.name, "sum") &&
+ strcmp(af->aggr->base.name, "count") &&
+ strcmp(af->aggr->base.name, "min") &&
+ strcmp(af->aggr->base.name, "max")))
+ return rel;
+ }
+
+ for (n = gbes->h; n; n = n->next) {
+ sql_exp *e = n->data;
+
+ e = exp_column(sql->sa, exp_find_rel_name(e), exp_name(e),
exp_subtype(e), e->card, has_nil(e), is_intern(e));
+ append(ngbes, e);
+ }
+
+ /* 1 for each aggr(distinct v) add the attribute expression v to gbes
and aggrs list
+ * 2 for each aggr(z) add aggr_phase2('z') to the naggrs list
+ * 3 for each group by col, add also to the naggrs list
+ * */
+ for (n = rel->exps->h; n; n = n->next) {
+ sql_exp *e = n->data;
+
+ if (e->type == e_aggr && need_distinct(e)) { /* 1 */
+ /* need column expression */
+ list *args = e->l;
+ sql_exp *v = args->h->data;
+ append(gbes, v);
+ v = exp_column(sql->sa, exp_find_rel_name(v),
exp_name(v), exp_subtype(v), v->card, has_nil(v), is_intern(v));
+ append(aggrs, v);
+ v = exp_aggr1(sql->sa, v, e->f, need_distinct(e), 1,
e->card, 1);
+ exp_setname(sql->sa, v, exp_find_rel_name(e),
exp_name(e));
+ append(naggrs, v);
+ } else if (e->type == e_aggr && !need_distinct(e)) {
+ list *args = e->l;
+ sql_exp *v = args->h->data;
+ sql_subaggr *f = e->f;
+ int cnt = strcmp(f->aggr->base.name,"count")==0;
+ sql_subaggr *a = sql_bind_aggr(sql->sa,
sql->session->schema, (cnt)?"sum":f->aggr->base.name, exp_subtype(e));
+
+ append(aggrs, e);
+ v = exp_column(sql->sa, exp_find_rel_name(e),
exp_name(e), exp_subtype(e), e->card, has_nil(e), is_intern(e));
+ set_has_nil(v);
+ v = exp_aggr1(sql->sa, v, a, 0, 1, e->card, 1);
+ exp_setname(sql->sa, v, exp_find_rel_name(e),
exp_name(e));
+ append(naggrs, v);
+ } else { /* group by col */
+ if (list_find_exp(gbes, e)) { /* group by exp are
needed in the aggr list, simple (alias or project) expressions are just needed
in the result */
+ append(aggrs, e);
+
+ e = exp_column(sql->sa, exp_find_rel_name(e),
exp_name(e), exp_subtype(e), e->card, has_nil(e), is_intern(e));
+ }
+ append(naggrs, e);
+ }
+ }
+
+ l = rel->l = rel_groupby(sql, rel->l, gbes);
+ l->exps = aggrs;
+ rel->r = ngbes;
+ rel->exps = naggrs;
+ (*changes)++;
+ return rel;
+}
+
+static sql_rel *
rel_groupby_distinct(int *changes, mvc *sql, sql_rel *rel)
{
+ if (is_groupby(rel->op)) {
+ sql_rel *l = rel->l;
+ if (!l || is_groupby(l->op))
+ return rel;
+ }
if (is_groupby(rel->op) && rel->r && !rel_is_ref(rel)) {
node *n;
int nr = 0;
@@ -4475,10 +4570,12 @@ rel_groupby_distinct(int *changes, mvc *
nr++;
}
}
- if (nr != 1 || list_length(rel->r) + nr !=
list_length(rel->exps))
+ if (nr < 1 || distinct->type != e_aggr)
return rel;
+ if ((nr > 1 || list_length(rel->r) + nr !=
list_length(rel->exps)))
+ return rel_groupby_distinct2(changes, sql, rel);
arg = distinct->l;
- if (distinct->type != e_aggr || list_length(arg) != 1)
+ if (list_length(arg) != 1 || list_length(rel->r) + nr !=
list_length(rel->exps))
return rel;
darg = arg->h->data;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list