Changeset: f504b13cfd82 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/f504b13cfd82
Modified Files:
        sql/server/rel_optimizer.c
Branch: antipush
Log Message:

I forgot to check for upcasts on the (a = b) or (a is null and b is null) -> a 
= b with null semantics optimization


diffs (119 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
@@ -3648,9 +3648,24 @@ merge_notequal(mvc *sql, list *exps, int
        return nexps;
 }
 
+static int
+is_numeric_upcast(sql_exp *e)
+{
+       if (is_convert(e->type)) {
+               sql_subtype *f = exp_fromtype(e);
+               sql_subtype *t = exp_totype(e);
+
+               if (f->type->eclass == t->type->eclass && 
EC_COMPUTE(f->type->eclass)) {
+                       if (f->type->localtype < t->type->localtype)
+                               return 1;
+               }
+       }
+       return 0;
+}
+
 /* optimize (a = b) or (a is null and b is null) -> a = b with null semantics 
*/
 static sql_exp *
-try_rewrite_equal_or_is_null(mvc *sql, sql_exp *or, list *l1, list *l2)
+try_rewrite_equal_or_is_null(mvc *sql, sql_rel *rel, sql_exp *or, list *l1, 
list *l2)
 {
        if (list_length(l1) == 1) {
                bool valid = true, first_is_null_found = false, 
second_is_null_found = false;
@@ -3658,14 +3673,17 @@ try_rewrite_equal_or_is_null(mvc *sql, s
                sql_exp *first = cmp->l, *second = cmp->r;
 
                if (is_compare(cmp->type) && !is_anti(cmp) && !cmp->f && 
cmp->flag == cmp_equal) {
+                       int fupcast = is_numeric_upcast(first), supcast = 
is_numeric_upcast(second);
                        for(node *n = l2->h ; n && valid; n = n->next) {
-                               sql_exp *e = n->data;
+                               sql_exp *e = n->data, *l = e->l;
 
                                if (is_compare(e->type) && e->flag == cmp_equal 
&& !e->f &&
                                        !is_anti(e) && is_semantics(e) && 
exp_is_null(e->r)) {
-                                       if (exp_match_exp(first, e->l))
+                                       int lupcast = is_numeric_upcast(l);
+
+                                       if 
(exp_match_exp(fupcast?first->l:first, lupcast?l->l:l))
                                                first_is_null_found = true;
-                                       else if (exp_match_exp(second, e->l))
+                                       else if 
(exp_match_exp(supcast?second->l:second, lupcast?l->l:l))
                                                second_is_null_found = true;
                                        else
                                                valid = false;
@@ -3674,6 +3692,15 @@ try_rewrite_equal_or_is_null(mvc *sql, s
                                }
                        }
                        if (valid && first_is_null_found && 
second_is_null_found) {
+                               sql_subtype super;
+
+                               supertype(&super, exp_subtype(first), 
exp_subtype(second)); /* first and second must have the same type */
+                               if (!(first = exp_check_type(sql, &super, rel, 
first, type_equal)) ||
+                                       !(second = exp_check_type(sql, &super, 
rel, second, type_equal))) {
+                                               sql->session->status = 0;
+                                               sql->errstr[0] = 0;
+                                               return or;
+                                       }
                                sql_exp *res = exp_compare(sql->sa, first, 
second, cmp->flag);
                                set_semantics(res);
                                if (exp_name(or))
@@ -3686,18 +3713,18 @@ try_rewrite_equal_or_is_null(mvc *sql, s
 }
 
 static list *
-merge_cmp_or_null(mvc *sql, list *exps, int *changes)
+merge_cmp_or_null(mvc *sql, sql_rel *rel, list *exps, int *changes)
 {
        for (node *n = exps->h; n ; n = n->next) {
                sql_exp *e = n->data;
 
                if (is_compare(e->type) && e->flag == cmp_or && !is_anti(e)) {
-                       sql_exp *ne = try_rewrite_equal_or_is_null(sql, e, 
e->l, e->r);
+                       sql_exp *ne = try_rewrite_equal_or_is_null(sql, rel, e, 
e->l, e->r);
                        if (ne != e) {
                                (*changes)++;
                                n->data = ne;
                        }
-                       ne = try_rewrite_equal_or_is_null(sql, e, e->r, e->l);
+                       ne = try_rewrite_equal_or_is_null(sql, rel, e, e->r, 
e->l);
                        if (ne != e) {
                                (*changes)++;
                                n->data = ne;
@@ -3717,7 +3744,7 @@ rel_select_cse(visitor *v, sql_rel *rel)
                rel->exps = merge_notequal(v->sql, rel->exps, &v->changes); /* 
x <> 1 and x <> 2 => x not in (1, 2)*/
 
        if ((is_select(rel->op) || is_join(rel->op) || is_semi(rel->op)) && 
rel->exps)
-               rel->exps = merge_cmp_or_null(v->sql, rel->exps, &v->changes); 
/* (a = b) or (a is null and b is null) -> a = b with null semantics */
+               rel->exps = merge_cmp_or_null(v->sql, rel, rel->exps, 
&v->changes); /* (a = b) or (a is null and b is null) -> a = b with null 
semantics */
 
        if ((is_select(rel->op) || is_join(rel->op) || is_semi(rel->op)) && 
rel->exps) {
                node *n;
@@ -3912,21 +3939,6 @@ exps_merge_select_rse( mvc *sql, list *l
        return nexps;
 }
 
-static int
-is_numeric_upcast(sql_exp *e)
-{
-       if (is_convert(e->type)) {
-               sql_subtype *f = exp_fromtype(e);
-               sql_subtype *t = exp_totype(e);
-
-               if (f->type->eclass == t->type->eclass && 
EC_COMPUTE(f->type->eclass)) {
-                       if (f->type->localtype < t->type->localtype)
-                               return 1;
-               }
-       }
-       return 0;
-}
-
 static sql_exp *
 rel_merge_project_rse(visitor *v, sql_rel *rel, sql_exp *e, int depth)
 {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to