diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index fa1f62b076308..6943a295acb46 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -3736,6 +3736,27 @@ DROP TABLE t1; # # End of 10.5 tests # +# +# MDEV-37913: disable_index_merge_plans causes SELECT data loss when more than 100 ORs +# +CREATE TABLE t1 ( +id int primary key, +key1 int, +index(key1) +); +INSERT INTO t1 VALUES +(1, 1), +(2, 1), +(3, 2); +$query; +id key1 +1 1 +2 1 +3 2 +drop table t1; +# +# End of 10.11 tests +# set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test index 2da200f4730d7..a77cef34e4c19 100644 --- a/mysql-test/main/range.test +++ b/mysql-test/main/range.test @@ -2533,6 +2533,32 @@ DROP TABLE t1; --echo # End of 10.5 tests --echo # +--echo # +--echo # MDEV-37913: disable_index_merge_plans causes SELECT data loss when more than 100 ORs +--echo # +CREATE TABLE t1 ( + id int primary key, + key1 int, + index(key1) +); + +INSERT INTO t1 VALUES +(1, 1), +(2, 1), +(3, 2); + +let $query=` + select concat('select * from t1 where (key1 = 2 AND id = 3) ', + REPEAT(' OR (key1 = 1)', 100)) +`; + +evalp $query; + +drop table t1; + +--echo # +--echo # End of 10.11 tests +--echo # set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index a49ad31ecdf8f..7a5a1405c7375 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -3725,6 +3725,27 @@ DROP TABLE t1; # # End of 10.5 tests # +# +# MDEV-37913: disable_index_merge_plans causes SELECT data loss when more than 100 ORs +# +CREATE TABLE t1 ( +id int primary key, +key1 int, +index(key1) +); +INSERT INTO t1 VALUES +(1, 1), +(2, 1), +(3, 2); +$query; +id key1 +1 1 +2 1 +3 2 +drop table t1; +# +# End of 10.11 tests +# set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index c6c4a5d7b4f5a..75abbe3bae2f8 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -9974,8 +9974,6 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) { bool must_be_ored= sel_trees_must_be_ored(param, tree1, tree2, ored_keys); no_imerge_from_ranges= must_be_ored; - if (param->disable_index_merge_plans) - no_imerge_from_ranges= true; if (no_imerge_from_ranges && no_merges1 && no_merges2) { @@ -10025,6 +10023,13 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) DBUG_RETURN(result); } + /* + Ok, the result now has the ranges that one gets for (RT1 OR RT2). + If construction of SEL_IMERGE is disabled, stop right here. + */ + if (param->disable_index_merge_plans) + DBUG_RETURN(result); + SEL_IMERGE *imerge_from_ranges; if (!(imerge_from_ranges= new SEL_IMERGE())) result= NULL;