MDEV-6794 XtraDB no longer using UNIQUE as clustered index when PK missing
try the first unique key as a surrogate PK *before* disabling extended keys because of missing PK
This commit is contained in:
parent
79c76400a6
commit
c417da24a3
20
mysql-test/r/ext_key_noPK_6794.result
Normal file
20
mysql-test/r/ext_key_noPK_6794.result
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
create table t1 (c1 int not null, c2 int, unique index(c1), index (c2)) engine=innodb;
|
||||||
|
insert into t1 (c1, c2) select 1, round(rand()*100);
|
||||||
|
insert into t1 (c1, c2) select (select max(c1) from t1) + c1, c1*93563%100 from t1;
|
||||||
|
insert into t1 (c1, c2) select (select max(c1) from t1) + c1, c1*93563%100 from t1;
|
||||||
|
insert into t1 (c1, c2) select (select max(c1) from t1) + c1, c1*93563%100 from t1;
|
||||||
|
select count(*) from t1;
|
||||||
|
count(*)
|
||||||
|
8
|
||||||
|
explain select * from t1 where c2 = 1 order by c1;
|
||||||
|
id 1
|
||||||
|
select_type SIMPLE
|
||||||
|
table t1
|
||||||
|
type ref
|
||||||
|
possible_keys c2
|
||||||
|
key c2
|
||||||
|
key_len 5
|
||||||
|
ref const
|
||||||
|
rows 1
|
||||||
|
Extra Using where; Using index
|
||||||
|
drop table t1;
|
15
mysql-test/t/ext_key_noPK_6794.test
Normal file
15
mysql-test/t/ext_key_noPK_6794.test
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#
|
||||||
|
# MDEV-6794 XtraDB no longer using UNIQUE as clustered index when PK missing
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
create table t1 (c1 int not null, c2 int, unique index(c1), index (c2)) engine=innodb;
|
||||||
|
insert into t1 (c1, c2) select 1, round(rand()*100);
|
||||||
|
insert into t1 (c1, c2) select (select max(c1) from t1) + c1, c1*93563%100 from t1;
|
||||||
|
insert into t1 (c1, c2) select (select max(c1) from t1) + c1, c1*93563%100 from t1;
|
||||||
|
insert into t1 (c1, c2) select (select max(c1) from t1) + c1, c1*93563%100 from t1;
|
||||||
|
select count(*) from t1;
|
||||||
|
--query_vertical explain select * from t1 where c2 = 1 order by c1
|
||||||
|
drop table t1;
|
||||||
|
|
72
sql/table.cc
72
sql/table.cc
@ -1666,10 +1666,44 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
|||||||
if (key_parts)
|
if (key_parts)
|
||||||
{
|
{
|
||||||
uint add_first_key_parts= 0;
|
uint add_first_key_parts= 0;
|
||||||
uint primary_key=(uint) (find_type(primary_key_name, &share->keynames,
|
|
||||||
FIND_TYPE_NO_PREFIX) - 1);
|
|
||||||
longlong ha_option= handler_file->ha_table_flags();
|
longlong ha_option= handler_file->ha_table_flags();
|
||||||
keyinfo= share->key_info;
|
keyinfo= share->key_info;
|
||||||
|
uint primary_key= my_strcasecmp(system_charset_info, share->keynames.type_names[0],
|
||||||
|
primary_key_name) ? MAX_KEY : 0;
|
||||||
|
|
||||||
|
if (primary_key >= MAX_KEY && keyinfo->flags & HA_NOSAME)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If the UNIQUE key doesn't have NULL columns and is not a part key
|
||||||
|
declare this as a primary key.
|
||||||
|
*/
|
||||||
|
primary_key= 0;
|
||||||
|
key_part= keyinfo->key_part;
|
||||||
|
for (i=0 ; i < keyinfo->user_defined_key_parts ;i++)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(key_part[i].fieldnr > 0);
|
||||||
|
// Table field corresponding to the i'th key part.
|
||||||
|
Field *table_field= share->field[key_part[i].fieldnr - 1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
If the key column is of NOT NULL BLOB type, then it
|
||||||
|
will definitly have key prefix. And if key part prefix size
|
||||||
|
is equal to the BLOB column max size, then we can promote
|
||||||
|
it to primary key.
|
||||||
|
*/
|
||||||
|
if (!table_field->real_maybe_null() &&
|
||||||
|
table_field->type() == MYSQL_TYPE_BLOB &&
|
||||||
|
table_field->field_length == key_part[i].length)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (table_field->real_maybe_null() ||
|
||||||
|
table_field->key_length() != key_part[i].length)
|
||||||
|
{
|
||||||
|
primary_key= MAX_KEY; // Can't be used
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (share->use_ext_keys)
|
if (share->use_ext_keys)
|
||||||
{
|
{
|
||||||
@ -1764,40 +1798,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
|||||||
if (share->key_info[key].flags & HA_FULLTEXT)
|
if (share->key_info[key].flags & HA_FULLTEXT)
|
||||||
share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
|
share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
|
||||||
|
|
||||||
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
If the UNIQUE key doesn't have NULL columns and is not a part key
|
|
||||||
declare this as a primary key.
|
|
||||||
*/
|
|
||||||
primary_key=key;
|
|
||||||
key_part= keyinfo->key_part;
|
|
||||||
for (i=0 ; i < keyinfo->user_defined_key_parts ;i++)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(key_part[i].fieldnr > 0);
|
|
||||||
// Table field corresponding to the i'th key part.
|
|
||||||
Field *table_field= share->field[key_part[i].fieldnr - 1];
|
|
||||||
|
|
||||||
/*
|
|
||||||
If the key column is of NOT NULL BLOB type, then it
|
|
||||||
will definitly have key prefix. And if key part prefix size
|
|
||||||
is equal to the BLOB column max size, then we can promote
|
|
||||||
it to primary key.
|
|
||||||
*/
|
|
||||||
if (!table_field->real_maybe_null() &&
|
|
||||||
table_field->type() == MYSQL_TYPE_BLOB &&
|
|
||||||
table_field->field_length == key_part[i].length)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (table_field->real_maybe_null() ||
|
|
||||||
table_field->key_length() != key_part[i].length)
|
|
||||||
{
|
|
||||||
primary_key= MAX_KEY; // Can't be used
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key_part= keyinfo->key_part;
|
key_part= keyinfo->key_part;
|
||||||
uint key_parts= share->use_ext_keys ? keyinfo->ext_key_parts :
|
uint key_parts= share->use_ext_keys ? keyinfo->ext_key_parts :
|
||||||
keyinfo->user_defined_key_parts;
|
keyinfo->user_defined_key_parts;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user