Changeset: 32295630b035 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/32295630b035
Modified Files:
sql/server/rel_exp.c
sql/server/rel_exp.h
sql/server/rel_unnest.c
Branch: default
Log Message:
only push up selects through projections if the expressions aren't fallible
diffs (88 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
@@ -2833,6 +2833,60 @@ exp_unsafe(sql_exp *e, bool allow_identi
return 0;
}
+bool
+exps_have_fallible(list *exps)
+{
+ if (!exps)
+ return false;
+ for (node *n = exps->h; n; n = n->next)
+ if (exp_is_fallible(n->data))
+ return true;
+ return false;
+}
+
+bool
+exp_is_fallible(sql_exp *e)
+{
+ switch (e->type) {
+ case e_convert:
+ {
+ sql_subtype *t = exp_totype(e);
+ sql_subtype *f = exp_fromtype(e);
+ if (t->type->eclass == EC_FLT && (f->type->eclass ==
EC_DEC || f->type->eclass == EC_NUM))
+ return exp_is_fallible(e->l);
+ if (f->type->localtype > t->type->localtype)
+ return true;
+ /* TODO for types with digits check if t->digits is
large enough
+ * for types with scale etc */
+ return exp_is_fallible(e->l);
+ }
+ case e_aggr:
+ case e_func: {
+ sql_subfunc *f = e->f;
+
+ if (IS_ANALYTIC(f->func) || !LANG_INT_OR_MAL(f->func->lang) ||
f->func->side_effect)
+ return true;
+ return exps_have_fallible(e->l);
+ } break;
+ case e_cmp: {
+ if (e->flag == cmp_con || e->flag == cmp_dis) {
+ return exps_have_fallible(e->l);
+ } else if (e->flag == cmp_in || e->flag == cmp_notin) {
+ return exp_is_fallible(e->l) ||
exps_have_fallible(e->r);
+ } else if (e->flag == cmp_filter) {
+ return exps_have_fallible(e->l) ||
exps_have_fallible(e->r);
+ } else {
+ return exp_is_fallible(e->l) || exp_is_fallible(e->r)
|| (e->f && exp_is_fallible(e->f));
+ }
+ } break;
+ case e_atom:
+ case e_column:
+ case e_psm:
+ return false;
+ }
+ return false;
+}
+
static inline int
exp_key( sql_exp *e )
{
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
@@ -187,6 +187,8 @@ extern bool exps_have_unsafe(list *exps,
unsafeness
(conversions for example) */);
extern bool exp_unsafe(sql_exp *e, bool allow_identity, bool card);
extern int exp_has_sideeffect(sql_exp *e);
+extern bool exp_is_fallible(sql_exp *e); /* exp could result in an error, ie
push up of lower restricting expressions isn't possible */
+extern bool exps_have_fallible(list *l);
extern sql_exp *exps_find_prop(list *exps, rel_prop kind);
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
@@ -2150,7 +2150,7 @@ static sql_rel *
sql_rel *l = rel->l;
sql_rel *r = rel->r;
/* try to push select up */
- if (!rel_is_ref(rel) && ((is_simple_project(rel->op) && !rel->r && l &&
is_select(l->op) && exps_have_freevar(v->sql, l->exps) && !rel_is_ref(l)) ||
+ if (!rel_is_ref(rel) && ((is_simple_project(rel->op) &&
!exps_have_fallible(rel->exps) && !rel->r && l && is_select(l->op) &&
exps_have_freevar(v->sql, l->exps) && !rel_is_ref(l)) ||
(is_join(rel->op) && l && is_select(l->op) &&
exps_have_freevar(v->sql, l->exps) && !rel_is_ref(l)) ||
(is_join(rel->op) && r && is_select(r->op) &&
exps_have_freevar(v->sql, r->exps) && !rel_is_ref(r)))) {
rel = push_up_select2(v, rel);
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]