mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-18775 Fix ALTER TABLE error handling for DROP INDEX
On an error (such as when an index cannot be dropped due to
FOREIGN KEY constraints), the field dict_index_t::to_be_dropped
was only being cleared in debug builds, even though the field
is available and being used also in non-debug builds.
This was a regression that was introduced by myself originally
in MySQL 5.7.6 and later merged to MariaDB 10.2.2, in
d39898de8e
An error manifested itself in the MariaDB Server 10.4 non-debug build,
involving instant ADD or DROP column. Because an earlier failed
ALTER TABLE operation incorrectly left the dict_index_t::to_be_dropped
flag set, the column pointers of the index fields would fail to be
adjusted for instant ADD or DROP column (MDEV-15562). The instant
ADD COLUMN in MariaDB Server 10.3 is unlikely to be affected by a
similar scenario, because dict_table_t::instant_add_column() in 10.3
is applying the transformations to all indexes, not skipping
to-be-dropped ones.
This commit is contained in:
@@ -38,3 +38,18 @@ Warnings:
|
||||
Warning 1105 ORDER BY ignored as there is a user-defined clustered index in the table 't1'
|
||||
DROP TABLE t1;
|
||||
SET sql_mode=DEFAULT;
|
||||
#
|
||||
# MDEV-18775 Server crashes in dict_table_t::instant_column
|
||||
# upon ADD COLUMN
|
||||
#
|
||||
CREATE TABLE tx (pk INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY (pk), KEY (a), FOREIGN KEY (a) REFERENCES tx (pk)) ENGINE=InnoDB;
|
||||
SET FOREIGN_KEY_CHECKS=OFF;
|
||||
ALTER TABLE t1 DROP a;
|
||||
ERROR HY000: Cannot drop column 'a': needed in a foreign key constraint 'test/t1_ibfk_1'
|
||||
SET FOREIGN_KEY_CHECKS=ON;
|
||||
ALTER TABLE t1 ADD b INT;
|
||||
ALTER TABLE t1 DROP a;
|
||||
ERROR HY000: Cannot drop index 'a': needed in a foreign key constraint
|
||||
ALTER TABLE t1 ADD c INT;
|
||||
DROP TABLE t1, tx;
|
||||
|
@@ -38,3 +38,24 @@ ALTER TABLE t1 ORDER BY a;
|
||||
DROP TABLE t1;
|
||||
|
||||
SET sql_mode=DEFAULT;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-18775 Server crashes in dict_table_t::instant_column
|
||||
--echo # upon ADD COLUMN
|
||||
--echo #
|
||||
|
||||
CREATE TABLE tx (pk INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY (pk), KEY (a), FOREIGN KEY (a) REFERENCES tx (pk)) ENGINE=InnoDB;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=OFF;
|
||||
|
||||
--error ER_FK_COLUMN_CANNOT_DROP
|
||||
ALTER TABLE t1 DROP a;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=ON;
|
||||
|
||||
ALTER TABLE t1 ADD b INT;
|
||||
--error ER_DROP_INDEX_FK
|
||||
ALTER TABLE t1 DROP a;
|
||||
ALTER TABLE t1 ADD c INT;
|
||||
DROP TABLE t1, tx;
|
||||
|
@@ -5142,14 +5142,12 @@ error_handled:
|
||||
ut_ad(!user_table->drop_aborted);
|
||||
|
||||
err_exit:
|
||||
#ifdef UNIV_DEBUG
|
||||
/* Clear the to_be_dropped flag in the data dictionary cache. */
|
||||
for (ulint i = 0; i < ctx->num_to_drop_index; i++) {
|
||||
DBUG_ASSERT(ctx->drop_index[i]->is_committed());
|
||||
DBUG_ASSERT(ctx->drop_index[i]->to_be_dropped);
|
||||
ctx->drop_index[i]->to_be_dropped = 0;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
row_mysql_unlock_data_dictionary(ctx->trx);
|
||||
|
||||
|
Reference in New Issue
Block a user