Changeset: c71081d50db3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c71081d50db3
Modified Files:
sql/server/rel_optimizer.c
sql/server/rel_outer_join_optimizer.h
sql/server/rel_rel.c
sql/server/rel_rel.h
sql/server/rel_rewriter.c
sql/server/rel_rewriter.h
sql/server/rel_select.c
sql/server/sql_mvc.c
sql/server/sql_mvc.h
Branch: default
Log Message:
Merge heads.
diffs (truncated from 964 to 300 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
@@ -1004,7 +1004,7 @@ order_joins(mvc *sql, list *rels, list *
if (exp_is_join_exp(e) == 0) {
sql_rel *nr = NULL;
if (e->flag == cmp_equal)
- nr = rel_push_join(sql, top->l, e->l,
e->r, NULL, e);
+ nr = rel_push_join(sql, top->l, e->l,
e->r, NULL, e, 0);
if (!nr)
rel_join_add_exp(sql->sa, top->l, e);
} else
@@ -1327,142 +1327,6 @@ exp_rename(mvc *sql, sql_exp *e, sql_rel
return exp_propagate(sql->sa, ne, e);
}
-/* push the expression down, ie translate colum references
- from relation f into expression of relation t
-*/
-
-static sql_exp * _exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t);
-
-static list *
-exps_push_down(mvc *sql, list *exps, sql_rel *f, sql_rel *t)
-{
- node *n;
- list *nl = new_exp_list(sql->sa);
-
- for(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);
- append(nl, narg);
- }
- return nl;
-}
-
-static sql_exp *
-_exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t)
-{
- sql_exp *oe = e;
- sql_exp *ne = NULL, *l, *r, *r2;
-
- switch(e->type) {
- case e_column:
- if (is_union(f->op)) {
- int p = list_position(f->exps, rel_find_exp(f, e));
-
- return list_fetch(t->exps, p);
- }
- 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 */
- }
- 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_setname(sql->sa, e, exp_relname(ne), exp_name(ne));
- return e;
- 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));
- } 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);
- } 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);
- }
- }
- 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;
- case e_aggr:
- case e_func: {
- list *l = e->l, *nl = NULL;
-
- if (!l) {
- return e;
- } else {
- 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_atom:
- case e_psm:
- return e;
- }
- return NULL;
-}
-
-static sql_exp *
-exp_push_down(mvc *sql, sql_exp *e, sql_rel *f, sql_rel *t)
-{
- return _exp_push_down(sql, e, f, t);
-}
-
static int
math_unsafe(sql_subfunc *f)
{
@@ -4712,9 +4576,9 @@ rel_push_select_down_join(mvc *sql, sql_
re->card = ne->card;
if (re->card >= CARD_AGGR) {
- nr = rel_push_join(sql, r, e->l, re,
NULL, e);
+ nr = rel_push_join(sql, r, e->l, re,
NULL, e, 0);
} else {
- nr = rel_push_select(sql, r, e->l, e);
+ nr = rel_push_select(sql, r, e->l, e,
0);
}
if (nr)
rel->l = nr;
diff --git a/sql/server/rel_outer_join_optimizer.h
b/sql/server/rel_outer_join_optimizer.h
--- a/sql/server/rel_outer_join_optimizer.h
+++ b/sql/server/rel_outer_join_optimizer.h
@@ -46,9 +46,9 @@ rel_outer2inner_join(mvc *sql, sql_rel *
re->card = ne->card;
if (re->card >= CARD_AGGR) {
- nr = rel_push_join(sql, r, e->l, re,
NULL, e);
+ nr = rel_push_join(sql, r, e->l, re,
NULL, e, 0);
} else {
- nr = rel_push_select(sql, r, e->l, e);
+ nr = rel_push_select(sql, r, e->l, e,
0);
}
if (nr)
rel->l = nr;
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
@@ -14,7 +14,7 @@
#include "rel_unnest.h"
#include "sql_semantic.h"
#include "sql_mvc.h"
-
+#include "rel_rewriter.h"
void
rel_set_exps(sql_rel *rel, list *exps)
@@ -1218,15 +1218,14 @@ rel_bind_path_(mvc *sql, sql_rel *rel, s
}
static list *
-rel_bind_path(mvc *sql, sql_rel *rel, sql_exp *e)
+rel_bind_path(mvc *sql, sql_rel *rel, sql_exp *e, list *path)
{
- list *path = sa_list(sql->sa);
if (!path)
return NULL;
if (e->type == e_convert)
- e = e->l;
- if (e->type == e_column) {
+ path = rel_bind_path(sql, rel, e->l, path);
+ else if (e->type == e_column) {
if (rel) {
if (!rel_bind_path_(sql, rel, e, path)) {
/* something is wrong */
@@ -1240,21 +1239,49 @@ rel_bind_path(mvc *sql, sql_rel *rel, sq
return path;
}
+static sql_rel *
+rel_select_push_exp_down(mvc *sql, sql_rel *rel, sql_exp *e)
+{
+ sql_rel *r = rel->l, *jl = r->l, *jr = r->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) {
+ 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);
+ }
+ }
+ }
+ if (!done)
+ rel_select_add_exp(sql->sa, rel, e);
+ return rel;
+}
+
/* ls is the left expression of the select, rs is a simple atom, e is the
select expression.
*/
sql_rel *
-rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e)
+rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e, int f)
{
- list *l = rel_bind_path(sql, rel, ls);
+ list *l = rel_bind_path(sql, rel, ls, sa_list(sql->sa));
node *n;
sql_rel *lrel = NULL, *p = NULL;
- if (!l || !sql->pushdown) {
- /* expression has no clear parent relation, so filter current
- with it */
+ if (!l)
+ return NULL;
+ if (is_sql_or(f)) /* expression has no clear parent relation, so filter
current with it */
return rel_select(sql->sa, rel, e);
- }
for (n = l->h; n; n = n->next ) {
lrel = n->data;
@@ -1276,7 +1303,7 @@ rel_push_select(mvc *sql, sql_rel *rel,
if (!lrel)
return NULL;
if (p && is_select(p->op) && !rel_is_ref(p)) { /* refine old select */
- rel_select_add_exp(sql->sa, p, e);
+ p = rel_select_push_exp_down(sql, p, e);
} else {
sql_rel *n = rel_select(sql->sa, lrel, e);
@@ -1300,21 +1327,21 @@ rel_push_select(mvc *sql, sql_rel *rel,
join expression.
*/
sql_rel *
-rel_push_join(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, sql_exp *rs2,
sql_exp *e)
+rel_push_join(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, sql_exp *rs2,
sql_exp *e, int f)
{
- list *l = rel_bind_path(sql, rel, ls);
- list *r = rel_bind_path(sql, rel, rs);
+ list *l = rel_bind_path(sql, rel, ls, sa_list(sql->sa));
+ list *r = rel_bind_path(sql, rel, rs, sa_list(sql->sa));
list *r2 = NULL;
node *ln, *rn;
sql_rel *lrel = NULL, *rrel = NULL, *rrel2 = NULL, *p = NULL;
if (rs2)
- r2 = rel_bind_path(sql, rel, rs2);
+ r2 = rel_bind_path(sql, rel, rs2, sa_list(sql->sa));
if (!l || !r || (rs2 && !r2))
return NULL;
- if (!sql->pushdown)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list