From bfb7727526b2081074325142b7a84426c89531fa Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 4 Dec 2010 19:19:55 -0800 Subject: [PATCH] Fixed LP bug #684117. A crash may happenin the cases when the range optimizer tried to OR two index merge such that the second one contained less range trees than the first one. The bug was introduced by the patch of MWL#24: "index_merge: fair choice between index_merge union and range access". --- mysql-test/r/range_vs_index_merge.result | 12 ++++++++++++ mysql-test/r/range_vs_index_merge_innodb.result | 12 ++++++++++++ mysql-test/t/range_vs_index_merge.test | 16 ++++++++++++++++ sql/opt_range.cc | 3 ++- 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 b616afc9578..1f5d2564be2 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1314,4 +1314,16 @@ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,PRIMARY,idx1 67,13,4,3 NULL 8 Using sort_union(idx3,idx2,PRIMARY,idx1); Using where DROP TABLE t1; +CREATE TABLE t1 ( +f1 int, f2 int, f3 int, f4 int, f5 int, +PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); +SELECT f5 FROM t1 +WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR +f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); +f5 +5 +NULL +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 037e23eae5d..8a373115522 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1315,5 +1315,17 @@ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,idx1,PRIMARY 67,13,3,4 NULL 9 Using sort_union(idx3,idx2,idx1,PRIMARY); Using where DROP TABLE t1; +CREATE TABLE t1 ( +f1 int, f2 int, f3 int, f4 int, f5 int, +PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); +SELECT f5 FROM t1 +WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR +f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); +f5 +5 +NULL +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 d63a88ebf74..036d8837d0b 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -925,6 +925,22 @@ SELECT COUNT(*) FROM t1 DROP TABLE t1; +# +# Bug #637978: ORing of two index merge that caused a crash +# + +CREATE TABLE t1 ( + f1 int, f2 int, f3 int, f4 int, f5 int, + PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); + +SELECT f5 FROM t1 + WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR + f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); + +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 9c961a45164..7c293648d23 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1195,7 +1195,8 @@ int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, { *is_last_check_pass= TRUE; SEL_TREE** tree= imerge->trees; - for (uint i= 0; i < n_trees; i++, tree++) + SEL_TREE** tree_end= imerge->trees_next; + for ( ; tree < tree_end; tree++) { uint rc; bool is_last= TRUE;