1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-35026: ALTER TABLE loses USING HASH on unique keys

mysql_prepare_alter_table() reset LONG_HASH keys to HA_KEY_ALG_UNDEF
even when no column changed, so a short key lost its hash column.
Keep HA_KEY_ALG_LONG_HASH unless ALTER_CHANGE_COLUMN is set.
This commit is contained in:
PranavKTiwari
2026-07-13 13:51:37 +05:30
committed by mariadb-PranavTiwari
parent 120162359b
commit d2dc0e6003
3 changed files with 127 additions and 7 deletions

View File

@@ -181,3 +181,78 @@ pk b
1 foo
drop table t1;
# End of 10.6 tests
#
# MDEV-35026 ALTER TABLE loses USING HASH on a unique key
#
create table t (
id int(10) unsigned not null auto_increment,
x int(10) unsigned default null,
y int(10) unsigned default null,
primary key (id),
unique key y (y) using hash,
key fk_1 (x),
constraint fk_1 foreign key (x) references t (id)
) engine=innodb;
insert t select seq, seq, seq from seq_1_to_1001;
show create table t;
Table Create Table
t CREATE TABLE `t` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`x` int(10) unsigned DEFAULT NULL,
`y` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `y` (`y`) USING HASH,
KEY `fk_1` (`x`),
CONSTRAINT `fk_1` FOREIGN KEY (`x`) REFERENCES `t` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
alter table t drop foreign key fk_1;
show create table t;
Table Create Table
t CREATE TABLE `t` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`x` int(10) unsigned DEFAULT NULL,
`y` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `y` (`y`) USING HASH,
KEY `fk_1` (`x`)
) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
alter table t drop column x;
show create table t;
Table Create Table
t CREATE TABLE `t` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`y` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `y` (`y`) USING HASH
) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t;
# Engine change must not keep the hidden hash column
create table t (a int, unique (a) using hash) engine=innodb;
show create table t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) DEFAULT NULL,
UNIQUE KEY `a` (`a`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
alter table t engine=memory;
select engine from information_schema.tables where table_schema=database() and table_name='t';
engine
MEMORY
show create table t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) DEFAULT NULL,
UNIQUE KEY `a` (`a`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
alter table t engine=myisam;
select engine from information_schema.tables where table_schema=database() and table_name='t';
engine
MyISAM
show create table t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) DEFAULT NULL,
UNIQUE KEY `a` (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t;
# End of 10.11 tests

View File

@@ -1,5 +1,6 @@
--source include/have_innodb.inc
--source include/have_partition.inc
--source include/have_sequence.inc
#
# MDEV-371 Unique indexes for blobs
@@ -187,3 +188,38 @@ select * from t1;
drop table t1;
--echo # End of 10.6 tests
--echo #
--echo # MDEV-35026 ALTER TABLE loses USING HASH on a unique key
--echo #
create table t (
id int(10) unsigned not null auto_increment,
x int(10) unsigned default null,
y int(10) unsigned default null,
primary key (id),
unique key y (y) using hash,
key fk_1 (x),
constraint fk_1 foreign key (x) references t (id)
) engine=innodb;
insert t select seq, seq, seq from seq_1_to_1001;
show create table t;
alter table t drop foreign key fk_1;
show create table t;
alter table t drop column x;
show create table t;
drop table t;
--echo # Engine change must not keep the hidden hash column
create table t (a int, unique (a) using hash) engine=innodb;
show create table t;
alter table t engine=memory;
select engine from information_schema.tables where table_schema=database() and table_name='t';
show create table t;
alter table t engine=myisam;
select engine from information_schema.tables where table_schema=database() and table_name='t';
show create table t;
drop table t;
--echo # End of 10.11 tests

View File

@@ -9265,15 +9265,24 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
enum Key::Keytype key_type;
LEX_CSTRING tmp_name;
bzero((char*) &key_create_info, sizeof(key_create_info));
if (key_info->algorithm == HA_KEY_ALG_LONG_HASH)
key_info->algorithm= alter_ctx->fast_alter_partition ?
HA_KEY_ALG_HASH : HA_KEY_ALG_UNDEF;
/*
For fast alter partition we set HA_KEY_ALG_HASH above to make sure it
doesn't lose the hash property.
Otherwise we let mysql_prepare_create_table() decide if the hash field
is needed depending on the (possibly changed) data types.
All columns of a long hash key survive here, so the key keeps
HA_KEY_ALG_LONG_HASH unless a column was changed or the storage engine
is changed.
For fast alter partition we set HA_KEY_ALG_HASH
to make sure it doesn't lose the hash property.
Otherwise we let mysql_prepare_create_table() decide
if the hash field is needed depending on the (possibly changed)
data types or engine.
*/
if (key_info->algorithm == HA_KEY_ALG_LONG_HASH)
{
if (alter_ctx->fast_alter_partition)
key_info->algorithm= HA_KEY_ALG_HASH;
else if ((alter_info->flags & ALTER_CHANGE_COLUMN) ||
create_info->db_type != table->s->db_type())
key_info->algorithm= HA_KEY_ALG_UNDEF;
}
key_create_info.algorithm= key_info->algorithm;
/*
We copy block size directly as some engines, like Area, sets this