From: Date: September 29 2005 5:58am Subject: bk commit into 5.0 tree (sergefp:1.2002) BUG#13455 List-Archive: http://lists.mysql.com/internals/30482 X-Bug: 13455 Message-Id: <20050929035841.6CDC537AFC@newbox.mylan> Below is the list of changes that have just been committed into a local 5.0 repository of psergey. When psergey does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2002 05/09/29 07:58:35 sergefp@stripped +6 -0 Fix for BUG#13455: Make "ref" optimizer able to make this inference: "t.key BETWEEN c1 AND c2" and c1 = c2 -> can access table t using "t.key = c1". sql/sql_select.cc 1.376 05/09/29 07:58:30 sergefp@stripped +14 -2 Fix for BUG#13455: Make "ref" optimizer able to make this inference: "t.key BETWEEN c1 AND c2" and c1 = c2 -> can access table t using "t.key = c1". mysql-test/t/range.test 1.35 05/09/29 07:58:30 sergefp@stripped +27 -1 Testcase for BUG#13455 mysql-test/r/range.result 1.42 05/09/29 07:58:30 sergefp@stripped +24 -1 Testcase for BUG#13455 mysql-test/r/myisam.result 1.68 05/09/29 07:58:30 sergefp@stripped +6 -6 BUG#13455: updated test results mysql-test/r/innodb.result 1.138 05/09/29 07:58:30 sergefp@stripped +6 -6 BUG#13455: updated test results mysql-test/r/heap.result 1.42 05/09/29 07:58:30 sergefp@stripped +4 -4 BUG#13455: updated test results # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: sergefp # Host: newbox.mylan # Root: /home/psergey/mysql-5.0-bug13455 --- 1.375/sql/sql_select.cc 2005-09-24 02:39:47 +04:00 +++ 1.376/sql/sql_select.cc 2005-09-29 07:58:30 +04:00 @@ -2409,6 +2409,7 @@ !field->table->maybe_null || field->null_ptr) return; // Not a key. Skip it exists_optimize= KEY_OPTIMIZE_EXISTS; + DBUG_ASSERT(num_values == 1); } else { @@ -2460,7 +2461,19 @@ eq_func is NEVER true when num_values > 1 */ if (!eq_func) - return; + { + /* + Additional optimization: if we're processing + "t.key BETWEEN c1 AND c2" and c1==c2 then proceed as if we were + processing "t.key = c1" + */ + if ((cond->functype() == Item_func::BETWEEN) && + value[0]->eq(value[1], field->binary())) + eq_func= TRUE; + else + return; + } + if (field->result_type() == STRING_RESULT) { if ((*value)->result_type() != STRING_RESULT) @@ -2487,7 +2500,6 @@ } } } - DBUG_ASSERT(num_values == 1); /* For the moment eq_func is always true. This slot is reserved for future extensions where we want to remembers other things than just eq comparisons --- 1.41/mysql-test/r/heap.result 2005-08-09 12:21:41 +04:00 +++ 1.42/mysql-test/r/heap.result 2005-09-29 07:58:30 +04:00 @@ -379,10 +379,10 @@ 1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where +1 SIMPLE t1 ref v v 13 const 10 Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where +1 SIMPLE t1 ref v v 13 const 10 Using where alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a' order by length(concat('*',v,'*',c,'*',t,'*')); @@ -602,10 +602,10 @@ 1 SIMPLE t1 range v v 13 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where +1 SIMPLE t1 ref v v 13 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where +1 SIMPLE t1 ref v v 13 const # Using where alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a' order by length(concat('*',v,'*',c,'*',t,'*')); --- 1.137/mysql-test/r/innodb.result 2005-09-23 17:44:23 +04:00 +++ 1.138/mysql-test/r/innodb.result 2005-09-29 07:58:30 +04:00 @@ -1997,10 +1997,10 @@ 1 SIMPLE t1 range v v 13 NULL # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where; Using index +1 SIMPLE t1 ref v v 13 const # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where; Using index +1 SIMPLE t1 ref v v 13 const # Using where; Using index alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 alter table t1 add key(v); @@ -2188,10 +2188,10 @@ 1 SIMPLE t1 range v v 303 NULL # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 303 NULL # Using where; Using index +1 SIMPLE t1 ref v v 303 const # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 303 NULL # Using where; Using index +1 SIMPLE t1 ref v v 303 const # Using where; Using index explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 303 const # Using where @@ -2268,10 +2268,10 @@ 1 SIMPLE t1 range v v 33 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 33 const # Using where --- 1.41/mysql-test/r/range.result 2005-09-21 21:36:11 +04:00 +++ 1.42/mysql-test/r/range.result 2005-09-29 07:58:30 +04:00 @@ -1,4 +1,4 @@ -drop table if exists t1, t2; +drop table if exists t1, t2, t3; CREATE TABLE t1 ( event_date date DEFAULT '0000-00-00' NOT NULL, type int(11) DEFAULT '0' NOT NULL, @@ -787,3 +787,26 @@ 1 PRIMARY t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index drop view v1; drop table t1; +create table t3 (a int); +insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a varchar(10), filler char(200), key(a)) charset=binary; +insert into t1 values ('a',''); +insert into t1 values ('a ',''); +insert into t1 values ('a ', ''); +insert into t1 select concat('a', 1000 + A.a + 10 * (B.a + 10 * C.a)), '' + from t3 A, t3 B, t3 C; +create table t2 (a varchar(10), filler char(200), key(a)); +insert into t2 select * from t1; +explain select * from t1 where a between 'a' and 'a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 13 NULL # Using where +explain select * from t1 where a = 'a' or a='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 13 NULL # Using where +explain select * from t2 where a between 'a' and 'a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref a a 13 const # Using where +explain select * from t2 where a = 'a' or a='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref a a 13 const # Using where +drop table t1,t2,t3; --- 1.34/mysql-test/t/range.test 2005-09-21 21:36:11 +04:00 +++ 1.35/mysql-test/t/range.test 2005-09-29 07:58:30 +04:00 @@ -3,7 +3,7 @@ # --disable_warnings -drop table if exists t1, t2; +drop table if exists t1, t2, t3; --enable_warnings CREATE TABLE t1 ( @@ -600,3 +600,29 @@ drop view v1; drop table t1; + +# BUG#13455: +create table t3 (a int); +insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1 (a varchar(10), filler char(200), key(a)) charset=binary; +insert into t1 values ('a',''); +insert into t1 values ('a ',''); +insert into t1 values ('a ', ''); +insert into t1 select concat('a', 1000 + A.a + 10 * (B.a + 10 * C.a)), '' + from t3 A, t3 B, t3 C; + +create table t2 (a varchar(10), filler char(200), key(a)); +insert into t2 select * from t1; + +--replace_column 9 # +explain select * from t1 where a between 'a' and 'a '; +--replace_column 9 # +explain select * from t1 where a = 'a' or a='a '; + +--replace_column 9 # +explain select * from t2 where a between 'a' and 'a '; +--replace_column 9 # +explain select * from t2 where a = 'a' or a='a '; + +drop table t1,t2,t3; --- 1.67/mysql-test/r/myisam.result 2005-09-24 02:35:27 +04:00 +++ 1.68/mysql-test/r/myisam.result 2005-09-29 07:58:30 +04:00 @@ -802,10 +802,10 @@ 1 SIMPLE t1 range v v 13 NULL # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where; Using index +1 SIMPLE t1 ref v v 13 const # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where; Using index +1 SIMPLE t1 ref v v 13 const # Using where; Using index alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 alter table t1 add key(v); @@ -993,10 +993,10 @@ 1 SIMPLE t1 range v v 303 NULL # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 303 NULL # Using where; Using index +1 SIMPLE t1 ref v v 303 const # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 303 NULL # Using where; Using index +1 SIMPLE t1 ref v v 303 const # Using where; Using index explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 303 const # Using where @@ -1073,10 +1073,10 @@ 1 SIMPLE t1 range v v 33 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 33 const # Using where