summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb/r/foreign-keys.result16
-rw-r--r--mysql-test/suite/innodb/t/foreign-keys.test26
-rw-r--r--storage/innobase/dict/dict0dict.c10
3 files changed, 52 insertions, 0 deletions
diff --git a/mysql-test/suite/innodb/r/foreign-keys.result b/mysql-test/suite/innodb/r/foreign-keys.result
new file mode 100644
index 00000000000..be8d27b152c
--- /dev/null
+++ b/mysql-test/suite/innodb/r/foreign-keys.result
@@ -0,0 +1,16 @@
+#
+# Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE
+# ADD FOREIGN KEY
+#
+CREATE TABLE `department` (`department_id` INT, `department_people_fk` INT,
+PRIMARY KEY (`department_id`)) engine=innodb;
+CREATE TABLE `title` (`title_id` INT, `title_manager_fk` INT,
+`title_reporter_fk` INT, PRIMARY KEY (`title_id`));
+CREATE TABLE `people` (`people_id` INT, PRIMARY KEY (`people_id`));
+ALTER TABLE `department` ADD FOREIGN KEY (`department_people_fk`) REFERENCES
+`people` (`people_id`);
+ALTER TABLE `title` ADD FOREIGN KEY (`title_manager_fk`) REFERENCES `people`
+(`people_id`);
+ALTER TABLE `title` ADD FOREIGN KEY (`title_reporter_fk`) REFERENCES `people`
+(`people_id`);
+drop table title, department, people;
diff --git a/mysql-test/suite/innodb/t/foreign-keys.test b/mysql-test/suite/innodb/t/foreign-keys.test
new file mode 100644
index 00000000000..45642cf28a7
--- /dev/null
+++ b/mysql-test/suite/innodb/t/foreign-keys.test
@@ -0,0 +1,26 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+--echo #
+--echo # Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE
+--echo # ADD FOREIGN KEY
+--echo #
+
+CREATE TABLE `department` (`department_id` INT, `department_people_fk` INT,
+PRIMARY KEY (`department_id`)) engine=innodb;
+
+CREATE TABLE `title` (`title_id` INT, `title_manager_fk` INT,
+`title_reporter_fk` INT, PRIMARY KEY (`title_id`));
+
+CREATE TABLE `people` (`people_id` INT, PRIMARY KEY (`people_id`));
+
+ALTER TABLE `department` ADD FOREIGN KEY (`department_people_fk`) REFERENCES
+`people` (`people_id`);
+
+ALTER TABLE `title` ADD FOREIGN KEY (`title_manager_fk`) REFERENCES `people`
+(`people_id`);
+
+ALTER TABLE `title` ADD FOREIGN KEY (`title_reporter_fk`) REFERENCES `people`
+(`people_id`);
+
+drop table title, department, people;
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index e225966afe6..0e4691658d5 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -1123,6 +1123,11 @@ dict_table_rename_in_cache(
/* The id will be changed. So remove old one */
rbt_delete(foreign->foreign_table->foreign_rbt, foreign->id);
+ if (foreign->referenced_table) {
+ rbt_delete(foreign->referenced_table->referenced_rbt,
+ foreign->id);
+ }
+
if (ut_strlen(foreign->foreign_table_name)
< ut_strlen(table->name)) {
/* Allocate a longer name buffer;
@@ -1273,6 +1278,11 @@ dict_table_rename_in_cache(
rbt_insert(foreign->foreign_table->foreign_rbt,
foreign->id, &foreign);
+ if (foreign->referenced_table) {
+ rbt_insert(foreign->referenced_table->referenced_rbt,
+ foreign->id, &foreign);
+ }
+
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}