mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
MDEV-24763 ALTER TABLE fails to rename a column in SYS_FIELDS
innobase_rename_column_try(): When renaming SYS_FIELDS records for secondary indexes, try to use both formats of SYS_FIELDS.POS as keys, in case the PRIMARY KEY includes a column prefix. Without this fix, an ALTER TABLE that renames a column followed by a server restart (or LRU eviction of the table definition from dict_sys) would make the table inaccessible.
This commit is contained in:
parent
028ba10d0b
commit
6f3f191cfa
3 changed files with 65 additions and 0 deletions
|
@ -70,3 +70,19 @@ ERROR HY000: Tablespace has been discarded for table `t`
|
|||
ALTER TABLE t FORCE;
|
||||
ERROR HY000: Tablespace has been discarded for table `t`
|
||||
DROP TABLE t;
|
||||
#
|
||||
# MDEV-24763 ALTER TABLE fails to rename a column in SYS_FIELDS
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b TEXT, c INT, PRIMARY KEY(b(9)), INDEX(c,a))
|
||||
ENGINE=InnoDB;
|
||||
ALTER TABLE t1 CHANGE COLUMN a u INT;
|
||||
SELECT sf.* FROM information_schema.innodb_sys_fields sf
|
||||
INNER JOIN information_schema.innodb_sys_indexes si ON sf.index_id=si.index_id
|
||||
INNER JOIN information_schema.innodb_sys_tables st ON si.table_id=st.table_id
|
||||
WHERE st.name='test/t1' ORDER BY pos;
|
||||
INDEX_ID NAME POS
|
||||
ID b 0
|
||||
ID c 0
|
||||
ID u 1
|
||||
DROP TABLE t1;
|
||||
# End of 10.2 tests
|
||||
|
|
|
@ -79,3 +79,18 @@ ALTER TABLE t ENGINE INNODB;
|
|||
--error ER_TABLESPACE_DISCARDED
|
||||
ALTER TABLE t FORCE;
|
||||
DROP TABLE t;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-24763 ALTER TABLE fails to rename a column in SYS_FIELDS
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT, b TEXT, c INT, PRIMARY KEY(b(9)), INDEX(c,a))
|
||||
ENGINE=InnoDB;
|
||||
ALTER TABLE t1 CHANGE COLUMN a u INT;
|
||||
--replace_column 1 ID
|
||||
SELECT sf.* FROM information_schema.innodb_sys_fields sf
|
||||
INNER JOIN information_schema.innodb_sys_indexes si ON sf.index_id=si.index_id
|
||||
INNER JOIN information_schema.innodb_sys_tables st ON si.table_id=st.table_id
|
||||
WHERE st.name='test/t1' ORDER BY pos;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # End of 10.2 tests
|
||||
|
|
|
@ -6734,6 +6734,7 @@ innobase_rename_column_try(
|
|||
{
|
||||
pars_info_t* info;
|
||||
dberr_t error;
|
||||
bool clust_has_prefixes = false;
|
||||
|
||||
DBUG_ENTER("innobase_rename_column_try");
|
||||
|
||||
|
@ -6822,6 +6823,39 @@ err_exit:
|
|||
if (error != DB_SUCCESS) {
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
if (!has_prefixes || !clust_has_prefixes
|
||||
|| field->prefix_len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* For secondary indexes, the
|
||||
has_prefixes check can be 'polluted'
|
||||
by PRIMARY KEY column prefix. Try also
|
||||
the simpler encoding of SYS_FIELDS.POS. */
|
||||
info = pars_info_create();
|
||||
|
||||
pars_info_add_ull_literal(info, "indexid", index->id);
|
||||
pars_info_add_int4_literal(info, "nth", i);
|
||||
pars_info_add_str_literal(info, "new", to);
|
||||
|
||||
error = que_eval_sql(
|
||||
info,
|
||||
"PROCEDURE RENAME_SYS_FIELDS_PROC () IS\n"
|
||||
"BEGIN\n"
|
||||
"UPDATE SYS_FIELDS SET COL_NAME=:new\n"
|
||||
"WHERE INDEX_ID=:indexid\n"
|
||||
"AND POS=:nth;\n"
|
||||
"END;\n",
|
||||
FALSE, trx);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
goto err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == dict_table_get_first_index(user_table)) {
|
||||
clust_has_prefixes = has_prefixes;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue