Changeset: 848a681f010c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/848a681f010c
Modified Files:
sql/server/rel_optimizer.c
sql/server/rel_rel.c
sql/server/rel_rewriter.c
sql/server/rel_rewriter.h
Branch: default
Log Message:
There are no aliases on expressions inside joins, so there's no reason to copy
expressions while trying to push down select expressions
diffs (264 lines):
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
@@ -4591,25 +4591,20 @@ rel_push_select_down(visitor *v, sql_rel
set_processed(jr);
for (n = exps->h; n;) {
node *next = n->next;
- sql_exp *e = n->data, *ne = NULL;
-
- if (left)
- ne = exp_push_down(v->sql, e, jl, jl);
- if (ne && ne != e) {
+ sql_exp *e = n->data;
+
+ if (left && exp_push_down(v->sql, e, jl)) {
if (!is_select(jl->op) || rel_is_ref(jl))
r->l = jl = rel_select(v->sql->sa, jl,
NULL);
- rel_select_add_exp(v->sql->sa, jl, ne);
+ rel_select_add_exp(v->sql->sa, jl, e);
list_remove_node(exps, NULL, n);
v->changes++;
- } else if (right) {
- ne = exp_push_down(v->sql, e, jr, jr);
- if (ne && ne != e) {
- if (!is_select(jr->op) ||
rel_is_ref(jr))
- r->r = jr =
rel_select(v->sql->sa, jr, NULL);
- rel_select_add_exp(v->sql->sa, jr, ne);
- list_remove_node(exps, NULL, n);
- v->changes++;
- }
+ } else if (right && exp_push_down(v->sql, e, jr)) {
+ if (!is_select(jr->op) || rel_is_ref(jr))
+ r->r = jr = rel_select(v->sql->sa, jr,
NULL);
+ rel_select_add_exp(v->sql->sa, jr, e);
+ list_remove_node(exps, NULL, n);
+ v->changes++;
}
n = next;
}
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -1137,21 +1137,15 @@ rel_select_push_exp_down(mvc *sql, sql_r
int left = r->op == op_join || r->op == op_left;
int right = r->op == op_join || r->op == op_right;
int done = 0;
- sql_exp *ne = NULL;
assert(is_select(rel->op));
if (!is_full(r->op) && !is_single(r)) {
- if (left)
- ne = exp_push_down(sql, e, jl, jl);
- if (ne && ne != e) {
+ if (left && exp_push_down(sql, e, jl)) {
done = 1;
- r->l = jl = rel_select_add_exp(sql->sa, jl, ne);
- } else if (right) {
- ne = exp_push_down(sql, e, jr, jr);
- if (ne && ne != e) {
- done = 1;
- r->r = jr = rel_select_add_exp(sql->sa, jr, ne);
- }
+ r->l = jl = rel_select_add_exp(sql->sa, jl, e);
+ } else if (right && exp_push_down(sql, e, jr)) {
+ done = 1;
+ r->r = jr = rel_select_add_exp(sql->sa, jr, e);
}
}
if (!done)
diff --git a/sql/server/rel_rewriter.c b/sql/server/rel_rewriter.c
--- a/sql/server/rel_rewriter.c
+++ b/sql/server/rel_rewriter.c
@@ -207,142 +207,66 @@ rewrite_simplify(visitor *v, sql_rel *re
return try_remove_empty_select(v, rel);
}
-/* push the expression down, ie translate colum references
- from relation f into expression of relation t
-*/
+/* push the expression down, ie check if relation r references it */
-static sql_exp * _exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t);
+static bool _exp_push_down(mvc *sql, sql_exp *e, sql_rel *r);
-static list *
-exps_push_down(mvc *sql, list *exps, sql_rel *f, sql_rel *t)
+static bool
+exps_push_down(mvc *sql, list *exps, sql_rel *r)
{
if (list_empty(exps))
- return exps;
- for(node *n = exps->h; n; n = n->next) {
- sql_exp *arg = n->data, *narg = NULL;
-
- narg = _exp_push_down(sql, arg, f, t);
- if (!narg)
- return NULL;
- narg = exp_propagate(sql->sa, narg, arg);
- n->data = narg;
- }
- return exps;
+ return true;
+ for (node *n = exps->h; n; n = n->next)
+ if (!_exp_push_down(sql, n->data, r))
+ return false;
+ return true;
}
-static sql_exp *
-_exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t)
+static bool
+_exp_push_down(mvc *sql, sql_exp *e, sql_rel *r)
{
- sql_exp *oe = e;
- sql_exp *ne = NULL, *l, *r, *r2;
+ sql_exp *ne = NULL;
switch(e->type) {
case e_column:
if (e->l) {
- ne = rel_bind_column2(sql, f, e->l, e->r, 0);
- /* if relation name matches expressions relation name,
find column based on column name alone */
+ ne = rel_bind_column2(sql, r, e->l, e->r, 0);
+ } else {
+ ne = rel_bind_column(sql, r, e->r, 0, 1);
}
- if (!ne && !e->l)
- ne = rel_bind_column(sql, f, e->r, 0, 1);
- if (!ne || ne->type != e_column)
- return NULL;
- e = NULL;
- if (ne->l && ne->r)
- e = rel_bind_column2(sql, t, ne->l, ne->r, 0);
- if (!e && ne->r && !ne->l)
- e = rel_bind_column(sql, t, ne->r, 0, 1);
- sql->session->status = 0;
- sql->errstr[0] = 0;
- if (e && oe)
- e = exp_propagate(sql->sa, e, oe);
- /* if the upper exp was an alias, keep this */
- if (e && exp_relname(ne))
- exp_prop_alias(sql->sa, e, ne);
- return e;
+ if (!ne) {
+ sql->session->status = 0;
+ sql->errstr[0] = 0;
+ return false;
+ }
+ if (ne->type != e_column)
+ return false;
+ return true;
case e_cmp:
if (e->flag == cmp_or || e->flag == cmp_filter) {
- list *l, *r;
-
- l = exps_push_down(sql, e->l, f, t);
- if (!l)
- return NULL;
- r = exps_push_down(sql, e->r, f, t);
- if (!r)
- return NULL;
- if (e->flag == cmp_filter)
- return exp_filter(sql->sa, l, r, e->f,
is_anti(e));
- return exp_or(sql->sa, l, r, is_anti(e));
+ return exps_push_down(sql, e->l, r) &&
exps_push_down(sql, e->r, r);
} else if (e->flag == cmp_in || e->flag == cmp_notin) {
- list *r;
-
- l = _exp_push_down(sql, e->l, f, t);
- if (!l)
- return NULL;
- r = exps_push_down(sql, e->r, f, t);
- if (!r)
- return NULL;
- return exp_in(sql->sa, l, r, e->flag);
+ return _exp_push_down(sql, e->l, r) &&
exps_push_down(sql, e->r, r);
} else {
- l = _exp_push_down(sql, e->l, f, t);
- if (!l)
- return NULL;
- r = _exp_push_down(sql, e->r, f, t);
- if (!r)
- return NULL;
- if (e->f) {
- r2 = _exp_push_down(sql, e->f, f, t);
- if (l && r && r2)
- ne = exp_compare2(sql->sa, l, r, r2,
e->flag);
- } else if (l && r) {
- if (l->card < r->card)
- ne = exp_compare(sql->sa, r, l,
swap_compare((comp_type)e->flag));
- else
- ne = exp_compare(sql->sa, l, r,
e->flag);
- }
+ return _exp_push_down(sql, e->l, r) &&
_exp_push_down(sql, e->r, r) && (!e->f || _exp_push_down(sql, e->f, r));
}
- if (!ne)
- return NULL;
- return exp_propagate(sql->sa, ne, e);
case e_convert:
- l = _exp_push_down(sql, e->l, f, t);
- if (l)
- return exp_convert(sql->sa, l, exp_fromtype(e),
exp_totype(e));
- return NULL;
+ return _exp_push_down(sql, e->l, r);
case e_aggr:
- case e_func: {
- list *l = e->l, *nl = NULL;
-
- if (!list_empty(l)) {
- nl = exps_push_down(sql, l, f, t);
- if (!nl)
- return NULL;
- }
- if (e->type == e_func)
- return exp_op(sql->sa, nl, e->f);
- else
- return exp_aggr(sql->sa, nl, e->f, need_distinct(e),
need_no_nil(e), e->card, has_nil(e));
+ case e_func:
+ return exps_push_down(sql, e->l, r);
+ case e_atom:
+ return exps_push_down(sql, e->f, r); /* for atom lists (ie
e->f) validate the list, otherwise it can be always pushed */
+ case e_psm:
+ return false;
}
- case e_atom: {
- list *l = e->f, *nl = NULL;
-
- if (!list_empty(l)) {
- nl = exps_push_down(sql, l, f, t);
- if (!nl)
- return NULL;
- return exp_values(sql->sa, nl);
- }
- return exp_copy(sql, e);
- }
- case e_psm:
- return e;
- }
- return NULL;
+ return false;
}
-sql_exp *
-exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t)
+bool
+exp_push_down(mvc *sql, sql_exp *e, sql_rel *r)
{
- return _exp_push_down(sql, e, f, t);
+ return _exp_push_down(sql, e, r);
}
sql_rel *
diff --git a/sql/server/rel_rewriter.h b/sql/server/rel_rewriter.h
--- a/sql/server/rel_rewriter.h
+++ b/sql/server/rel_rewriter.h
@@ -33,7 +33,7 @@ try_remove_empty_select(visitor *v, sql_
return rel;
}
-extern sql_exp *exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t);
+extern bool exp_push_down(mvc *sql, sql_exp *e, sql_rel *r);
extern sql_rel *rewrite_reset_used(visitor *v, sql_rel *rel);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list