Changeset: 480c1c2c0808 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=480c1c2c0808
Modified Files:
        sql/src/server/rel_optimizer.mx
        
sql/src/test/BugDay_2005-10-06_2.9.3/Tests/multiple_select_on_view.SF-935639.stable.out
        sql/src/test/Tests/trace.stable.out
Branch: Jun2010
Log Message:

back ported improvement of rel_dce (fixes problem with
select count(*) from (select distinct x,y from a) as b


diffs (220 lines):

diff -r e42dc8f76d4c -r 480c1c2c0808 sql/src/server/rel_optimizer.mx
--- a/sql/src/server/rel_optimizer.mx   Fri Jul 02 23:27:45 2010 +0200
+++ b/sql/src/server/rel_optimizer.mx   Sun Jul 04 19:26:15 2010 +0200
@@ -2666,7 +2666,7 @@
        return rel;
 }
 
-static void
+static int
 exp_mark_used(sql_rel *subrel, sql_exp *e)
 {
        sql_exp *ne = NULL;
@@ -2676,8 +2676,7 @@
                ne = rel_find_exp(subrel, e);
                break;
        case e_convert:
-               exp_mark_used(subrel, e->l);
-               break;
+               return exp_mark_used(subrel, e->l);
        case e_aggr:
        case e_func: {
                if (e->l) {
@@ -2717,23 +2716,52 @@
        case e_atom:
                /* atoms are used in e_cmp */
                e->used = 1;
-               break;
+               /* return 0 as constants may require a full column ! */
+               return 0;
        }
-       if (ne)
+       if (ne) {
                ne->used = 1;
+               return ne->used;
+       }
+       return 0;
+}
+
+static void
+positional_exps_mark_used( sql_rel *rel, sql_rel *subrel )
+{
+       if (!rel->exps) 
+               assert(0);
+
+       if (rel->exps && subrel->exps) {
+               node *n, *m;
+               for (n=rel->exps->h, m=subrel->exps->h; n && m; n = n->next, m 
= m->next) {
+                       sql_exp *e = n->data;
+                       sql_exp *se = m->data;
+
+                       if (e->used)
+                               se->used = 1;
+               }
+       }
 }
 
 static void
 exps_mark_used(sql_rel *rel, sql_rel *subrel)
 {
+       int nr = 0;
        if (rel->exps) {
                node *n;
                for (n=rel->exps->h; n; n = n->next) {
                        sql_exp *e = n->data;
 
-                       exp_mark_used(subrel, e);
+                       if (!is_project(rel->op) || e->used) 
+                               nr += exp_mark_used(subrel, e);
                }
        }
+       /* for count/rank we need atleast one column */
+       if (!nr && (is_project(subrel->op) || is_base(subrel->op))) {
+               sql_exp *e = subrel->exps->h->data;
+               e->used = 1;
+       }
        if (rel->r && (rel->op == op_project || rel->op  == op_groupby)) {
                list *l = rel->r;
                node *n;
@@ -2765,7 +2793,7 @@
 static void
 rel_used(sql_rel *rel)
 {
-       if (is_join(rel->op) || is_union(rel->op)) {
+       if (is_join(rel->op) || is_set(rel->op)) {
                if (rel->l) 
                        rel_used(rel->l);
                if (rel->r) 
@@ -2783,6 +2811,10 @@
 rel_mark_used(mvc *sql, sql_rel *rel, int proj)
 {
        (void)sql;
+
+       if (proj && (need_distinct(rel))) 
+               rel_used(rel);
+
        switch(rel->op) {
        case op_basetable:
        case op_table:
@@ -2824,10 +2856,17 @@
                 * 
                 * Project part of union is based on column position.
                 */
-               if (proj) {
-                       /* properly mark left/right based on exps list */
-                       rel_used(rel->l);
-                       rel_used(rel->r);
+               if (proj && (need_distinct(rel) || !rel->exps)) {
+                       rel_used(rel);
+                       if (!rel->exps) {
+                               rel_used(rel->l);
+                               rel_used(rel->r);
+                       }
+                       rel_mark_used(sql, rel->l, 0);
+                       rel_mark_used(sql, rel->r, 0);
+               } else if (proj && !need_distinct(rel)) {
+                       positional_exps_mark_used(rel, rel->l);
+                       positional_exps_mark_used(rel, rel->r);
                        rel_mark_used(sql, rel->l, 0);
                        rel_mark_used(sql, rel->r, 0);
                }
@@ -2868,11 +2907,8 @@
                                if (e->used || is_intern(e))
                                        append(exps, exp_dup(e));
                        }
-                       /* atleast one (needed for crossproducts, count(*), 
rank() and single value projections) ! */
-                       if (list_length(exps) == 0) {
-                               sql_exp *e = rel->exps->h->data;
-                               append(exps, exp_dup(e));
-                       }
+                       /* atleast one (needed for crossproducts, count(*), 
rank() and single value projections) !, handled by exps_mark_used */
+                       assert(list_length(exps) > 0);
                        list_destroy(rel->exps);
                        rel->exps = exps;
                }
@@ -2887,6 +2923,10 @@
        case op_project:
        case op_groupby: 
 
+       case op_union: 
+       case op_inter: 
+       case op_except: 
+
                if (rel->l && rel->exps) {
                        node *n;
                        list *exps = new_exp_list();
@@ -2897,11 +2937,8 @@
                                if (e->used || is_intern(e))
                                        append(exps, exp_dup(e));
                        }
-                       /* atleast one (needed for crossproducts, count(*), 
rank() and single value projections) ! */
-                       if (list_length(exps) == 0) {
-                               sql_exp *e = rel->exps->h->data;
-                               append(exps, exp_dup(e));
-                       }
+                       /* atleast one (needed for crossproducts, count(*), 
rank() and single value projections) !, handled by exps_mark_used */
+                       assert(list_length(exps) > 0);
                        list_destroy(rel->exps);
                        rel->exps = exps;
                }
@@ -2913,12 +2950,6 @@
 
        case op_select: 
 
-       case op_union: 
-       case op_inter: 
-       case op_except: 
-               /* We cannot remove here as set projection are based on column
-                  position */
-
        case op_join: 
        case op_left: 
        case op_right: 
@@ -3012,9 +3043,13 @@
        if (!rel)
                return rel;
        
+       /* 
+        * Mark used up until the next project 
+        * For setops we need to first mark, then remove 
+         * because of positional dependency 
+        */
+       rel_mark_used(sql, rel, 1);
        rel = rel_remove_unused(sql, rel);
-       /* mark used up until the next project */
-       rel_mark_used(sql, rel, 1);
        rel_dce_down(sql, rel, 1);
        return rel;
 }
diff -r e42dc8f76d4c -r 480c1c2c0808 
sql/src/test/BugDay_2005-10-06_2.9.3/Tests/multiple_select_on_view.SF-935639.stable.out
--- 
a/sql/src/test/BugDay_2005-10-06_2.9.3/Tests/multiple_select_on_view.SF-935639.stable.out
   Fri Jul 02 23:27:45 2010 +0200
+++ 
b/sql/src/test/BugDay_2005-10-06_2.9.3/Tests/multiple_select_on_view.SF-935639.stable.out
   Sun Jul 04 19:26:15 2010 +0200
@@ -26,12 +26,14 @@
 
 [ 1    ]
 [ 1    ]
-% sys.a # table_name
+#select count(*) from c;
+% sys.c # table_name
 % L2 # name
 % wrd # type
 % 1 # length
 [ 2    ]
-% sys.a # table_name
+#select count(*) from c;
+% sys.c # table_name
 % L3 # name
 % wrd # type
 % 1 # length
diff -r e42dc8f76d4c -r 480c1c2c0808 sql/src/test/Tests/trace.stable.out
--- a/sql/src/test/Tests/trace.stable.out       Fri Jul 02 23:27:45 2010 +0200
+++ b/sql/src/test/Tests/trace.stable.out       Sun Jul 04 19:26:15 2010 +0200
@@ -35,7 +35,7 @@
 % L2 # name
 % wrd # type
 % 2 # length
-[ 47   ]
+[ 42   ]
 
 # 11:14:41 >  
 # 11:14:41 >  Done.
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to