Changeset: 3a4a78ae690a for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3a4a78ae690a Modified Files: sql/server/rel_optimizer.c Branch: default Log Message:
Not projected columns in grouping relation must be used in the new generated grouping relation, otherwise the results won't be the same diffs (135 lines): 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 @@ -4030,11 +4030,10 @@ rel_push_aggr_down(visitor *v, sql_rel * { if (rel->op == op_groupby && rel->l) { sql_rel *u = rel->l, *ou = u; - sql_rel *g = rel; sql_rel *ul = u->l; sql_rel *ur = u->r; node *n, *m; - list *lgbe = NULL, *rgbe = NULL, *gbe = NULL, *exps = NULL; + list *lgbe = NULL, *rgbe = NULL, *gbe = NULL, *exps = NULL, *others = NULL; if (u->op == op_project) u = u->l; @@ -4050,7 +4049,7 @@ rel_push_aggr_down(visitor *v, sql_rel * return rel; /* distinct should be done over the full result */ - for (n = g->exps->h; n; n = n->next) { + for (n = rel->exps->h; n; n = n->next) { sql_exp *e = n->data; sql_subfunc *af = e->f; @@ -4068,11 +4067,9 @@ rel_push_aggr_down(visitor *v, sql_rel * ul = rel_dup(ul); ur = rel_dup(ur); if (!is_project(ul->op)) - ul = rel_project(v->sql->sa, ul, - rel_projections(v->sql, ul, NULL, 1, 1)); + ul = rel_project(v->sql->sa, ul, rel_projections(v->sql, ul, NULL, 1, 1)); if (!is_project(ur->op)) - ur = rel_project(v->sql->sa, ur, - rel_projections(v->sql, ur, NULL, 1, 1)); + ur = rel_project(v->sql->sa, ur, rel_projections(v->sql, ur, NULL, 1, 1)); rel_rename_exps(v->sql, u->exps, ul->exps); rel_rename_exps(v->sql, u->exps, ur->exps); if (u != ou) { @@ -4084,29 +4081,49 @@ rel_push_aggr_down(visitor *v, sql_rel * rel_rename_exps(v->sql, ou->exps, ur->exps); } - if (g->r && list_length(g->r) > 0) { - list *gbe = g->r; - - lgbe = exps_copy(v->sql, gbe); - rgbe = exps_copy(v->sql, gbe); - } + if (!list_empty(rel->r)) { + list *ogbe = rel->r; + + lgbe = exps_copy(v->sql, ogbe); + rgbe = exps_copy(v->sql, ogbe); + gbe = new_exp_list(v->sql->sa); + others = new_exp_list(v->sql->sa); + for (n = ogbe->h; n; n = n->next) { + sql_exp *e = n->data, *ne; + + /* all grouping columns are required to the sum, otherwise the grouping column will different, thus giving a different result */ + ne = exps_uses_exp(rel->exps, e); + if (!ne) { + ne = exp_ref(v->sql, e); + list_append(others, ne); + } else { + ne = list_find_exp(rel->exps, ne); + assert(ne); + ne = exp_ref(v->sql, ne); + } + append(gbe, ne); + } + } + ul = rel_groupby(v->sql, ul, NULL); ul->r = lgbe; - ul->nrcols = g->nrcols; - ul->card = g->card; - ul->exps = exps_copy(v->sql, g->exps); + ul->nrcols = rel->nrcols; + ul->card = rel->card; + ul->exps = list_empty(others) ? exps_copy(v->sql, rel->exps) : list_merge(exps_copy(v->sql, others), exps_copy(v->sql, rel->exps), (fdup) NULL); ul->nrcols = list_length(ul->exps); ur = rel_groupby(v->sql, ur, NULL); ur->r = rgbe; - ur->nrcols = g->nrcols; - ur->card = g->card; - ur->exps = exps_copy(v->sql, g->exps); + ur->nrcols = rel->nrcols; + ur->card = rel->card; + ur->exps = list_empty(others) ? exps_copy(v->sql, rel->exps) : list_merge(exps_copy(v->sql, others), exps_copy(v->sql, rel->exps), (fdup) NULL); ur->nrcols = list_length(ur->exps); + rel->exps = list_empty(others) ? rel->exps : list_merge(others, rel->exps, (fdup) NULL); + /* group by on primary keys which define the partioning scheme * don't need a finalizing group by */ - /* how to check if a partion is based on some primary key ? + /* how to check if a partition is based on some primary key ? * */ if (rel->r && list_length(rel->r)) { node *n; @@ -4122,8 +4139,7 @@ rel_push_aggr_down(visitor *v, sql_rel * sql_table *mt = (bt)?bt->r:NULL; if (c && mt && list_find(c->t->pkey->k.columns, c, cmp) != NULL) { v->changes++; - return rel_inplace_setop(v->sql, rel, ul, ur, op_union, - rel_projections(v->sql, rel, NULL, 1, 1)); + return rel_inplace_setop(v->sql, rel, ul, ur, op_union, rel_projections(v->sql, rel, NULL, 1, 1)); } } } @@ -4133,22 +4149,6 @@ rel_push_aggr_down(visitor *v, sql_rel * rel_setop_set_exps(v->sql, u, rel_projections(v->sql, ul, NULL, 1, 1)); set_processed(u); - if (rel->r) { - list *ogbe = rel->r; - - gbe = new_exp_list(v->sql->sa); - for (n = ogbe->h; n; n = n->next) { - sql_exp *e = n->data, *ne; - - ne = exps_uses_exp( rel->exps, e); - if (!ne) - continue; - ne = list_find_exp( u->exps, ne); - assert(ne); - ne = exp_ref(v->sql, ne); - append(gbe, ne); - } - } exps = new_exp_list(v->sql->sa); for (n = u->exps->h, m = rel->exps->h; n && m; n = n->next, m = m->next) { sql_exp *ne, *e = n->data, *oa = m->data; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list