Commit f97dfa81 authored by Annamalai Gurusami's avatar Annamalai Gurusami

Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE ADD FOREIGN KEY

Problem:

We maintain two rb trees in each dict_table_t.  The foreign_rbt must be in
sync with foreign_list.  The referenced_rbt must be in sync with
referenced_list. There is one function which checks this consistency and it
failed, resulting in an assert failure.

The root cause of the problem was identified that the search order was 
lost in the referenced_rbt.  This is because while renaming the table,
we didn't not refresh this referenced_rbt.

Solution:

When a foreign key is renamed, we must delete and re-insert into both
foreign_rbt and referenced_rbt.  

rb#6412 approved by Jimmy.
parent 97beafc5
#
# 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;
--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;
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment