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