Commit 6f3f191c authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent 028ba10d
......@@ -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 @@ innobase_rename_column_try(
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;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment