Changeset: 6f4701853169 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/6f4701853169
Modified Files:
sql/server/rel_optimize_exps.c
Branch: default
Log Message:
Splits simplify_predicate_exps into smaller functions
diffs (256 lines):
diff --git a/sql/server/rel_optimize_exps.c b/sql/server/rel_optimize_exps.c
--- a/sql/server/rel_optimize_exps.c
+++ b/sql/server/rel_optimize_exps.c
@@ -429,6 +429,139 @@ reduce_scale(mvc *sql, atom *a)
}
static inline sql_exp *
+simplify_func_isnull_equals_bool(visitor *v, sql_exp *e)
+{
+ /* rewrite isnull(x) = TRUE/FALSE => x =/<> NULL */
+ if (!(is_compare(e->type) && (e->flag == cmp_equal || e->flag ==
cmp_notequal)))
+ return e;
+ sql_exp *l = e->l;
+ sql_exp *r = e->r;
+
+ if (!is_func(l->type))
+ return e;
+ sql_subfunc *f = l->f;
+ list *args = l->l;
+ sql_exp *ie = args->h->data;
+
+ if (f->func->s || !is_isnull_func(f))
+ return e;
+
+ if (!has_nil(ie) || exp_is_not_null(ie)) {
+ /* is null on something that is never null, is always false */
+ ie = exp_atom_bool(v->sql->sa, 0);
+ v->changes++;
+ e->l = ie;
+ } else if (exp_is_null(ie)) {
+ /* is null on something that is always null, is always true */
+ ie = exp_atom_bool(v->sql->sa, 1);
+ v->changes++;
+ e->l = ie;
+ } else if (is_atom(r->type) && r->l) {
+ /* direct literal */
+ atom *a = r->l;
+
+ if (a->isnull) {
+ if (is_semantics(e)) {
+ /* isnull(x) = NULL -> false, isnull(x) <> NULL
-> true */
+ int flag = e->flag == cmp_notequal;
+ if (is_anti(e))
+ flag = !flag;
+ e = exp_atom_bool(v->sql->sa, flag);
+ } else {
+ /* always NULL */
+ e = exp_null(v->sql->sa,
sql_bind_localtype("bit"));
+ }
+ v->changes++;
+ } else {
+ int flag = a->data.val.bval;
+
+ assert(list_length(args) == 1);
+ l = args->h->data;
+ if (exp_subtype(l)) {
+ r = exp_atom(v->sql->sa,
atom_general(v->sql->sa, exp_subtype(l), NULL, 0));
+ e = exp_compare(v->sql->sa, l, r, e->flag);
+ if (e && !flag)
+ set_anti(e);
+ if (e)
+ set_semantics(e);
+ v->changes++;
+ }
+ }
+ }
+ return e;
+}
+
+static inline sql_exp *
+simplify_func_not_over_equality_exp(visitor *v, sql_exp *e) {
+ if (!(is_compare(e->type) && (e->flag == cmp_equal || e->flag ==
cmp_notequal)))
+ return e;
+ sql_exp *l = e->l;
+ sql_exp *r = e->r;
+
+ if (!is_func(l->type))
+ return e;
+ sql_subfunc *f = l->f;
+
+ if (f->func->s || !is_not_func(f))
+ return e;
+
+ if (is_atom(r->type) && r->l) {
+ /* direct literal */
+ atom *a = r->l;
+ list *args = l->l;
+ sql_exp *inner = args->h->data;
+ sql_subfunc *inf = inner->f;
+
+ assert(list_length(args) == 1);
+
+ if (is_func(inner->type) && !inf->func->s && is_not_func(inf)) {
+ /* not(not(x)) = TRUE/FALSE => x = TRUE/FALSE */
+ int anti = is_anti(e), is_semantics = is_semantics(e);
+
+ args = inner->l;
+ assert(list_length(args) == 1);
+ l = args->h->data;
+ e = exp_compare(v->sql->sa, l, r, e->flag);
+ if (anti) set_anti(e);
+ if (is_semantics) set_semantics(e);
+ v->changes++;
+ } else if (is_func(inner->type) && !inf->func->s &&
+ (!strcmp(inf->func->base.name, "=") ||
!strcmp(inf->func->base.name, "<>"))) {
+ /* rewrite not(=/<>(a,b)) = TRUE/FALSE => a=b / a<>b */
+ int flag = a->data.val.bval;
+ sql_exp *ne;
+ args = inner->l;
+
+ if (!strcmp(inf->func->base.name, "<>"))
+ flag = !flag;
+ if (e->flag == cmp_notequal)
+ flag = !flag;
+ assert(list_length(args) == 2);
+ l = args->h->data;
+ r = args->h->next->data;
+ ne = exp_compare(v->sql->sa, l, r,
(!flag)?cmp_equal:cmp_notequal);
+ if (a->isnull)
+ e->l = ne;
+ else
+ e = ne;
+ v->changes++;
+ } else if (a && a->data.vtype == TYPE_bit) {
+ int anti = is_anti(e), is_semantics = is_semantics(e);
+
+ /* change atom's value on right */
+ l = args->h->data;
+ if (!a->isnull)
+ r = exp_atom_bool(v->sql->sa,
!a->data.val.bval);
+ e = exp_compare(v->sql->sa, l, r, e->flag);
+ if (anti) set_anti(e);
+ if (is_semantics) set_semantics(e);
+ v->changes++;
+ }
+ }
+ return e;
+}
+
+static inline sql_exp *
rel_simplify_predicates(visitor *v, sql_rel *rel, sql_exp *e)
{
if (is_func(e->type) && list_length(e->l) == 3 &&
is_case_func((sql_subfunc*)e->f)) {
@@ -622,109 +755,10 @@ rel_simplify_predicates(visitor *v, sql_
sql_exp *l = e->l;
sql_exp *r = e->r;
- if (is_func(l->type) && (e->flag == cmp_equal ||
e->flag == cmp_notequal)) {
- sql_subfunc *f = l->f;
-
- /* rewrite isnull(x) = TRUE/FALSE => x =/<>
NULL */
- if (!f->func->s && is_isnull_func(f)) {
- list *args = l->l;
- sql_exp *ie = args->h->data;
-
- if (!has_nil(ie) ||
exp_is_not_null(ie)) { /* is null on something that is never null, is always
false */
- ie = exp_atom_bool(v->sql->sa,
0);
- v->changes++;
- e->l = ie;
- } else if (exp_is_null(ie)) { /* is
null on something that is always null, is always true */
- ie = exp_atom_bool(v->sql->sa,
1);
- v->changes++;
- e->l = ie;
- } else if (is_atom(r->type) && r->l) {
/* direct literal */
- atom *a = r->l;
-
- if (a->isnull) {
- if (is_semantics(e)) {
/* isnull(x) = NULL -> false, isnull(x) <> NULL -> true */
- int flag =
e->flag == cmp_notequal;
- if (is_anti(e))
- flag =
!flag;
- e =
exp_atom_bool(v->sql->sa, flag);
- } else /* always NULL */
- e =
exp_null(v->sql->sa, sql_bind_localtype("bit"));
- v->changes++;
- } else {
- int flag =
a->data.val.bval;
-
-
assert(list_length(args) == 1);
- l = args->h->data;
- if (exp_subtype(l)) {
- r =
exp_atom(v->sql->sa, atom_general(v->sql->sa, exp_subtype(l), NULL, 0));
- e =
exp_compare(v->sql->sa, l, r, e->flag);
- if (e && !flag)
-
set_anti(e);
- if (e)
-
set_semantics(e);
- v->changes++;
- }
- }
- }
- } else if (!f->func->s && is_not_func(f)) {
- if (is_atom(r->type) && r->l) { /*
direct literal */
- atom *a = r->l;
- list *args = l->l;
- sql_exp *inner = args->h->data;
- sql_subfunc *inf = inner->f;
+ e = simplify_func_isnull_equals_bool(v, e);
+ e = simplify_func_not_over_equality_exp(v, e);
- assert(list_length(args) == 1);
-
- /* not(not(x)) = TRUE/FALSE =>
x = TRUE/FALSE */
- if (is_func(inner->type) &&
- !inf->func->s &&
- is_not_func(inf)) {
- int anti = is_anti(e),
is_semantics = is_semantics(e);
-
- args = inner->l;
-
assert(list_length(args) == 1);
- l = args->h->data;
- e =
exp_compare(v->sql->sa, l, r, e->flag);
- if (anti) set_anti(e);
- if (is_semantics)
set_semantics(e);
- v->changes++;
- /* rewrite not(=/<>(a,b)) =
TRUE/FALSE => a=b / a<>b */
- } else if (is_func(inner->type)
&&
- !inf->func->s &&
-
(!strcmp(inf->func->base.name, "=") ||
-
!strcmp(inf->func->base.name, "<>"))) {
- int flag =
a->data.val.bval;
- sql_exp *ne;
- args = inner->l;
-
- if
(!strcmp(inf->func->base.name, "<>"))
- flag = !flag;
- if (e->flag ==
cmp_notequal)
- flag = !flag;
-
assert(list_length(args) == 2);
- l = args->h->data;
- r = args->h->next->data;
- ne =
exp_compare(v->sql->sa, l, r, (!flag)?cmp_equal:cmp_notequal);
- if (a->isnull)
- e->l = ne;
- else
- e = ne;
- v->changes++;
- } else if (a && a->data.vtype
== TYPE_bit) {
- int anti = is_anti(e),
is_semantics = is_semantics(e);
-
- /* change atom's value
on right */
- l = args->h->data;
- if (!a->isnull)
- r =
exp_atom_bool(v->sql->sa, !a->data.val.bval);
- e =
exp_compare(v->sql->sa, l, r, e->flag);
- if (anti) set_anti(e);
- if (is_semantics)
set_semantics(e);
- v->changes++;
- }
- }
- }
- } else if (is_atom(l->type) && is_atom(r->type) &&
!is_semantics(e) && !is_any(e) && !e->f) {
+ if (is_atom(l->type) && is_atom(r->type) &&
!is_semantics(e) && !is_any(e) && !e->f) {
/* compute comparisons on atoms */
if (exp_is_null(l) || exp_is_null(r)) {
e = exp_null(v->sql->sa,
sql_bind_localtype("bit"));
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]