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 -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org