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:
Sergei Golubchik 2014-11-18 22:26:14 +01:00
parent 79c76400a6
commit c417da24a3
3 changed files with 71 additions and 36 deletions

View 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;

View 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;

View File

@ -1666,10 +1666,44 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (key_parts)
{
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();
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)
{
@ -1764,40 +1798,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (share->key_info[key].flags & HA_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;
uint key_parts= share->use_ext_keys ? keyinfo->ext_key_parts :
keyinfo->user_defined_key_parts;