From 6ed9c1364302ea998aa265e67aa7714dc3f365c2 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 18 Nov 2011 09:35:51 -0800 Subject: [PATCH] Fixed LP bug #891953. Due to this bug the function SEL_IMERGE::or_sel_tree_with_checks() could build an inconsistent merge tree if one of the SEL_TREEs in the resulting index merge happened to contain a full key range. This could trigger an assertion failure. --- mysql-test/r/range_vs_index_merge.result | 13 +++++++++++++ mysql-test/r/range_vs_index_merge_innodb.result | 13 +++++++++++++ mysql-test/t/range_vs_index_merge.test | 15 +++++++++++++++ sql/opt_range.cc | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index cd5f0848ea7..933da379640 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1427,4 +1427,17 @@ WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); a b c DROP TABLE t1; +CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX idx(b)); +INSERT INTO t1 VALUES (167,9999), (168,10000); +EXPLAIN +SELECT * FROM t1 +WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY,idx NULL NULL NULL 2 Using where +SELECT * FROM t1 +WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2; +a b +167 9999 +168 10000 +DROP TABLE t1; set session optimizer_switch='index_merge_sort_intersection=default'; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 62199e9b4ab..166177a9ccc 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1428,5 +1428,18 @@ WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); a b c DROP TABLE t1; +CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX idx(b)); +INSERT INTO t1 VALUES (167,9999), (168,10000); +EXPLAIN +SELECT * FROM t1 +WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,idx PRIMARY 0 NULL 1 Using where +SELECT * FROM t1 +WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2; +a b +167 9999 +168 10000 +DROP TABLE t1; set session optimizer_switch='index_merge_sort_intersection=default'; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index f1bf9d9026f..de7e6a0838c 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -1074,6 +1074,21 @@ SELECT * FROM t1 DROP TABLE t1; +# +# LP bug #891953: always true OR +# + +CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX idx(b)); +INSERT INTO t1 VALUES (167,9999), (168,10000); + +EXPLAIN +SELECT * FROM t1 + WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2; +SELECT * FROM t1 + WHERE a BETWEEN 4 AND 5 AND b IN (255,4) OR a IN (2,14,25) OR a!=2; + +DROP TABLE t1; + #the following command must be the last one in the file set session optimizer_switch='index_merge_sort_intersection=default'; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 229c1e2861b..71bb2157a39 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1208,13 +1208,13 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, if (result) { + result->keys_map= result_keys; if (result_keys.is_clear_all()) result->type= SEL_TREE::ALWAYS; if ((result->type == SEL_TREE::MAYBE) || (result->type == SEL_TREE::ALWAYS)) return 1; /* SEL_TREE::IMPOSSIBLE is impossible here */ - result->keys_map= result_keys; *or_tree= result; was_ored= TRUE; }