Changeset: ffd1b69a0993 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ffd1b69a0993
Branch: default
Log Message:

merge with distinct_from


diffs (266 lines):

diff --git a/sql/ChangeLog b/sql/ChangeLog
--- a/sql/ChangeLog
+++ b/sql/ChangeLog
@@ -1,6 +1,11 @@
 # ChangeLog file for sql
 # This file is updated with Maddlog
 
+* Thu Mar 21 2024 Yunus Koning <yunus.kon...@monetdbsolutions.com>
+- Introduce IS [NOT] DISTINCT FROM syntax. The syntax allows two values
+  to be compared. The comparison always returns boolean FALSE or TRUE
+  never NULL.
+
 * Wed Mar  6 2024 Yunus Koning <yunus.kon...@monetdbsolutions.com>
 - SQL2023 feature: Introduce UNIQUE NULLS [NOT] DISTINCT syntax which
   allows for NULLS to be treated as unique, i.e. a column with this
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -1831,8 +1831,8 @@ exp_bin(backend *be, sql_exp *e, stmt *l
                                                                                
                   tail_type(l), tail_type(l), F_FUNC, true, true);
                                        assert(f);
                                        if (is_semantics(e)) {
-                                               if (exp_is_null(e->l) && 
exp_is_null(e->r)) {
-                                                       s = stmt_bool(be, 
!is_anti(e));
+                                               if (exp_is_null(e->l) && 
exp_is_null(e->r) && (e->flag == cmp_equal || e->flag == cmp_notequal)) {
+                                                       s = stmt_bool(be, 
e->flag == cmp_equal ? !is_anti(e): is_anti(e));
                                                } else {
                                                        list *args = 
sa_list(sql->sa);
                                                        if (args == NULL)
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -2367,6 +2367,8 @@ rel_logical_value_exp(sql_query *query, 
                int quantifier = 0, need_not = 0;
                sql_exp *rs = NULL, *ls;
                comp_type cmp_type = compare_str2type(compare_op);
+               bool is_not_distinct_from = false;
+               bool is_distinct_from = false;
 
                /*
                 * = ANY -> IN, <> ALL -> NOT( = ANY) -> NOT IN
@@ -2374,7 +2376,17 @@ rel_logical_value_exp(sql_query *query, 
                 */
                if (n->next->next->next)
                        quantifier = n->next->next->next->data.i_val + 1;
-               assert(quantifier == 0 || quantifier == 1 || quantifier == 2);
+               assert(quantifier == 0 || quantifier == 1 || quantifier == 2 || 
quantifier == 3 || quantifier == 4);
+
+               /* [NOT] DISTINCT FROM */
+               if (quantifier == 3) {
+                               is_not_distinct_from = true;
+                               quantifier = 0;
+               }
+               else if (quantifier == 4) {
+                               is_distinct_from = true;
+                               quantifier = 0;
+               }
 
                if ((quantifier == 1 && cmp_type == cmp_equal) ||
                    (quantifier == 2 && cmp_type == cmp_notequal)) {
@@ -2405,6 +2417,15 @@ rel_logical_value_exp(sql_query *query, 
                rs = rel_value_exp(query, rel, ro, f|sql_farg, ek);
                if (!rs)
                        return NULL;
+
+               if (is_distinct_from || is_not_distinct_from) {
+                       if (rel_convert_types(sql, rel ? *rel : NULL, rel ? 
*rel : NULL, &ls, &rs, 1, type_equal_no_any) < 0)
+                               return NULL;
+                       sql_exp* e = exp_compare(sql->sa, ls, rs, 
is_not_distinct_from?cmp_equal:cmp_notequal);
+                       set_semantics(e);
+                       return e;
+               }
+
                if (rs->type == e_atom)
                        quantifier = 0;
 
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -3909,6 +3909,20 @@ comparison_predicate:
                  append_symbol(l, $5);
                  append_int(l, $3);
                  $$ = _symbol_create_list(SQL_COMPARE, l ); }
+ |     pred_exp IS NOT DISTINCT FROM pred_exp
+               { dlist *l = L();
+                 append_symbol(l, $1);
+                 append_string(l, sa_strdup(SA, "="));
+                 append_symbol(l, $6);
+                 append_int(l, 2);
+                 $$ = _symbol_create_list(SQL_COMPARE, l ); }
+ |     pred_exp IS DISTINCT FROM pred_exp
+               { dlist *l = L();
+                 append_symbol(l, $1);
+                 append_string(l, sa_strdup(SA, "="));
+                 append_symbol(l, $5);
+                 append_int(l, 3);
+                 $$ = _symbol_create_list(SQL_COMPARE, l ); }
  ;
 
 between_predicate:
diff --git a/sql/test/2024/Tests/All b/sql/test/2024/Tests/All
--- a/sql/test/2024/Tests/All
+++ b/sql/test/2024/Tests/All
@@ -1,1 +1,2 @@
 groupby_primary_key_project_unique_key
+distinct_from
diff --git a/sql/test/2024/Tests/distinct_from.test 
b/sql/test/2024/Tests/distinct_from.test
new file mode 100644
--- /dev/null
+++ b/sql/test/2024/Tests/distinct_from.test
@@ -0,0 +1,143 @@
+
+query I nosort
+SELECT 10 IS NOT DISTINCT FROM 20
+----
+0
+
+query I nosort
+SELECT 10 IS DISTINCT FROM 20
+----
+1
+
+
+query I nosort
+SELECT 10 IS DISTINCT FROM NULL
+----
+1
+
+query I nosort
+SELECT NULL IS DISTINCT FROM 20
+----
+1
+
+query I nosort
+SELECT 10 IS NOT DISTINCT FROM NULL
+----
+0
+
+query I nosort
+SELECT NULL IS NOT DISTINCT FROM 20
+----
+0
+
+query I nosort
+SELECT NULL IS DISTINCT FROM NULL
+----
+0
+
+query I nosort
+SELECT NULL IS NOT DISTINCT FROM NULL
+----
+1
+
+statement ok
+create table foo(s) as values (10), (20), (NULL)
+
+query I nosort
+select s IS NOT DISTINCT FROM 20 FROM foo;
+----
+0
+1
+0
+
+query I nosort
+select s IS DISTINCT FROM 20 FROM foo;
+----
+1
+0
+1
+
+query I nosort
+select s IS NOT DISTINCT FROM NULL FROM foo;
+----
+0
+0
+1
+
+query I nosort
+select s IS DISTINCT FROM NULL FROM foo;
+----
+1
+1
+0
+
+query I nosort
+select 20 IS NOT DISTINCT FROM s FROM foo;
+----
+0
+1
+0
+
+query I nosort
+select 20 IS DISTINCT FROM s FROM foo;
+----
+1
+0
+1
+
+query I nosort
+select NULL IS NOT DISTINCT FROM s FROM foo;
+----
+0
+0
+1
+
+query I nosort
+select NULL IS DISTINCT FROM s FROM foo;
+----
+1
+1
+0
+
+statement ok
+create table bar(s) as values (20), (30), (NULL)
+
+query IIII rowsort
+select foo.s, bar.s, foo.s IS DISTINCT FROM bar.s, foo.s IS NOT DISTINCT FROM 
bar.s FROM foo, bar
+----
+10
+20
+1
+0
+10
+30
+1
+0
+10
+NULL
+1
+0
+20
+20
+0
+1
+20
+30
+1
+0
+20
+NULL
+1
+0
+NULL
+20
+1
+0
+NULL
+30
+1
+0
+NULL
+NULL
+0
+1
diff --git 
a/sql/test/sys-schema/Tests/webExamplesComparisonFunctionsOperators.test 
b/sql/test/sys-schema/Tests/webExamplesComparisonFunctionsOperators.test
--- a/sql/test/sys-schema/Tests/webExamplesComparisonFunctionsOperators.test
+++ b/sql/test/sys-schema/Tests/webExamplesComparisonFunctionsOperators.test
@@ -920,7 +920,7 @@ select 'db' not between SYMMETRIC 'db' a
 ----
 0
 
-statement error
+statement ok
 select 'a' IS DISTINCT FROM 'b' as tru
 
 query I rowsort
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to