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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list