diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 32a3e6b3ebd..5e6a535fce5 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -939,6 +939,36 @@ alter table t1 add index(a(1024)); show create table t1; drop table t1; +# +# Bug #28570: handler::index_read() is called with different find_flag when +# ORDER BY is used +# + +CREATE TABLE t1 ( + a INT, + b INT, + KEY (b) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1,10), (2,10), (2,20), (3,30); + +START TRANSACTION; +SELECT * FROM t1 WHERE b=20 FOR UPDATE; + +--connect (conn2, localhost, root,,test) + +# This statement gives a "failed: 1205: Lock wait timeout exceeded; try +# restarting transaction" message when the bug is present. +START TRANSACTION; +SELECT * FROM t1 WHERE b=10 ORDER BY A FOR UPDATE; +ROLLBACK; + +--disconnect conn2 +--connection default + +ROLLBACK; +DROP TABLE t1; + --echo End of 5.0 tests # Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index ae442acd1b9..32c692501ad 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1123,6 +1123,24 @@ t1 CREATE TABLE `t1` ( KEY `a` (`a`(255)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 drop table t1; +CREATE TABLE t1 ( +a INT, +b INT, +KEY (b) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,10), (2,10), (2,20), (3,30); +START TRANSACTION; +SELECT * FROM t1 WHERE b=20 FOR UPDATE; +a b +2 20 +START TRANSACTION; +SELECT * FROM t1 WHERE b=10 ORDER BY A FOR UPDATE; +a b +1 10 +2 10 +ROLLBACK; +ROLLBACK; +DROP TABLE t1; End of 5.0 tests CREATE TABLE `t2` ( `k` int(11) NOT NULL auto_increment, diff --git a/sql/handler.cc b/sql/handler.cc index 3e9524e9821..1faaccf1257 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3186,7 +3186,8 @@ int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p) read_range_first() start_key Start key. Is 0 if no min range end_key End key. Is 0 if no max range - eq_range_arg Set to 1 if start_key == end_key + eq_range_arg Set to 1 if start_key == end_key and the range endpoints + will not change during query execution. sorted Set to 1 if result should be sorted per key NOTES diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 948b268d9a3..3dab3627a9d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7815,8 +7815,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, range->min_keypart_map= range->max_keypart_map= make_prev_keypart_map(ref->key_parts); range->flag= ((ref->key_length == key_info->key_length && - (key_info->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == - HA_NOSAME) ? EQ_RANGE : 0); + (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0); if (!(quick->key_parts=key_part=(KEY_PART *) alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))