Changeset: 3458e6ebdaf3 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3458e6ebdaf3
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
Branch: Jan2014
Log Message:

fixed bug in rel_reduce_groupby_exps optimizer


diffs (141 lines):

diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -617,11 +617,23 @@ exp_match( sql_exp *e1, sql_exp *e2)
        if (exp_cmp(e1, e2) == 0)
                return 1;
        if (e1->type == e2->type && e1->type == e_column) {
-               if (!e1->name || !e2->name || strcmp(e1->name, e2->name) != 0)
+               if (!e1->l || !e2->l || strcmp(e1->l, e2->l) != 0) 
                        return 0;
-               if (!e1->l || !e2->l || strcmp(e1->l, e2->l) != 0)
+               if (!e1->r || !e2->r || strcmp(e1->r, e2->r) != 0)
                        return 0;
-               /* e1->r */
+               return 1;
+       }
+       return 0;
+}
+
+int 
+exp_refers( sql_exp *c, sql_exp *p)
+{
+       if (c->type == e_column) {
+               if (!p->name || !c->r || strcmp(p->name, c->r) != 0)
+                       return 0;
+               if (!c->l || (p->rname && strcmp(p->rname, c->l) != 0) || 
(!p->rname && strcmp(p->l, c->l) != 0))
+                       return 0;
                return 1;
        }
        return 0;
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -100,6 +100,7 @@ extern char *exp_find_rel_name(sql_exp *
 extern sql_exp *rel_find_exp( sql_rel *rel, sql_exp *e);
 
 extern int exp_cmp( sql_exp *e1, sql_exp *e2);
+extern int exp_refers( sql_exp *c, sql_exp *p);
 extern int exp_match( sql_exp *e1, sql_exp *e2);
 extern int exp_match_exp( sql_exp *e1, sql_exp *e2);
 /* match just the column (cmp equality) expressions */
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
@@ -3910,7 +3910,7 @@ rel_reduce_groupby_exps(int *changes, mv
                                                for (l = 0, n = gbe->h; l < k 
&& n && !fnd; l++, n = n->next) {
                                                        sql_exp *gb = n->data;
 
-                                                       if (scores[l] == -1 && 
exp_match_exp(e,gb)) {
+                                                       if (scores[l] == -1 && 
exp_refers(e,gb)) {
                                                                sql_column *c = 
exp_find_column_(rel, e, -2, &bt);
                                                                sql_exp *rs;
                                                               
@@ -3926,6 +3926,7 @@ rel_reduce_groupby_exps(int *changes, mv
                                                        append(nexps, e);
                                        }
                                        /* new reduced aggr expression list */
+                                       assert(list_length(nexps)>0);
                                        rel->exps = nexps;
                                        rel = rel_crossproduct(sql->sa, rel, r, 
op_join);
                                        rel->exps = lpje;
@@ -5532,11 +5533,6 @@ is_identity_of(sql_exp *e, sql_rel *l)
 }
 
 
-/* More general case is (join reduction)
-       {semi,anti}join (A, join(A,B) [A.c1 == B.c1]) [ A.c1 == B.c1 ]
-       into {semi,anti}join (A,B) [ A.c1 == B.c1 ] 
-*/
-       
 static sql_rel *
 rel_rewrite_semijoin(int *changes, mvc *sql, sql_rel *rel)
 {
@@ -5583,6 +5579,12 @@ rel_rewrite_semijoin(int *changes, mvc *
                                rl = r->l;
                }
 
+               /* More general case is (join reduction)
+                  {semi,anti}join (A, join(A,B) [A.c1 == B.c1]) [ A.c1 == B.c1 
]
+                  into {semi,anti}join (A,B) [ A.c1 == B.c1 ] 
+
+                  for semijoin also A.c1 == B.k1 ] [ A.c1 == B.k2 ] could be 
rewriten
+                */
                if (l && r && rl && 
                    is_basetable(l->op) && is_basetable(rl->op) &&
                    is_join(r->op) && l->l == rl->l)
@@ -5602,29 +5604,46 @@ rel_rewrite_semijoin(int *changes, mvc *
                                sql_exp *le = NULL, *oe = n->data;
                                sql_exp *re = NULL, *ne = m->data;
                                sql_column *cl;  
+                               int anti = (rel->op == op_anti);
                                
                                if (oe->type != e_cmp || ne->type != e_cmp ||
                                    oe->flag != cmp_equal || 
                                    ne->flag != cmp_equal)
                                        return rel;
 
-                               if ((cl = exp_find_column(rel->l, oe->l, -2)) 
!= NULL)
+                               if ((cl = exp_find_column(rel->l, oe->l, -2)) 
!= NULL) {
                                        le = oe->l;
-                               else if ((cl = exp_find_column(rel->l, oe->r, 
-2)) != NULL)
+                                       re = oe->r;
+                               } else if ((cl = exp_find_column(rel->l, oe->r, 
-2)) != NULL) {
                                        le = oe->r;
-
-                               if (exp_find_column(rl, ne->l, -2) == cl)
-                                       re = oe->r;
-                               else if (exp_find_column(rl, ne->r, -2) == cl)
                                        re = oe->l;
-                               if (!re)
+                               } else
                                        return rel;
+
+                               if (exp_find_column(rl, ne->l, -2) == cl) {
+                                       sql_exp *e = (or != r)?rel_find_exp(or, 
re):re;
+                                       int equal = exp_match_exp(ne->r, e);
+                                      
+                                       assert(equal);
+                                       if (anti && re != ne->r)
+                                               return rel;
+                                       re = ne->r;
+                               } else if (exp_find_column(rl, ne->r, -2) == 
cl) {
+                                       sql_exp *e = (or != r)?rel_find_exp(or, 
re):re;
+                                       int equal = exp_match_exp(ne->l, e);
+                                      
+                                       assert(equal);
+                                       if (anti && re != ne->l)
+                                               return rel;
+                                       re = ne->l;
+                               } else
+                                       return rel;
+
                                ne = exp_compare(sql->sa, le, re, cmp_equal);
                                append(exps, ne);
                        }
 
                        rel->r = rel_dup(r->r);
-                       /* maybe rename exps ? */
                        rel->exps = exps;
                        rel_destroy(or);
                        (*changes)++;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to