summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-02-12 09:48:36 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-02-12 09:48:36 +0200
commit6f3f191cfa434f1be71b42747769114ba31ae567 (patch)
tree395f7b381e4177bed41859a76786a9957b383da9 /storage
parent028ba10d0bd0f66b0d3c49167b67ab2e6061eb64 (diff)
downloadmariadb-git-6f3f191cfa434f1be71b42747769114ba31ae567.tar.gz
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.
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/handler/handler0alter.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 4b077c44f17..e03621795ba 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -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;
}
}