mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-14081 ALTER TABLE CHANGE COLUMN Corrupts Index Leading to Crashes in 10.2
remove remnants of 10.0 bugfix, incorrectly merged into 10.2 Using col_names[i] was obviously, wrong, must've been col_names[ifield->col_no]. incorrect column name resulted in innodb having index unique_id2(id1), while the server thought it's unique_id2(id4). But col_names[ifield->col_no] is wrong too, because `table` has non-renamed columns, so the correct column name is always dict_table_get_col_name(table, ifield->col_no)
This commit is contained in:
@ -11,3 +11,14 @@ t1 CREATE TABLE `t1` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set @@sql_mode=default;
|
set @@sql_mode=default;
|
||||||
|
create table t1 (
|
||||||
|
id1 int(11) not null auto_increment,
|
||||||
|
id2 varchar(30) not null,
|
||||||
|
id3 datetime not null default current_timestamp,
|
||||||
|
primary key (id1),
|
||||||
|
unique key unique_id2 (id2)
|
||||||
|
) engine=innodb;
|
||||||
|
alter table t1 change column id2 id4 varchar(100) not null;
|
||||||
|
select * from t1 where id4 like 'a';
|
||||||
|
id1 id4 id3
|
||||||
|
drop table t1;
|
||||||
|
@ -640,10 +640,8 @@ CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL;
|
|||||||
ALTER TABLE t1o DROP INDEX ct, DROP INDEX FTS_DOC_ID_INDEX,
|
ALTER TABLE t1o DROP INDEX ct, DROP INDEX FTS_DOC_ID_INDEX,
|
||||||
CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
|
CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
|
||||||
ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id);
|
ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id);
|
||||||
call mtr.add_suppression("InnoDB: No matching column for `FTS_DOC_ID` in index `ct` of table `test`\\.`t1o`");
|
|
||||||
ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
|
ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
|
||||||
ADD FULLTEXT INDEX(ct);
|
ADD FULLTEXT INDEX(ct);
|
||||||
ERROR HY000: Index for table 't1o' is corrupt; try to repair it
|
|
||||||
DROP TABLE sys_indexes;
|
DROP TABLE sys_indexes;
|
||||||
CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
|
CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
|
||||||
INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
|
INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID;
|
||||||
|
@ -8,3 +8,17 @@ create index idx1 on t1(a(3073));
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set @@sql_mode=default;
|
set @@sql_mode=default;
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-14081 ALTER TABLE CHANGE COLUMN Corrupts Index Leading to Crashes in 10.2
|
||||||
|
#
|
||||||
|
create table t1 (
|
||||||
|
id1 int(11) not null auto_increment,
|
||||||
|
id2 varchar(30) not null,
|
||||||
|
id3 datetime not null default current_timestamp,
|
||||||
|
primary key (id1),
|
||||||
|
unique key unique_id2 (id2)
|
||||||
|
) engine=innodb;
|
||||||
|
alter table t1 change column id2 id4 varchar(100) not null;
|
||||||
|
select * from t1 where id4 like 'a';
|
||||||
|
drop table t1;
|
||||||
|
@ -370,16 +370,8 @@ CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL;
|
|||||||
|
|
||||||
ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id);
|
ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id);
|
||||||
|
|
||||||
# FIXME: MDEV-9469 'Incorrect key file' on ALTER TABLE
|
|
||||||
call mtr.add_suppression("InnoDB: No matching column for `FTS_DOC_ID` in index `ct` of table `test`\\.`t1o`");
|
|
||||||
--error ER_NOT_KEYFILE
|
|
||||||
ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
|
ALTER TABLE t1o CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL,
|
||||||
ADD FULLTEXT INDEX(ct);
|
ADD FULLTEXT INDEX(ct);
|
||||||
# FIXME: MDEV-9469 (enable this)
|
|
||||||
#--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
|
||||||
#ALTER TABLE t1o CHANGE FTS_DOC_ID foo_id BIGINT UNSIGNED NOT NULL,
|
|
||||||
#ALGORITHM=INPLACE;
|
|
||||||
#end of MDEV-9469 FIXME
|
|
||||||
|
|
||||||
DROP TABLE sys_indexes;
|
DROP TABLE sys_indexes;
|
||||||
CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
|
CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i
|
||||||
|
@ -4850,7 +4850,7 @@ new_clustered_failed:
|
|||||||
|
|
||||||
ctx->add_index[a] = row_merge_create_index(
|
ctx->add_index[a] = row_merge_create_index(
|
||||||
ctx->trx, ctx->new_table,
|
ctx->trx, ctx->new_table,
|
||||||
&index_defs[a], add_v, ctx->col_names);
|
&index_defs[a], add_v);
|
||||||
|
|
||||||
add_key_nums[a] = index_defs[a].key_number;
|
add_key_nums[a] = index_defs[a].key_number;
|
||||||
|
|
||||||
|
@ -265,16 +265,13 @@ row_merge_rename_index_to_drop(
|
|||||||
@param[in] index_def the index definition
|
@param[in] index_def the index definition
|
||||||
@param[in] add_v new virtual columns added along with add
|
@param[in] add_v new virtual columns added along with add
|
||||||
index call
|
index call
|
||||||
@param[in] col_names column names if columns are renamed
|
|
||||||
or NULL
|
|
||||||
@return index, or NULL on error */
|
@return index, or NULL on error */
|
||||||
dict_index_t*
|
dict_index_t*
|
||||||
row_merge_create_index(
|
row_merge_create_index(
|
||||||
trx_t* trx,
|
trx_t* trx,
|
||||||
dict_table_t* table,
|
dict_table_t* table,
|
||||||
const index_def_t* index_def,
|
const index_def_t* index_def,
|
||||||
const dict_add_v_col_t* add_v,
|
const dict_add_v_col_t* add_v)
|
||||||
const char** col_names)
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
@ -4362,16 +4362,13 @@ row_merge_create_index_graph(
|
|||||||
@param[in] index_def the index definition
|
@param[in] index_def the index definition
|
||||||
@param[in] add_v new virtual columns added along with add
|
@param[in] add_v new virtual columns added along with add
|
||||||
index call
|
index call
|
||||||
@param[in] col_names column names if columns are renamed
|
|
||||||
or NULL
|
|
||||||
@return index, or NULL on error */
|
@return index, or NULL on error */
|
||||||
dict_index_t*
|
dict_index_t*
|
||||||
row_merge_create_index(
|
row_merge_create_index(
|
||||||
trx_t* trx,
|
trx_t* trx,
|
||||||
dict_table_t* table,
|
dict_table_t* table,
|
||||||
const index_def_t* index_def,
|
const index_def_t* index_def,
|
||||||
const dict_add_v_col_t* add_v,
|
const dict_add_v_col_t* add_v)
|
||||||
const char** col_names)
|
|
||||||
{
|
{
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
@ -4411,20 +4408,7 @@ row_merge_create_index(
|
|||||||
table, ifield->col_no);
|
table, ifield->col_no);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
name = dict_table_get_col_name(table, ifield->col_no);
|
||||||
Alter table renaming a column and then adding a index
|
|
||||||
to this new name e.g ALTER TABLE t
|
|
||||||
CHANGE COLUMN b c INT NOT NULL, ADD UNIQUE INDEX (c);
|
|
||||||
requires additional check as column names are not yet
|
|
||||||
changed when new index definitions are created. Table's
|
|
||||||
new column names are on a array of column name pointers
|
|
||||||
if any of the column names are changed. */
|
|
||||||
|
|
||||||
if (col_names && col_names[i]) {
|
|
||||||
name = col_names[i];
|
|
||||||
} else {
|
|
||||||
name = dict_table_get_col_name(table, ifield->col_no);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dict_mem_index_add_field(index, name, ifield->prefix_len);
|
dict_mem_index_add_field(index, name, ifield->prefix_len);
|
||||||
|
Reference in New Issue
Block a user