Changeset: cfadf2af4862 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/cfadf2af4862
Added Files:
        sql/test/BugTracker-2024/Tests/7552-nested-expression-with-null.test
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_rewriter.c
        sql/test/BugTracker-2024/Tests/All
Branch: Aug2024
Log Message:

fixed bug #7552, improved checking for NULL's


diffs (135 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
@@ -1940,7 +1940,8 @@ exp_single_bound_cmp_exp_is_false(sql_ex
 }
 
 static inline bool
-exp_two_sided_bound_cmp_exp_is_false(sql_exp* e) {
+exp_two_sided_bound_cmp_exp_is_false(sql_exp* e)
+{
     assert(e->type == e_cmp);
     sql_exp* v = e->l;
     sql_exp* l = e->r;
@@ -1951,7 +1952,8 @@ exp_two_sided_bound_cmp_exp_is_false(sql
 }
 
 static inline bool
-exp_regular_cmp_exp_is_false(sql_exp* e) {
+exp_regular_cmp_exp_is_false(sql_exp* e)
+{
     assert(e->type == e_cmp);
 
     if (is_semantics(e) && !is_any(e)) return exp_is_cmp_exp_is_false(e);
@@ -2060,6 +2062,17 @@ exp_is_not_null(sql_exp *e)
        return false;
 }
 
+static int
+exps_have_null(list *l)
+{
+       if (!l)
+               return false;
+       for(node *n = l->h; n; n = n->next)
+               if (exp_is_null(n->data))
+                       return true;
+       return false;
+}
+
 int
 exp_is_null(sql_exp *e )
 {
@@ -2089,9 +2102,24 @@ exp_is_null(sql_exp *e )
                        }
                }
                return 0;
+       case e_cmp:
+               if (!is_semantics(e)) {
+                       if (e->flag == cmp_or) {
+                               return (exps_have_null(e->l) && 
exps_have_null(e->r));
+                       } else if (e->flag == cmp_filter) {
+                               return (exps_have_null(e->l) || 
exps_have_null(e->r));
+                       } else if (e->flag == cmp_in || e->flag == cmp_notin) {
+                               return ((e->flag == cmp_in && 
exp_is_null(e->l)) ||
+                                               (e->flag == cmp_notin && 
(exp_is_null(e->l) || exps_have_null(e->r))));
+                       } else if (e->f) {
+                               return exp_is_null(e->l) || (!is_anti(e) && 
(exp_is_null(e->r) || exp_is_null(e->f)));
+                       } else {
+                               return exp_is_null(e->l) || exp_is_null(e->r);
+                       }
+               }
+               return 0;
        case e_aggr:
        case e_column:
-       case e_cmp:
        case e_psm:
                return 0;
        }
@@ -2645,7 +2673,7 @@ exp_has_func(sql_exp *e)
 }
 
 static int
-exps_has_sideeffect( list *exps)
+exps_have_sideeffect( list *exps)
 {
        node *n;
        int has_sideeffect = 0;
@@ -2668,12 +2696,12 @@ exp_has_sideeffect( sql_exp *e )
                        if (f->func->side_effect)
                                return 1;
                        if (e->l)
-                               return exps_has_sideeffect(e->l);
+                               return exps_have_sideeffect(e->l);
                        return 0;
                }
        case e_atom:
                if (e->f)
-                       return exps_has_sideeffect(e->f);
+                       return exps_have_sideeffect(e->f);
                return 0;
        case e_aggr:
        case e_cmp:
diff --git a/sql/server/rel_rewriter.c b/sql/server/rel_rewriter.c
--- a/sql/server/rel_rewriter.c
+++ b/sql/server/rel_rewriter.c
@@ -187,7 +187,7 @@ rewrite_simplify_exp(visitor *v, sql_rel
                sql_exp *l = e->l, *r = e->r;
                if (is_func(l->type) && exp_is_true(r) && 
(is_anyequal_func(((sql_subfunc*)l->f)) || 
is_exists_func(((sql_subfunc*)l->f))))
                        return l;
-               if (is_func(l->type) && exp_is_false(r) && 
(is_anyequal_func(((sql_subfunc*)l->f)) || 
is_exists_func(((sql_subfunc*)l->f)))) {
+               if (is_func(l->type) && exp_is_false(r) && !exp_is_null(r) && 
(is_anyequal_func(((sql_subfunc*)l->f)) || 
is_exists_func(((sql_subfunc*)l->f)))) {
                        sql_subfunc *sf = l->f;
                        if (is_anyequal_func(sf))
                                return exp_in_func(v->sql, 
((list*)l->l)->h->data, ((list*)l->l)->h->next->data, !is_anyequal(sf), 0);
diff --git 
a/sql/test/BugTracker-2024/Tests/7552-nested-expression-with-null.test 
b/sql/test/BugTracker-2024/Tests/7552-nested-expression-with-null.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2024/Tests/7552-nested-expression-with-null.test
@@ -0,0 +1,19 @@
+statement ok
+CREATE TABLE  IF NOT EXISTS t0 ( c1 INT )
+
+statement ok
+INSERT INTO t0(c1) VALUES (1)
+
+query I
+SELECT * FROM t0
+----
+1
+
+query I
+SELECT ((NULL NOT BETWEEN 1 AND 2)=(t0.c1 NOT IN (t0.c1))) FROM t0
+----
+NULL
+
+query I
+SELECT * FROM t0 WHERE ((NULL NOT BETWEEN 1 AND 2)=(t0.c1 NOT IN (t0.c1)))
+----
diff --git a/sql/test/BugTracker-2024/Tests/All 
b/sql/test/BugTracker-2024/Tests/All
--- a/sql/test/BugTracker-2024/Tests/All
+++ b/sql/test/BugTracker-2024/Tests/All
@@ -75,3 +75,4 @@ 7544-startswith-bug
 7545-groupby_on_index_col
 7547-drop-login-trigger-crash
 7550-select-statistics-auth
+7552-nested-expression-with-null
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to