diff --git a/mysql-test/main/alter_table_failed_rename_index.result b/mysql-test/main/alter_table_failed_rename_index.result new file mode 100644 index 0000000000000..d315b6a5d5c09 --- /dev/null +++ b/mysql-test/main/alter_table_failed_rename_index.result @@ -0,0 +1,20 @@ +# +# Scenario A: WITH a prior failed ALTER ... RENAME INDEX +# +CREATE TABLE t1 (f1 INT, f2 INT, KEY(f1), KEY(f2)) ENGINE=InnoDB; +CREATE TABLE t2 (pk INT PRIMARY KEY, a INT, b INT, KEY ind1(a), +FOREIGN KEY fk1 (b) REFERENCES t1 (f1)) ENGINE=InnoDB; +ALTER TABLE t2 RENAME INDEX fk1 TO fk, ALGORITHM=INSTANT, ORDER BY a; +ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY +ALTER TABLE t2 ADD FOREIGN KEY ind1 (b) REFERENCES t1 (f2); +ERROR 42000: Duplicate key name 'ind1' +DROP TABLE t2, t1; +# +# Scenario B: WITHOUT a prior failed ALTER ... RENAME INDEX (baseline) +# +CREATE TABLE t1 (f1 INT, f2 INT, KEY(f1), KEY(f2)) ENGINE=InnoDB; +CREATE TABLE t2 (pk INT PRIMARY KEY, a INT, b INT, KEY ind1(a), +FOREIGN KEY fk1 (b) REFERENCES t1 (f1)) ENGINE=InnoDB; +ALTER TABLE t2 ADD FOREIGN KEY ind1 (b) REFERENCES t1 (f2); +ERROR 42000: Duplicate key name 'ind1' +DROP TABLE t2, t1; diff --git a/mysql-test/main/alter_table_failed_rename_index.test b/mysql-test/main/alter_table_failed_rename_index.test new file mode 100644 index 0000000000000..11d543e2b791f --- /dev/null +++ b/mysql-test/main/alter_table_failed_rename_index.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc + +# MDEV-35732: Failed ALTER TABLE causes inconsistency, changes behavior of the next statement + +--echo # +--echo # Scenario A: WITH a prior failed ALTER ... RENAME INDEX +--echo # +CREATE TABLE t1 (f1 INT, f2 INT, KEY(f1), KEY(f2)) ENGINE=InnoDB; +CREATE TABLE t2 (pk INT PRIMARY KEY, a INT, b INT, KEY ind1(a), + FOREIGN KEY fk1 (b) REFERENCES t1 (f1)) ENGINE=InnoDB; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t2 RENAME INDEX fk1 TO fk, ALGORITHM=INSTANT, ORDER BY a; + +--error ER_DUP_KEYNAME +ALTER TABLE t2 ADD FOREIGN KEY ind1 (b) REFERENCES t1 (f2); + +DROP TABLE t2, t1; + +--echo # +--echo # Scenario B: WITHOUT a prior failed ALTER ... RENAME INDEX (baseline) +--echo # +CREATE TABLE t1 (f1 INT, f2 INT, KEY(f1), KEY(f2)) ENGINE=InnoDB; +CREATE TABLE t2 (pk INT PRIMARY KEY, a INT, b INT, KEY ind1(a), + FOREIGN KEY fk1 (b) REFERENCES t1 (f1)) ENGINE=InnoDB; + +--error ER_DUP_KEYNAME +ALTER TABLE t2 ADD FOREIGN KEY ind1 (b) REFERENCES t1 (f2); + +DROP TABLE t2, t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5ae123c528bab..19d5c5ed6bd5c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8941,6 +8941,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, bool long_hash_key= false; if (key_info->flags & HA_INVISIBLE_KEY) continue; + bool generated_key= key_info->flags & HA_GENERATED_KEY; const char *key_name= key_info->name.str; const bool primary_key= table->s->primary_key == i; const bool explicit_pk= primary_key && @@ -9029,7 +9030,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, dropped by mysql_prepare_create_table() and this will confuse code in fill_alter_inplace_info(). */ - key_info->flags&= ~HA_GENERATED_KEY; + generated_key= false; break; } } @@ -9229,7 +9230,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, tmp_name.length= strlen(key_name); /* We dont need LONG_UNIQUE_HASH_FIELD flag because it will be autogenerated */ key= new (thd->mem_root) Key(key_type, &tmp_name, &key_create_info, - key_info->flags & HA_GENERATED_KEY, + generated_key, &key_parts, key_info->option_list, DDL_options()); key->without_overlaps= key_info->without_overlaps; key->period= table->s->period.name;