diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index f9bf08a0675..12797d83acf 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -4855,7 +4855,8 @@ void dict_table_replace_index_in_foreign_list( /*=====================================*/ dict_table_t* table, /*!< in/out: table */ - dict_index_t* index) /*!< in: index to be replaced */ + dict_index_t* index, /*!< in: index to be replaced */ + const trx_t* trx) /*!< in: transaction handle */ { dict_foreign_t* foreign; @@ -4866,7 +4867,13 @@ dict_table_replace_index_in_foreign_list( if (foreign->foreign_index == index) { dict_index_t* new_index = dict_foreign_find_equiv_index(foreign); - ut_a(new_index); + + /* There must exist an alternative index if + check_foreigns (FOREIGN_KEY_CHECKS) is on, + since ha_innobase::prepare_drop_index had done + the check before we reach here. */ + + ut_a(new_index || !trx->check_foreigns); foreign->foreign_index = new_index; } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 3744d16570c..c0bd3121c9c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1016,12 +1016,13 @@ ha_innobase::prepare_drop_index( index->to_be_dropped = TRUE; } - /* If FOREIGN_KEY_CHECK = 1 you may not drop an index defined + /* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined for a foreign key constraint because InnoDB requires that both - tables contain indexes for the constraint. Note that CREATE - INDEX id ON table does a CREATE INDEX and DROP INDEX, and we - can ignore here foreign keys because a new index for the - foreign key has already been created. + tables contain indexes for the constraint. Such index can + be dropped only if FOREIGN_KEY_CHECKS is set to 0. + Note that CREATE INDEX id ON table does a CREATE INDEX and + DROP INDEX, and we can ignore here foreign keys because a + new index for the foreign key has already been created. We check for the foreign key constraints after marking the candidate indexes for deletion, because when we check for an diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index f5a3e8dafc0..1c9e351b30b 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -345,7 +345,8 @@ void dict_table_replace_index_in_foreign_list( /*=====================================*/ dict_table_t* table, /*!< in/out: table */ - dict_index_t* index); /*!< in: index to be replaced */ + dict_index_t* index, /*!< in: index to be replaced */ + const trx_t* trx); /*!< in: transaction handle */ /*********************************************************************//** Checks if a index is defined for a foreign key constraint. Index is a part of a foreign key constraint if the index is referenced by foreign key diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c index 1b96ff50e66..0c68d6477a4 100644 --- a/storage/innobase/row/row0merge.c +++ b/storage/innobase/row/row0merge.c @@ -2042,7 +2042,7 @@ row_merge_drop_index( /* Replace this index with another equivalent index for all foreign key constraints on this table where this index is used */ - dict_table_replace_index_in_foreign_list(table, index); + dict_table_replace_index_in_foreign_list(table, index, trx); dict_index_remove_from_cache(table, index); trx->op_info = "";