diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 0404ab81c61..6c17504b5e0 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -164,9 +164,6 @@ DELETE FROM parent; ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) ALTER TABLE child ADD INDEX(a); DELETE FROM parent; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) -ALTER TABLE child FORCE; -DELETE FROM parent; DROP TABLE child,parent; SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; @@ -1142,5 +1139,31 @@ DELETE FROM t2; DELETE FROM t1; DROP DATABASE `#mysql50##mysql50#d-b`; USE test; +# +# MDEV-35962 CREATE INDEX fails to heal a FOREIGN KEY constraint +# +CREATE TABLE t2 (b INT, FOREIGN KEY (b) REFERENCES t1(a)) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +SET STATEMENT foreign_key_checks=0 FOR +CREATE TABLE t2 (b INT, FOREIGN KEY (b) REFERENCES t1(a)) ENGINE=InnoDB; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") +SET STATEMENT foreign_key_checks=0 FOR +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`a`)) +ALTER TABLE t1 ADD KEY(a), ALGORITHM=NOCOPY; +INSERT INTO t2 VALUES (1); +DROP INDEX b ON t2; +ERROR HY000: Cannot drop index 'b': needed in a foreign key constraint +SET STATEMENT foreign_key_checks=0 FOR +DROP INDEX b ON t2; +DELETE FROM t2; +DELETE FROM t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`a`)) +ALTER TABLE t2 ADD KEY(b), ALGORITHM=NOCOPY; +DELETE FROM t1; +DROP TABLE t2, t1; # End of 10.6 tests SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index e31320ee810..23e9bf8fc82 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -142,9 +142,6 @@ INSERT INTO child SET a=1; --error ER_ROW_IS_REFERENCED_2 DELETE FROM parent; ALTER TABLE child ADD INDEX(a); ---error ER_ROW_IS_REFERENCED_2 -DELETE FROM parent; -ALTER TABLE child FORCE; DELETE FROM parent; DROP TABLE child,parent; @@ -1205,6 +1202,34 @@ DELETE FROM t1; DROP DATABASE `#mysql50##mysql50#d-b`; USE test; +--echo # +--echo # MDEV-35962 CREATE INDEX fails to heal a FOREIGN KEY constraint +--echo # + +--error ER_CANT_CREATE_TABLE +CREATE TABLE t2 (b INT, FOREIGN KEY (b) REFERENCES t1(a)) ENGINE=InnoDB; +SET STATEMENT foreign_key_checks=0 FOR +CREATE TABLE t2 (b INT, FOREIGN KEY (b) REFERENCES t1(a)) ENGINE=InnoDB; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +SET STATEMENT foreign_key_checks=0 FOR +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES (1); +ALTER TABLE t1 ADD KEY(a), ALGORITHM=NOCOPY; +INSERT INTO t2 VALUES (1); +--error ER_DROP_INDEX_FK +DROP INDEX b ON t2; +SET STATEMENT foreign_key_checks=0 FOR +DROP INDEX b ON t2; +DELETE FROM t2; +--error ER_ROW_IS_REFERENCED_2 +DELETE FROM t1; +ALTER TABLE t2 ADD KEY(b), ALGORITHM=NOCOPY; +DELETE FROM t1; +DROP TABLE t2, t1; + --echo # End of 10.6 tests SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index a967259a2ab..04e57c83f10 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -11036,6 +11036,37 @@ commit_cache_norebuild( dict_index_remove_from_cache(index->table, index); } + if (ctx->num_to_add_index) { + for (dict_foreign_t* foreign: ctx->new_table->foreign_set) { + if (foreign->foreign_table == ctx->new_table + && !foreign->foreign_index) { + foreign->foreign_index = + dict_foreign_find_index( + foreign->foreign_table, + nullptr, + foreign->foreign_col_names, + foreign->n_fields, nullptr, + /*check_charsets=*/TRUE, + /*check_null=*/FALSE, + nullptr, nullptr, nullptr); + } + } + for (dict_foreign_t* foreign: ctx->new_table->referenced_set) { + if (foreign->referenced_table == ctx->new_table + && !foreign->referenced_index) { + foreign->referenced_index = + dict_foreign_find_index( + foreign->referenced_table, + nullptr, + foreign->referenced_col_names, + foreign->n_fields, nullptr, + /*check_charsets=*/TRUE, + /*check_null=*/FALSE, + nullptr, nullptr, nullptr); + } + } + } + fts_clear_all(ctx->old_table); if (!ctx->is_instant()) {