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

Reply via email to