MonetDB: default - Splits simplify_predicate_exps into smaller f...

2025-01-20 Thread stefanos mavros via checkin-list
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 = a

MonetDB: default - Implements optimization of isnotequal equalit...

2025-01-20 Thread stefanos mavros via checkin-list
Changeset: 1054bf841c5a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/1054bf841c5a
Modified Files:
sql/server/rel_optimize_exps.c
sql/server/rel_rewriter.h
Branch: default
Log Message:

Implements optimization of isnotequal equality exp


diffs (119 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,31 +429,45 @@ reduce_scale(mvc *sql, atom *a)
 }
 
 static inline sql_exp *
-simplify_func_isnull_equals_bool(visitor *v, sql_exp *e)
+simplify_isnull_isnotnull_equals_bool(visitor *v, sql_exp *e)
 {
-   /* rewrite isnull(x) = TRUE/FALSE => x =/<> NULL */
+   /* rewrite isnull/isnotnull(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_atom(r->type) && r->l &&*/
+   /*strcmp(((atom*)r->l)->tpe.type->base.name, "boolean") != 0)*/
+   /*return e;*/
+
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))
+   if (f->func->s || (!is_isnull_func(f) && !is_isnotnull_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);
+   if (is_isnull_func(f)) {
+   /* is null on something that is never null, is always 
false */
+   ie = exp_atom_bool(v->sql->sa, 0);
+   } else if (is_isnotnull_func(f)) {
+   /* is NOT null on something that is never null, is 
always true */
+   ie = exp_atom_bool(v->sql->sa, 1);
+   }
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);
+   if (is_isnull_func(f)) {
+   /* is null on something that is always null, is always 
true */
+   ie = exp_atom_bool(v->sql->sa, 1);
+   } else if (is_isnotnull_func(f)) {
+   /* is NOT null on something that is always null, is 
always false */
+   ie = exp_atom_bool(v->sql->sa, 0);
+   }
v->changes++;
e->l = ie;
} else if (is_atom(r->type) && r->l) {
@@ -462,7 +476,8 @@ simplify_func_isnull_equals_bool(visitor
 
if (a->isnull) {
if (is_semantics(e)) {
-   /* isnull(x) = NULL -> false, isnull(x) <> NULL 
-> true */
+   /* isnull/isnotnull(x) = NULL -> false,
+* isnull/isnotnull(x) <> NULL -> true */
int flag = e->flag == cmp_notequal;
if (is_anti(e))
flag = !flag;
@@ -473,15 +488,18 @@ simplify_func_isnull_equals_bool(visitor
}
v->changes++;
} else {
+   /* case isnull/isnotnull(x) = TRUE/FALSE => x =/<> NULL 
*/
int flag = a->data.val.bval;
 
assert(list_length(args) == 1);
-   l = args->h->data;
-   if (exp_subtype(l)) {
+
+   l = ie;
+   if (exp_subtype(l)->type) {
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 (is_isnull_func(f))
+   set_anti(e);
if (e)
set_semantics(e);
v->changes++;
@@ -492,7 +510,7 @@ simplify_func_isnull_equals_bool(visitor
 }
 
 static inline sql_exp *
-simplify_func_not_over_equality_exp(visitor *v, sql_exp *e) {
+simplify_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;
@@ -755,8 +773,8 @@ rel_simplify_predicates(visitor *v, sql_
sql_exp *l = e->l;
sql_exp *r = e->r;
 
-   e = simplify_func_isnull_equals_bool(v, e);
-   e = simplify_func_not_over_equality_exp(v, e);

MonetDB: default - Adds tests for isnull-isnotnull exp optimization

2025-01-20 Thread stefanos mavros via checkin-list
Changeset: 18bb52d72122 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/18bb52d72122
Added Files:
sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
Modified Files:
sql/test/rel-optimizers/Tests/All
Branch: default
Log Message:

Adds tests for isnull-isnotnull exp optimization


diffs (83 lines):

diff --git a/sql/test/rel-optimizers/Tests/All 
b/sql/test/rel-optimizers/Tests/All
--- a/sql/test/rel-optimizers/Tests/All
+++ b/sql/test/rel-optimizers/Tests/All
@@ -15,3 +15,4 @@ merge-unions
 merge-ors-base
 merge-ors-single-col-eq-to-cmp_in
 merge-ors-multi-col-eq-to-cmp_in
+isnull-isnotnull-equality-exp
diff --git a/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test 
b/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
new file mode 100644
--- /dev/null
+++ b/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
@@ -0,0 +1,70 @@
+statement ok
+create table foo (n int, m text);
+
+statement ok
+insert into foo values (1, 'one'), (NULL, 'mighty null'), (2, 'two');
+
+query IT rowsort
+select * from foo where n is null;
+
+NULL
+mighty null
+
+query T
+plan select * from foo where n is null;
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") * = (int(2) NULL) ]
+) [ "foo"."n", "foo"."m" NOT NULL ]
+
+query IT rowsort
+select * from foo where not n is null;
+
+1
+one
+2
+two
+
+query T
+plan select * from foo where not n is null;
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") ! * = (int(2) NULL) ]
+) [ "foo"."n" NOT NULL, "foo"."m" NOT NULL ]
+
+query IT rowsort
+select * from foo where n is not null;
+
+1
+one
+2
+two
+
+query T
+plan select * from foo where n is not null;
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") ! * = (int(2) NULL) ]
+) [ "foo"."n" NOT NULL, "foo"."m" NOT NULL ]
+
+query IT rowsort
+select * from foo where not n is not null;
+
+NULL
+mighty null
+
+query T
+plan select * from foo where not n is not null;
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") * = (int(2) NULL) ]
+) [ "foo"."n", "foo"."m" NOT NULL ]
+
___
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org


MonetDB: default - Adds tests for isnull/isnotnull optimization ...

2025-01-20 Thread stefanos mavros via checkin-list
Changeset: 0e4bfabdf4b2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/0e4bfabdf4b2
Modified Files:
sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
Branch: default
Log Message:

Adds tests for isnull/isnotnull optimization cases


diffs (63 lines):

diff --git a/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test 
b/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
--- a/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
+++ b/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
@@ -68,3 +68,59 @@ project (
 | ) [ ("foo"."n") * = (int(2) NULL) ]
 ) [ "foo"."n", "foo"."m" NOT NULL ]
 
+query IT rowsort
+select * from foo where sys.isnull(n) = true
+
+NULL
+mighty null
+
+query IT rowsort
+select * from foo where sys.isnull(n) = false
+
+1
+one
+2
+two
+
+query IT rowsort
+select * from foo where sys.isnull(n) != true
+
+1
+one
+2
+two
+
+query IT rowsort
+select * from foo where sys.isnull(n) != false
+
+NULL
+mighty null
+
+query IT rowsort
+select * from foo where sys.isnotnull(n) = true
+
+1
+one
+2
+two
+
+query IT rowsort
+select * from foo where sys.isnotnull(n) = false
+
+NULL
+mighty null
+
+query IT rowsort
+select * from foo where sys.isnotnull(n) != true
+
+NULL
+mighty null
+
+query IT rowsort
+select * from foo where sys.isnotnull(n) != false
+
+1
+one
+2
+two
+
___
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org


MonetDB: default - Adds tests for isnull/isnotnull plans

2025-01-20 Thread stefanos mavros via checkin-list
Changeset: 898bfc3e4a32 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/898bfc3e4a32
Modified Files:
sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
Branch: default
Log Message:

Adds tests for isnull/isnotnull plans


diffs (125 lines):

diff --git a/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test 
b/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
--- a/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
+++ b/sql/test/rel-optimizers/Tests/isnull-isnotnull-equality-exp.test
@@ -74,6 +74,15 @@ select * from foo where sys.isnull(n) = 
 NULL
 mighty null
 
+query T
+plan select * from foo where sys.isnull(n) = true
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") * = (int(2) NULL) ]
+) [ "foo"."n", "foo"."m" NOT NULL ]
+
 query IT rowsort
 select * from foo where sys.isnull(n) = false
 
@@ -82,6 +91,15 @@ one
 2
 two
 
+query T
+plan select * from foo where sys.isnull(n) = false
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") ! * = (int(2) NULL) ]
+) [ "foo"."n" NOT NULL, "foo"."m" NOT NULL ]
+
 query IT rowsort
 select * from foo where sys.isnull(n) != true
 
@@ -90,12 +108,30 @@ one
 2
 two
 
+query T
+plan select * from foo where sys.isnull(n) != true
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") * != (int(2) NULL) ]
+) [ "foo"."n", "foo"."m" NOT NULL ]
+
 query IT rowsort
 select * from foo where sys.isnull(n) != false
 
 NULL
 mighty null
 
+query T
+plan select * from foo where sys.isnull(n) != false
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") ! * != (int(2) NULL) ]
+) [ "foo"."n", "foo"."m" NOT NULL ]
+
 query IT rowsort
 select * from foo where sys.isnotnull(n) = true
 
@@ -104,18 +140,45 @@ one
 2
 two
 
+query T
+plan select * from foo where sys.isnotnull(n) = true
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") ! * = (int(2) NULL) ]
+) [ "foo"."n" NOT NULL, "foo"."m" NOT NULL ]
+
 query IT rowsort
 select * from foo where sys.isnotnull(n) = false
 
 NULL
 mighty null
 
+query T
+plan select * from foo where sys.isnotnull(n) = false
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") * = (int(2) NULL) ]
+) [ "foo"."n", "foo"."m" NOT NULL ]
+
 query IT rowsort
 select * from foo where sys.isnotnull(n) != true
 
 NULL
 mighty null
 
+query T
+plan select * from foo where sys.isnotnull(n) != true
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") ! * != (int(2) NULL) ]
+) [ "foo"."n", "foo"."m" NOT NULL ]
+
 query IT rowsort
 select * from foo where sys.isnotnull(n) != false
 
@@ -124,3 +187,12 @@ one
 2
 two
 
+query T
+plan select * from foo where sys.isnotnull(n) != false
+
+project (
+| select (
+| | table("sys"."foo") [ "foo"."n", "foo"."m" NOT NULL ]
+| ) [ ("foo"."n") * != (int(2) NULL) ]
+) [ "foo"."n", "foo"."m" NOT NULL ]
+
___
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org


MonetDB: default - Fixes failing test because isnotnull() case w...

2025-01-20 Thread stefanos mavros via checkin-list
Changeset: b7a89741dabf for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b7a89741dabf
Modified Files:
sql/server/rel_optimize_exps.c
Branch: default
Log Message:

Fixes failing test because isnotnull() case was not handled


diffs (36 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
@@ -489,8 +489,15 @@ simplify_isnull_isnotnull_equals_bool(vi
}
v->changes++;
} else {
-   /* case isnull/isnotnull(x) = TRUE/FALSE => x =/<> NULL 
*/
-   int flag = a->data.val.bval;
+   /* case isnull(x)  = TRUE  => x  = NULL */
+   /* case isnull(x) != TRUE  => x != NULL */
+   /* case isnull(x)  = FALSE => x != NULL <-- op switch */
+   /* case isnull(x) != FALSE => x  = NULL <-- op switch */
+   /* case isnotnull(x)  = TRUE  => x != NULL <-- op 
switch */
+   /* case isnotnull(x) != TRUE  => x  = NULL <-- op 
switch */
+   /* case isnotnull(x)  = FALSE => x  = NULL */
+   /* case isnotnull(x) != FALSE => x != NULL */
+   bool bval = a->data.val.bval;
 
assert(list_length(args) == 1);
 
@@ -498,9 +505,12 @@ simplify_isnull_isnotnull_equals_bool(vi
if (exp_subtype(l)->type) {
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)
-   if (is_isnull_func(f))
+   if (e) {
+   if (bval == false && is_isnull_func(f))
set_anti(e);
+   if (bval == true && 
is_isnotnull_func(f))
+   set_anti(e);
+   }
if (e)
set_semantics(e);
v->changes++;
___
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org