Update of /cvsroot/monetdb/sql/src/server
In directory sfp-cvsdas-1.v30.ch3.sourceforge.com:/tmp/cvs-serv29027

Modified Files:
        rel_optimizer.mx 
Log Message:
reduce groupby list by looking if an expression is a primary key
(then all columns from the same base table aren't needed)
this reduces the group by list of Q10 from 7 to 2.

TODO also check for foreign keys out of the pkey to reduce furtur to a single 
column


Index: rel_optimizer.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_optimizer.mx,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -r1.82 -r1.83
--- rel_optimizer.mx    18 Jan 2010 13:36:19 -0000      1.82
+++ rel_optimizer.mx    18 Jan 2010 19:39:37 -0000      1.83
@@ -40,6 +40,7 @@
 #include "rel_prop.h"
 #include "rel_exp.h"
 #include "rel_dump.h"
+#include "sql_env.h"
 
 typedef struct global_props {
        int cnt[MAXOPS];
@@ -449,6 +450,14 @@
        return (c->colnr - kc->c->colnr);
 }
 
+static int
+kc_column_cmp(sql_kc *kc, sql_column *c)
+{
+       /* return on equality */
+       return !(c == kc->c);
+}
+
+
 static sql_idx *
 find_fk_index(sql_table *l, list *lcols, sql_table *r, list *rcols)
 {
@@ -1807,6 +1816,12 @@
                                                list_destroy(lexps);
                                                lexps = NULL;
                                        }
+/*
+                               } else {
+                                       if (!nexps) 
+                                               nexps = new_exp_list();
+                                       append(nexps, exp_dup(e));
+*/
                                }
                        }
                }
@@ -1816,6 +1831,12 @@
                        list_destroy(nexps);
                        nexps = NULL;
                }
+/*
+               if (nexps) {    
+                       list_destroy(rel->exps);
+                       rel->exps = nexps;
+               }
+*/
        }
        return rel;
 }
@@ -2374,6 +2395,80 @@
        return rel;
 }
 
+/* reduce group by expressions based on pkey info */
+static sql_rel *
+rel_reduce_groupby_exps(int *changes, mvc *sql, sql_rel *rel) 
+{
+       list *gbe = rel->r;
+
+       *changes = 0;
+       (void)sql;
+       if (is_groupby(rel->op) && list_length(gbe) > 1 && list_length(gbe)<9) {
+               node *n;
+               char *scores = alloca(list_length(gbe));
+               int k, j, i;
+               sql_column *c;
+               sql_table **tbls;
+
+               gbe = rel->r;
+               tbls = (sql_table**)alloca(sizeof(sql_table*)*list_length(gbe));
+               for (k = 0, i = 0, n = gbe->h; n; n = n->next, k++) {
+                       sql_exp *e = n->data;
+
+                       c = exp_find_column(rel, e);
+                       if (c) {
+                               for(j = 0; j < i; j++)
+                                       if (c->t == tbls[j])
+                                               break;
+                               tbls[j] = c->t;
+                               i += (j == i);
+                       }
+               }
+               if (i) { /* forall tables find pkey and 
+                               remove useless other columns */
+                       for(j = 0; j < i; j++) {
+                               int l, nr = 0;
+
+                               k = list_length(gbe);
+                               memset(scores, 0, list_length(gbe));
+                               if (tbls[j]->pkey) {
+                                       for (l = 0, n = gbe->h; l < k && n; 
l++, n = n->next) {
+                                               fcmp cmp = (fcmp)&kc_column_cmp;
+                                               sql_exp *e = n->data;
+
+                                               c = exp_find_column(rel, e);
+                                               if (c && 
list_find(tbls[j]->pkey->k.columns, c, cmp) != NULL) {
+                                                       scores[l] = 1;
+                                                       nr ++;
+                                               }
+                                       }
+                               }
+                               if (nr && list_length(tbls[j]->pkey->k.columns) 
== nr) {
+                                       list *ngbe = new_exp_list();
+                                       for (l = 0, n = gbe->h; l < k && n; 
l++, n = n->next) {
+                                               sql_exp *e = n->data;
+
+                                               if (scores[l])
+                                                       append(ngbe, 
exp_dup(e)); 
+                                       }
+                                       for (l = 0, n = gbe->h; l < k && n; 
l++, n = n->next) {
+                                               sql_exp *e = n->data;
+
+                                               c = exp_find_column(rel, e);
+                                               if (!c || c->t != tbls[j]) 
+                                                       append(ngbe, 
exp_dup(e)); 
+                                       }
+
+                                       list_destroy(rel->r);
+                                       rel->r = ngbe;
+                               } 
+                               gbe = rel->r;
+                       }
+               }
+       }
+       return rel;
+}
+
 /* Pushing projects up the tree. Done very early in the optimizer.
  * Makes later steps easier. 
  */
@@ -3387,8 +3482,10 @@
        if (gp.cnt[op_select]) 
                rel = rewrite(sql, rel, &rel_remove_empty_select); 
 
-       if (gp.cnt[op_select] && gp.cnt[op_join]) 
+       if (gp.cnt[op_select] && gp.cnt[op_join]) {
                rel = rewrite(sql, rel, &rel_push_select_down_join); 
+               rel = rewrite(sql, rel, &rel_remove_empty_select); 
+       }
 
        if (gp.cnt[op_topn])
                rel = rewrite(sql, rel, &rel_push_topn_down); 
@@ -3397,8 +3494,6 @@
           the 'unique/primary (right hand side)' done before the (fake)-join 
and the selections on the foreign 
           part done after. */
        
-
-
        if (gp.cnt[op_join] && gp.cnt[op_groupby]) {
                rel = rewrite(sql, rel, &rel_push_count_down);
                rel = rewrite(sql, rel, &rel_push_join_down); 
@@ -3407,6 +3502,7 @@
        if (gp.cnt[op_groupby]) {
                rel = rewrite(sql, rel, &rel_avg2sum_count); 
                rel = rewrite(sql, rel, &rel_groupby_order); 
+               rel = rewrite(sql, rel, &rel_reduce_groupby_exps); 
        }
 
        if (gp.cnt[op_join] || gp.cnt[op_left])


------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins

Reply via email to