summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-01-29 14:14:57 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-01-29 15:20:26 +0200
commit6699cac0bf10464feab631ff3909ca8c66405628 (patch)
tree1130b1e0a27387bedd4a731e1102c7cc9a2d986d
parent5e06ee41a46dd9f336e73c0f9b6622c5ea5d548f (diff)
downloadmariadb-git-6699cac0bf10464feab631ff3909ca8c66405628.tar.gz
MDEV-18256 Duplicated call to dict_foreign_remove_from_cache()
ha_innobase::prepare_inplace_alter_table(): Filter out duplicates from ha_alter_info->alter_info->drop_list.elements.
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result9
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test10
-rw-r--r--storage/innobase/handler/handler0alter.cc18
-rw-r--r--storage/xtradb/handler/handler0alter.cc18
4 files changed, 45 insertions, 10 deletions
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result
index f62a251161a..6573d744714 100644
--- a/mysql-test/suite/innodb/r/foreign_key.result
+++ b/mysql-test/suite/innodb/r/foreign_key.result
@@ -61,3 +61,12 @@ ALTER TABLE t1 ADD pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
ALTER TABLE t1 CHANGE COLUMN a b TIME;
SET SESSION FOREIGN_KEY_CHECKS = ON;
DROP TABLE t1;
+#
+# MDEV-18256 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N
+# upon DROP FOREIGN KEY
+#
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 (b INT PRIMARY KEY, FOREIGN KEY fk1 (b) REFERENCES t1 (a))
+ENGINE=InnoDB;
+ALTER TABLE t2 DROP FOREIGN KEY fk1, DROP FOREIGN KEY fk1;
+DROP TABLE t2, t1;
diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test
index dc55a5c3a96..aa35e3abf00 100644
--- a/mysql-test/suite/innodb/t/foreign_key.test
+++ b/mysql-test/suite/innodb/t/foreign_key.test
@@ -86,3 +86,13 @@ ALTER TABLE t1 ADD pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
ALTER TABLE t1 CHANGE COLUMN a b TIME;
SET SESSION FOREIGN_KEY_CHECKS = ON;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-18256 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N
+--echo # upon DROP FOREIGN KEY
+--echo #
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 (b INT PRIMARY KEY, FOREIGN KEY fk1 (b) REFERENCES t1 (a))
+ENGINE=InnoDB;
+ALTER TABLE t2 DROP FOREIGN KEY fk1, DROP FOREIGN KEY fk1;
+DROP TABLE t2, t1;
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index d67defa56e8..17e2810b649 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -3690,12 +3690,14 @@ check_if_ok_to_rename:
continue;
}
+ dict_foreign_t* foreign;
+
for (dict_foreign_set::iterator it
= prebuilt->table->foreign_set.begin();
it != prebuilt->table->foreign_set.end();
++it) {
- dict_foreign_t* foreign = *it;
+ foreign = *it;
const char* fid = strchr(foreign->id, '/');
DBUG_ASSERT(fid);
@@ -3706,7 +3708,6 @@ check_if_ok_to_rename:
if (!my_strcasecmp(system_charset_info,
fid, drop->name)) {
- drop_fk[n_drop_fk++] = foreign;
goto found_fk;
}
}
@@ -3715,12 +3716,19 @@ check_if_ok_to_rename:
drop->name);
goto err_exit;
found_fk:
+ for (ulint i = n_drop_fk; i--; ) {
+ if (drop_fk[i] == foreign) {
+ goto dup_fk;
+ }
+ }
+ drop_fk[n_drop_fk++] = foreign;
+dup_fk:
continue;
}
DBUG_ASSERT(n_drop_fk > 0);
DBUG_ASSERT(n_drop_fk
- == ha_alter_info->alter_info->drop_list.elements);
+ <= ha_alter_info->alter_info->drop_list.elements);
} else {
drop_fk = NULL;
}
@@ -5057,7 +5065,7 @@ commit_try_rebuild(
& Alter_inplace_info::DROP_FOREIGN_KEY)
|| ctx->num_to_drop_fk > 0);
DBUG_ASSERT(ctx->num_to_drop_fk
- == ha_alter_info->alter_info->drop_list.elements);
+ <= ha_alter_info->alter_info->drop_list.elements);
for (dict_index_t* index = dict_table_get_first_index(rebuilt_table);
index;
@@ -5309,7 +5317,7 @@ commit_try_norebuild(
& Alter_inplace_info::DROP_FOREIGN_KEY)
|| ctx->num_to_drop_fk > 0);
DBUG_ASSERT(ctx->num_to_drop_fk
- == ha_alter_info->alter_info->drop_list.elements);
+ <= ha_alter_info->alter_info->drop_list.elements);
for (ulint i = 0; i < ctx->num_to_add_index; i++) {
dict_index_t* index = ctx->add_index[i];
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index b7705691949..c27cd7f1b40 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -3704,12 +3704,14 @@ check_if_ok_to_rename:
continue;
}
+ dict_foreign_t* foreign;
+
for (dict_foreign_set::iterator it
= prebuilt->table->foreign_set.begin();
it != prebuilt->table->foreign_set.end();
++it) {
- dict_foreign_t* foreign = *it;
+ foreign = *it;
const char* fid = strchr(foreign->id, '/');
DBUG_ASSERT(fid);
@@ -3720,7 +3722,6 @@ check_if_ok_to_rename:
if (!my_strcasecmp(system_charset_info,
fid, drop->name)) {
- drop_fk[n_drop_fk++] = foreign;
goto found_fk;
}
}
@@ -3729,12 +3730,19 @@ check_if_ok_to_rename:
drop->name);
goto err_exit;
found_fk:
+ for (ulint i = n_drop_fk; i--; ) {
+ if (drop_fk[i] == foreign) {
+ goto dup_fk;
+ }
+ }
+ drop_fk[n_drop_fk++] = foreign;
+dup_fk:
continue;
}
DBUG_ASSERT(n_drop_fk > 0);
DBUG_ASSERT(n_drop_fk
- == ha_alter_info->alter_info->drop_list.elements);
+ <= ha_alter_info->alter_info->drop_list.elements);
} else {
drop_fk = NULL;
}
@@ -5071,7 +5079,7 @@ commit_try_rebuild(
& Alter_inplace_info::DROP_FOREIGN_KEY)
|| ctx->num_to_drop_fk > 0);
DBUG_ASSERT(ctx->num_to_drop_fk
- == ha_alter_info->alter_info->drop_list.elements);
+ <= ha_alter_info->alter_info->drop_list.elements);
for (dict_index_t* index = dict_table_get_first_index(rebuilt_table);
index;
@@ -5325,7 +5333,7 @@ commit_try_norebuild(
& Alter_inplace_info::DROP_FOREIGN_KEY)
|| ctx->num_to_drop_fk > 0);
DBUG_ASSERT(ctx->num_to_drop_fk
- == ha_alter_info->alter_info->drop_list.elements);
+ <= ha_alter_info->alter_info->drop_list.elements);
for (ulint i = 0; i < ctx->num_to_add_index; i++) {
dict_index_t* index = ctx->add_index[i];