Changeset: d9ab7f8929b3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/d9ab7f8929b3
Modified Files:
sql/server/rel_unnest.c
Branch: default
Log Message:
only rewrite outer 2 inner when needed for unnesting anyequal or complex or
expressions (with subqueries)
diffs (166 lines):
diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c
--- a/sql/server/rel_unnest.c
+++ b/sql/server/rel_unnest.c
@@ -728,7 +728,7 @@ move_join_exps(mvc *sql, sql_rel *j, sql
for(n = exps->h; n; n = n->next){
sql_exp *e = n->data;
- if (rel_find_exp(rel, e)) {
+ if (rel_rebind_exp(sql, rel, e)) {
if (exp_has_freevar(sql, e))
rel_bind_var(sql, rel->l, e);
append(rel->exps, e);
@@ -1380,10 +1380,8 @@ push_up_join(mvc *sql, sql_rel *rel, lis
set_processed(nj);
rel_destroy(j);
j = nj;
- if (is_semi(rel->op)) {
- //assert(!is_semi(rel->op));
+ if (is_semi(rel->op))
rel->op = op_left;
- }
move_join_exps(sql, j, rel);
return j;
}
@@ -1397,10 +1395,8 @@ push_up_join(mvc *sql, sql_rel *rel, lis
set_processed(nj);
rel_destroy(j);
j = nj;
- if (is_semi(rel->op)) {
- //assert(!is_semi(rel->op));
+ if (is_semi(rel->op))
rel->op = op_left;
- }
move_join_exps(sql, j, rel);
return j;
}
@@ -1835,10 +1831,12 @@ rewrite_empty_project(visitor *v, sql_re
#define is_anyequal(sf) (strcmp((sf)->func->base.name, "sql_anyequal") == 0)
#define is_not_anyequal(sf) (strcmp((sf)->func->base.name, "sql_not_anyequal")
== 0)
-static int exps_have_not_anyequal(list *exps);
+#define ANYEQUAL 1
+#define NOT_ANYEQUAL 2
+static int exps_have_anyequal(list *exps, int any_or_not_anyequal);
static int
-exp_has_not_anyequal(sql_exp *e)
+exp_has_anyequal(sql_exp *e, int any_or_not_anyequal)
{
if (!e)
return 0;
@@ -1848,20 +1846,23 @@ exp_has_not_anyequal(sql_exp *e)
list *args = e->l;
sql_subfunc *f = e->f;
- if (f && f->func && is_not_anyequal(f) &&
exps_have_rel_exp(args))
+ if (f && f->func && (any_or_not_anyequal&NOT_ANYEQUAL) &&
is_not_anyequal(f) && exps_have_rel_exp(args))
return 1;
- return exps_have_not_anyequal(e->l);
+ if (f && f->func && (any_or_not_anyequal&ANYEQUAL) &&
is_anyequal(f) && exps_have_rel_exp(args))
+ return 1;
+ return exps_have_anyequal(e->l, any_or_not_anyequal);
}
case e_cmp:
if (e->flag == cmp_or || e->flag == cmp_filter)
- return (exps_have_not_anyequal(e->l) ||
exps_have_not_anyequal(e->r));
+ return (exps_have_anyequal(e->l, any_or_not_anyequal)
|| exps_have_anyequal(e->r, any_or_not_anyequal));
if (e->flag == cmp_in || e->flag == cmp_notin)
- return (exp_has_not_anyequal(e->l) ||
exps_have_not_anyequal(e->r));
- return (exp_has_not_anyequal(e->l) ||
exp_has_not_anyequal(e->r) || (e->f && exp_has_not_anyequal(e->f)));
+ return (exp_has_anyequal(e->l, any_or_not_anyequal) ||
exps_have_anyequal(e->r, any_or_not_anyequal));
+ return (exp_has_anyequal(e->l, any_or_not_anyequal) ||
exp_has_anyequal(e->r, any_or_not_anyequal) ||
+ (e->f && exp_has_anyequal(e->f,
any_or_not_anyequal)));
case e_convert:
- return exp_has_not_anyequal(e->l);
+ return exp_has_anyequal(e->l, any_or_not_anyequal);
case e_atom:
- return (e->f && exp_has_not_anyequal(e->f));
+ return (e->f && exp_has_anyequal(e->f, any_or_not_anyequal));
case e_psm:
case e_column:
return 0;
@@ -1870,14 +1871,14 @@ exp_has_not_anyequal(sql_exp *e)
}
static int
-exps_have_not_anyequal(list *exps)
+exps_have_anyequal(list *exps, int any_or_not_anyequal)
{
if (list_empty(exps))
return 0;
for(node *n=exps->h; n; n=n->next) {
sql_exp *e = n->data;
- if (exp_has_not_anyequal(e))
+ if (exp_has_anyequal(e, any_or_not_anyequal))
return 1;
}
return 0;
@@ -1887,7 +1888,7 @@ exps_have_not_anyequal(list *exps)
static sql_rel *
not_anyequal_helper(visitor *v, sql_rel *rel)
{
- if (is_innerjoin(rel->op) && exps_have_not_anyequal(rel->exps)) {
+ if (is_innerjoin(rel->op) && exps_have_anyequal(rel->exps,
NOT_ANYEQUAL)) {
sql_rel *nrel = rel_select(v->sql->sa, rel, NULL);
nrel->exps = rel->exps;
rel->exps = NULL;
@@ -2245,6 +2246,24 @@ rewrite_aggregates(visitor *v, sql_rel *
return rel;
}
+static sql_exp*
+has_or(visitor *v, sql_rel *rel, sql_exp *e, int depth)
+{
+ (void)rel;
+ (void)depth;
+ if(!v->data && e && is_compare(e->type) && e->flag == cmp_or)
+ v->data = e;
+ return e;
+}
+
+static bool
+exps_has_or_exp(mvc *sql, list *exps)
+{
+ visitor v = { .sql = sql, .data = NULL };
+ exps_exp_visitor_topdown(&v, NULL, exps, 0, &has_or, true);
+ return v.data != NULL;
+}
+
/* remove or expressions with subqueries */
static sql_rel *
rewrite_or_exp(visitor *v, sql_rel *rel)
@@ -3709,11 +3728,10 @@ include_tid(sql_rel *r)
return r->nrcols;
}
-static inline sql_rel *
-rewrite_outer2inner_union(visitor *v, sql_rel *rel)
+static sql_rel *
+rewrite_outer2inner_union_(visitor *v, sql_rel *rel)
{
- if (is_outerjoin(rel->op) && !is_rewrite_outer_used(rel->used) &&
rel->flag != MERGE_LEFT && !list_empty(rel->exps) && (((/*is_left(rel->op) ||*/
is_full(rel->op)) && rel_has_freevar(v->sql,rel->l)) ||
- ((/*is_right(rel->op) ||*/ is_full(rel->op)) &&
rel_has_freevar(v->sql,rel->r)) || exps_have_freevar(v->sql, rel->exps) ||
exps_have_rel_exp(rel->exps))) {
+ if (is_outerjoin(rel->op) && !is_rewrite_outer_used(rel->used) &&
rel->flag != MERGE_LEFT) {
/* the join relation may have more than 1 reference, a
replacement is needed */
sql_rel *nr = rel_dup_copy(v->sql->sa, rel);
sql_exp *f = exp_atom_bool(v->sql->sa, 0);
@@ -3799,6 +3817,17 @@ rewrite_outer2inner_union(visitor *v, sq
return rel;
}
+static sql_rel *
+rewrite_outer2inner_union(visitor *v, sql_rel *rel)
+{
+ if (is_outerjoin(rel->op) && !list_empty(rel->exps) &&
(exps_have_anyequal(rel->exps, ANYEQUAL|NOT_ANYEQUAL) ||
(exps_have_rel_exp(rel->exps) && exps_has_or_exp(v->sql, rel->exps))))
+ return rewrite_outer2inner_union_(v, rel);
+ if (!is_dependent(rel) && is_outerjoin(rel->op) && rel->flag !=
MERGE_LEFT && !list_empty(rel->exps) && (((/*is_left(rel->op) ||*/
is_full(rel->op)) && rel_has_freevar(v->sql,rel->l)) ||
+ ((/*is_right(rel->op) ||*/ is_full(rel->op)) &&
rel_has_freevar(v->sql,rel->r)) || exps_have_freevar(v->sql, rel->exps)))
+ return rewrite_outer2inner_union_(v, rel);
+ return rel;
+}
+
static sql_exp *
rewrite_complex(visitor *v, sql_rel *rel, sql_exp *e, int depth)
{
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]