Changeset: b9c2bc990da3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b9c2bc990da3
Modified Files:
        sql/server/rel_optimize_proj.c
        sql/server/rel_rewriter.c
        sql/server/rel_statistics.c
Branch: default
Log Message:

improved rel_reduce_groupby_exps, iff column is unique skip other columns in 
same table.


diffs (121 lines):

diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c
--- a/sql/server/rel_optimize_proj.c
+++ b/sql/server/rel_optimize_proj.c
@@ -2330,13 +2330,16 @@ rel_reduce_groupby_exps(visitor *v, sql_
        global_props *gp = v->data;
 
        /* ukey + no null could also work and a single unique (base) column 
also reduces the group by exps */
-       if (gp->has_pkey && is_groupby(rel->op) && rel->r && !rel_is_ref(rel) 
&& list_length(gbe)) {
+       if (/*gp->has_pkey &&*/
+               gp->cnt[op_munion] == 0 && is_groupby(rel->op) && rel->r && 
!rel_is_ref(rel) && list_length(gbe) > 1) {
                allocator *ta = MT_thread_getallocator();
                allocator_state ta_state = ma_open(ta);
                node *n, *m;
                int k, j, i, ngbe = list_length(gbe);
                sql_column *c;
                sql_table **tbls = SA_ZNEW_ARRAY(ta, sql_table*, ngbe);
+               int *table_id = SA_ZNEW_ARRAY(ta, int, ngbe);
+               sql_exp **unique = SA_ZNEW_ARRAY(ta, sql_exp*, ngbe);
                sql_rel **bts = SA_ZNEW_ARRAY(ta, sql_rel*, ngbe), *bt = NULL;
 
                gbe = rel->r;
@@ -2344,13 +2347,18 @@ rel_reduce_groupby_exps(visitor *v, sql_
                        sql_exp *e = n->data;
 
                        c = exp_find_column_(rel, e, -2, &bt);
-                       if (c) {
+                       if (c && bt) {
                                for(j = 0; j < i; j++)
                                        if (c->t == tbls[j] && bts[j] == bt)
                                                break;
+                               if (c->unique == 2 || mvc_is_unique(v->sql, c))
+                                       unique[j] = e;
+                               table_id[k] = j;
                                tbls[j] = c->t;
                                bts[j] = bt;
                                i += (j == i);
+                       } else {
+                               table_id[k] = -1;
                        }
                }
                if (i) { /* forall tables find pkey and remove useless other 
columns */
@@ -2364,6 +2372,46 @@ rel_reduce_groupby_exps(visitor *v, sql_
 
                                k = list_length(gbe);
                                memset(scores, 0, list_length(gbe));
+                               if (unique[j]) { /* we found one unique column, 
clean up those from the same table */
+                                       list *ngbe = new_exp_list(v->sql->sa);
+
+                                       for (l = 0, n = gbe->h; l < k && n; 
l++, n = n->next) {
+                                               sql_exp *e = n->data;
+
+                                               /* keep the group by columns 
which form a primary key
+                                                * of this table. And those 
unrelated to this table. */
+                                               if (e == unique[j] || 
table_id[l] != j)
+                                                       append(ngbe, e);
+                                       }
+                                       if (list_length(ngbe) < 
list_length(gbe)) {
+                                               rel->r = ngbe;
+                                               /* rewrite gbe and aggr, in the 
aggr list, as they may refer to the removed expressions */
+                                               for (m = rel->exps->h; m; m = 
m->next ){
+                                                       sql_exp *e = m->data;
+                                                       int fnd = 0;
+
+                                                       for (l = 0, n = gbe->h; 
l < k && n && !fnd; l++, n = n->next) {
+                                                               sql_exp *gb = 
n->data;
+
+                                                               if (gb != 
unique[j] && table_id[l] == j && exp_refers(gb, e) && gb->alias.label != 
gb->nid) {
+                                                                       sql_exp 
*rs = exp_column(v->sql->sa, gb->l?gb->l:exp_relname(gb), 
gb->r?gb->r:exp_name(gb), exp_subtype(gb), rel->card, has_nil(gb), 
is_unique(gb), is_intern(gb));
+                                                                       
exp_setalias(rs, e->alias.label, exp_find_rel_name(e), exp_name(e));
+                                                                       rs->nid 
= gb->nid;
+                                                                       e = rs;
+                                                                       fnd = 1;
+                                                               }
+                                                       }
+                                                       m->data = e;
+                                               }
+                                               /* new reduced aggr expression 
list */
+                                               
assert(list_length(rel->exps)>0);
+                                               /* only one reduction at a time 
*/
+                                               list_hash_clear(rel->exps);
+                                               v->changes++;
+                                       }
+                                       ma_close(&ta_state);
+                                       return rel;
+                               }
                                if (tbls[j]->pkey) {
                                        for (l = 0, n = gbe->h; l < k && n; 
l++, n = n->next) {
                                                sql_fkey *fk = NULL;
diff --git a/sql/server/rel_rewriter.c b/sql/server/rel_rewriter.c
--- a/sql/server/rel_rewriter.c
+++ b/sql/server/rel_rewriter.c
@@ -293,14 +293,6 @@ find_member_pos(list *l, sql_table *t)
        return -1;
 }
 
-/* The important task of the relational optimizer is to optimize the
-   join order.
-
-   The current implementation chooses the join order based on
-   select counts, ie if one of the join sides has been reduced using
-   a select this join is chosen over one without such selections.
- */
-
 /* currently we only find simple column expressions */
 sql_column *
 name_find_column( sql_rel *rel, const char *rname, const char *name, int pnr, 
sql_rel **bt )
diff --git a/sql/server/rel_statistics.c b/sql/server/rel_statistics.c
--- a/sql/server/rel_statistics.c
+++ b/sql/server/rel_statistics.c
@@ -251,10 +251,8 @@ sql_column_get_statistics(mvc *sql, sql_
 
        if (has_nil(e) && nonil)
                set_has_no_nil(e);
-       if (!is_unique(e) && unique) {
+       if (!is_unique(e) && unique)
                set_unique(e);
-               c->unique=true;
-       }
        if (unique_est != 0.0) {
                prop *p = e->p = prop_create(sql->sa, PROP_NUNIQUES, e->p);
                p->value.dval = unique_est;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to