summaryrefslogtreecommitdiff
path: root/mysql-test/t/range.test
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-08-24 19:51:32 +0400
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-08-24 19:51:32 +0400
commit756076bd23d9e194d5730745d07ee86aa543d4e5 (patch)
treed51bc34d86979999da310f2aa07b4fd57c7e5581 /mysql-test/t/range.test
parent6973c354de11570f5575abdbd40bb47dce636d34 (diff)
downloadmariadb-git-756076bd23d9e194d5730745d07ee86aa543d4e5.tar.gz
Bug #54802: 'NOT BETWEEN' evaluation is incorrect
Queries involving predicates of the form "const NOT BETWEEN not_indexed_column AND indexed_column" could return wrong data due to incorrect handling by the range optimizer. For "c NOT BETWEEN f1 AND f2" predicates, get_mm_tree() produces a disjunction of the SEL_ARG trees for "f1 > c" and "f2 < c". If one of the trees is empty (i.e. one of the arguments is not sargable) the resulting tree should be empty as well, since the whole expression in this case is not sargable. The above logic is implemented in get_mm_tree() as follows. The initial state of the resulting tree is NULL (aka empty). We then iterate through arguments and compute the corresponding SEL_ARG tree (either "f1 > c" or "f2 < c"). If the resulting tree is NULL, it is simply replaced by the generated tree. Otherwise it is replaced by a disjunction of itself and the generated tree. The obvious flaw in this implementation is that if the first argument is not sargable and thus produces a NULL tree, the resulting tree will simply be replaced by the tree for the second argument. As a result, "c NOT BETWEEN f1 AND f2" will end up as just "f2 < c". Fixed by adding a check so that when the first argument produces an empty tree for the NOT BETWEEN case, the loop is aborted with an empty tree as a result. The whole idea of using a loop for 2 arguments does not make much sense, but it was probably used to avoid code duplication for several BETWEEN variants.
Diffstat (limited to 'mysql-test/t/range.test')
-rw-r--r--mysql-test/t/range.test12
1 files changed, 12 insertions, 0 deletions
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 5d5ad180f1a..0ad3d3e8504 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1313,4 +1313,16 @@ SELECT * FROM t1 FORCE INDEX (PRIMARY)
DROP TABLE t1;
+--echo #
+--echo # Bug #54802: 'NOT BETWEEN' evaluation is incorrect
+--echo #
+
+CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+
+EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+
+DROP TABLE t1;
+
--echo End of 5.1 tests