Changeset: 5ea5bee7dcd2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/5ea5bee7dcd2
Added Files:
sql/test/BugTracker-2024/Tests/7554-incorrect-result-between.test
sql/test/BugTracker-2024/Tests/7555-incorrect-semijoin-rewrite.test
Modified Files:
sql/server/rel_exp.c
sql/server/rel_exp.h
sql/server/rel_optimize_exps.c
sql/server/rel_rewriter.c
sql/server/rel_statistics.c
sql/test/BugTracker-2024/Tests/All
Branch: Aug2024
Log Message:
added tests for bugs #7554 and #7555
fixed #7554, properly handle exp_is_null vs exp_is_not_null
fixed #7555, exp_has_func should return true on exp_convert (on down casting)
diffs (168 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
@@ -1956,7 +1956,8 @@ exp_is_cmp_exp_is_false(sql_exp* e)
}
static inline bool
-exp_single_bound_cmp_exp_is_false(sql_exp* e) {
+exp_single_bound_cmp_exp_is_false(sql_exp* e)
+{
assert(e->type == e_cmp);
sql_exp* l = e->l;
sql_exp* r = e->r;
@@ -1990,7 +1991,8 @@ exp_regular_cmp_exp_is_false(sql_exp* e)
}
static inline bool
-exp_or_exp_is_false(sql_exp* e) {
+exp_or_exp_is_false(sql_exp* e)
+{
assert(e->type == e_cmp && e->flag == cmp_or);
list* left = e->l;
@@ -2018,7 +2020,8 @@ exp_or_exp_is_false(sql_exp* e) {
}
static inline bool
-exp_cmp_exp_is_false(sql_exp* e) {
+exp_cmp_exp_is_false(sql_exp* e)
+{
assert(e->type == e_cmp);
switch (e->flag) {
@@ -2137,7 +2140,7 @@ exp_is_null(sql_exp *e )
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)));
+ return exp_is_null(e->l) && exp_is_null(e->r)
&& exp_is_null(e->f);
} else {
return exp_is_null(e->l) || exp_is_null(e->r);
}
@@ -2666,6 +2669,14 @@ exp_has_func_or_cmp(sql_exp *e, bool cmp
return exps_have_func_or_cmp(e->f, true);
return 0;
case e_convert:
+ {
+ sql_subtype *t = exp_totype(e);
+ sql_subtype *f = exp_fromtype(e);
+ if (t->type->eclass == EC_FLT && (f->type->eclass ==
EC_DEC || f->type->eclass == EC_NUM))
+ return exp_has_func_or_cmp(e->l, cmp);
+ if (f->type->localtype > t->type->localtype)
+ return true;
+ }
return exp_has_func_or_cmp(e->l, cmp);
case e_func:
return 1;
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -160,6 +160,7 @@ extern int exp_is_join(sql_exp *e, list
extern int exp_is_eqjoin(sql_exp *e);
extern int exp_is_join_exp(sql_exp *e);
extern int exp_is_atom(sql_exp *e);
+/* exp_is_true/false etc return true if the expression is true, on unknown etc
false is returned */
extern int exp_is_true(sql_exp *e);
extern int exp_is_false(sql_exp *e);
extern int exp_is_zero(sql_exp *e);
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
@@ -456,7 +456,7 @@ rel_simplify_predicates(visitor *v, sql_
sql_exp *le = n->data;
sql_exp *re = n->next->data;
- if (exp_is_atom(le) && !exp_is_null(le) && exp_is_atom(re) &&
le->type == e_atom && le->l && re->type == e_atom && re->l) {
+ if (exp_is_atom(le) && exp_is_not_null(le) && exp_is_atom(re)
&& le->type == e_atom && le->l && re->type == e_atom && re->l) {
n = n->next->next;
if (exp_match_exp(le, re)) { /* x==y -> a */
sql_exp *res = n->data;
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) && !exp_is_null(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_not_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/server/rel_statistics.c b/sql/server/rel_statistics.c
--- a/sql/server/rel_statistics.c
+++ b/sql/server/rel_statistics.c
@@ -1101,11 +1101,11 @@ rel_get_statistics_(visitor *v, sql_rel
if (lv != BUN_NONE) {
sql_exp *le = rel->exps->h->data, *oe =
list_length(rel->exps) > 1 ? rel->exps->h->next->data : NULL;
- if (oe && oe->l && !exp_is_null(oe)) { /* no parameters
*/
+ if (oe && oe->l && exp_is_not_null(oe)) { /* no
parameters */
BUN offset = (BUN)
((atom*)oe->l)->data.val.lval;
lv = offset >= lv ? 0 : lv - offset;
}
- if (le->l && !exp_is_null(le)) {
+ if (le->l && exp_is_not_null(le)) {
BUN limit = (BUN) ((atom*)le->l)->data.val.lval;
lv = MIN(lv, limit);
}
diff --git a/sql/test/BugTracker-2024/Tests/7554-incorrect-result-between.test
b/sql/test/BugTracker-2024/Tests/7554-incorrect-result-between.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2024/Tests/7554-incorrect-result-between.test
@@ -0,0 +1,8 @@
+query T
+SELECT (1 BETWEEN NULL AND -1) IS NULL
+----
+False
+
+query I
+SELECT 1 WHERE ((1 BETWEEN NULL AND -1) IS NULL)
+----
diff --git
a/sql/test/BugTracker-2024/Tests/7555-incorrect-semijoin-rewrite.test
b/sql/test/BugTracker-2024/Tests/7555-incorrect-semijoin-rewrite.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2024/Tests/7555-incorrect-semijoin-rewrite.test
@@ -0,0 +1,32 @@
+statement ok
+CREATE TABLE t1 (c1 BOOLEAN)
+
+statement ok
+CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0) )
+
+statement ok
+INSERT INTO t1(c1) VALUES (true)
+
+statement ok
+INSERT INTO t0(c0) VALUES (2)
+
+statement ok
+INSERT INTO t0(c0) VALUES (1)
+
+query T
+SELECT t1.c1 FROM t0, t1 WHERE (NOT (t1.c1 != CAST(t0.c0 AS BOOLEAN)))
+----
+True
+True
+
+query T
+SELECT t1.c1 FROM t0, t1 WHERE (NOT (t1.c1 != CAST(t0.c0 AS BOOLEAN))) UNION
ALL SELECT t1.c1 FROM t0, t1 WHERE (t1.c1 != CAST(t0.c0 AS BOOLEAN))
+----
+True
+True
+
+statement ok
+DROP table t0
+
+statement ok
+DROP table t1
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
@@ -78,3 +78,5 @@ 7550-select-statistics-auth
7552-nested-expression-with-null
7553-join-on-startswith-crash
7045-do-not-push-down-converts
+7554-incorrect-result-between
+7555-incorrect-semijoin-rewrite
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]