mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03: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:
@@ -70,3 +70,19 @@ ERROR HY000: Tablespace has been discarded for table `t`
|
|||||||
ALTER TABLE t FORCE;
|
ALTER TABLE t FORCE;
|
||||||
ERROR HY000: Tablespace has been discarded for table `t`
|
ERROR HY000: Tablespace has been discarded for table `t`
|
||||||
DROP 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
|
--error ER_TABLESPACE_DISCARDED
|
||||||
ALTER TABLE t FORCE;
|
ALTER TABLE t FORCE;
|
||||||
DROP TABLE t;
|
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;
|
pars_info_t* info;
|
||||||
dberr_t error;
|
dberr_t error;
|
||||||
|
bool clust_has_prefixes = false;
|
||||||
|
|
||||||
DBUG_ENTER("innobase_rename_column_try");
|
DBUG_ENTER("innobase_rename_column_try");
|
||||||
|
|
||||||
@@ -6822,6 +6823,39 @@ err_exit:
|
|||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
goto err_exit;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user