diff --git a/mysql-test/r/innodb_ext_key.result b/mysql-test/r/innodb_ext_key.result index c7a5b1a80ca..880d7a8bceb 100644 --- a/mysql-test/r/innodb_ext_key.result +++ b/mysql-test/r/innodb_ext_key.result @@ -790,3 +790,19 @@ EXPLAIN } drop table t1; SET optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +# +# MDEV-11172: EXPLAIN shows non-sensical value for key_len with type=index +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +CREATE TABLE t2 ( +pk VARCHAR(50), +a VARCHAR(20), +KEY k1(a), +PRIMARY KEY(pk) +)ENGINE=INNODB; +INSERT INTO t2 SELECT a,a FROM t1; +EXPLAIN SELECT pk FROM t2 FORCE INDEX(k1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL k1 23 NULL 10 Using index +DROP TABLE t1,t2; diff --git a/mysql-test/t/innodb_ext_key.test b/mysql-test/t/innodb_ext_key.test index f5edd736490..de9ca10ff1b 100644 --- a/mysql-test/t/innodb_ext_key.test +++ b/mysql-test/t/innodb_ext_key.test @@ -606,3 +606,22 @@ explain format= json select * from t1 force index(k1) where f2 <= 5 and pk2 <=5 and pk1 = 'abc' and f1 <= '3'; drop table t1; SET optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; + +--echo # +--echo # MDEV-11172: EXPLAIN shows non-sensical value for key_len with type=index +--echo # + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +CREATE TABLE t2 ( + pk VARCHAR(50), + a VARCHAR(20), + KEY k1(a), + PRIMARY KEY(pk) +)ENGINE=INNODB; + +INSERT INTO t2 SELECT a,a FROM t1; +EXPLAIN SELECT pk FROM t2 FORCE INDEX(k1); + +DROP TABLE t1,t2; diff --git a/sql/structs.h b/sql/structs.h index 67fb0d5dd66..27b9725815b 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -90,7 +90,7 @@ class engine_option_value; struct ha_index_option_struct; typedef struct st_key { - uint key_length; /* Tot length of key */ + uint key_length; /* total length of user defined key parts */ ulong flags; /* dupp key and pack flags */ uint user_defined_key_parts; /* How many key_parts */ uint usable_key_parts; /* Should normally be = user_defined_key_parts */ diff --git a/sql/table.cc b/sql/table.cc index e4492f21a30..1004f583448 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2273,6 +2273,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, key_part->null_bit= field->null_bit; key_part->store_length+=HA_KEY_NULL_LENGTH; keyinfo->flags|=HA_NULL_PART_KEY; + + /* + This branch is executed only for user defined key parts of the + secondary indexes. + */ + DBUG_ASSERT(i < keyinfo->user_defined_key_parts); keyinfo->key_length+= HA_KEY_NULL_LENGTH; } if (field->type() == MYSQL_TYPE_BLOB || @@ -2285,7 +2291,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, else key_part->key_part_flag|= HA_VAR_LENGTH_PART; key_part->store_length+=HA_KEY_BLOB_LENGTH; - keyinfo->key_length+= HA_KEY_BLOB_LENGTH; + if (i < keyinfo->user_defined_key_parts) + keyinfo->key_length+= HA_KEY_BLOB_LENGTH; } if (field->type() == MYSQL_TYPE_BIT) key_part->key_part_flag|= HA_BIT_PART; @@ -2378,7 +2385,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, set_if_bigger(share->max_key_length,keyinfo->key_length+ keyinfo->user_defined_key_parts); - share->total_key_length+= keyinfo->key_length; /* MERGE tables do not have unique indexes. But every key could be an unique index on the underlying MyISAM table. (Bug #10400) diff --git a/sql/table.h b/sql/table.h index a5d412c2c08..83c72f76831 100644 --- a/sql/table.h +++ b/sql/table.h @@ -773,7 +773,7 @@ struct TABLE_SHARE uint rec_buff_length; /* Size of table->record[] buffer */ uint keys, key_parts; uint ext_key_parts; /* Total number of key parts in extended keys */ - uint max_key_length, max_unique_length, total_key_length; + uint max_key_length, max_unique_length; uint uniques; /* Number of UNIQUE index */ uint db_create_options; /* Create options from database */ uint db_options_in_use; /* Options in use */