diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-04 19:00:21 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-04 19:00:21 +0300 |
commit | 3f65ce5781e7eb047be1471bebddeaa002b4b0cd (patch) | |
tree | 8aa37b31f70f553a7d29f72144a81efd39a4f419 | |
parent | d467bb7e5e7902cf763c86cae71fde4f08e2ae3e (diff) | |
parent | 2748c4993c68aa4b03049a97f3657de42dd01c52 (diff) | |
download | mariadb-git-3f65ce5781e7eb047be1471bebddeaa002b4b0cd.tar.gz |
Merge 10.1 into 10.2
-rw-r--r-- | mysql-test/suite/innodb/r/foreign_key.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/foreign_key.test | 13 | ||||
-rw-r--r-- | storage/innobase/dict/dict0mem.cc | 46 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0mem.cc | 46 |
4 files changed, 101 insertions, 14 deletions
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 749aa5943d3..d1a5016d429 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -280,6 +280,16 @@ ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES tx(x); ALTER TABLE t1 DROP KEY idx; ALTER TABLE t1 CHANGE a c INT; DROP TABLE t1; +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY idx(f1)) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1 (f1); +ALTER TABLE t1 ADD COLUMN f INT; +SET FOREIGN_KEY_CHECKS= OFF; +ALTER TABLE t1 DROP KEY idx; +ALTER TABLE t1 ADD KEY idx (f1); +SET FOREIGN_KEY_CHECKS= ON; +ALTER TABLE t1 DROP f3; +ALTER TABLE t1 CHANGE f f3 INT; +DROP TABLE t1; SET FOREIGN_KEY_CHECKS=1; # Start of 10.2 tests # diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index b5a84756914..13203383188 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -266,6 +266,19 @@ ALTER TABLE t1 DROP KEY idx; ALTER TABLE t1 CHANGE a c INT; # Cleanup DROP TABLE t1; + +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY idx(f1)) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1 (f1); +ALTER TABLE t1 ADD COLUMN f INT; +SET FOREIGN_KEY_CHECKS= OFF; +ALTER TABLE t1 DROP KEY idx; +ALTER TABLE t1 ADD KEY idx (f1); +SET FOREIGN_KEY_CHECKS= ON; +ALTER TABLE t1 DROP f3; +ALTER TABLE t1 CHANGE f f3 INT; +# Cleanup +DROP TABLE t1; + SET FOREIGN_KEY_CHECKS=1; --echo # Start of 10.2 tests diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 9190272a4c5..02ab1d77eb3 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -559,17 +559,15 @@ dict_mem_table_col_rename_low( } } - dict_index_t* new_index = dict_foreign_find_index( + /* New index can be null if InnoDB already dropped + the foreign index when FOREIGN_KEY_CHECKS is + disabled */ + foreign->foreign_index = dict_foreign_find_index( foreign->foreign_table, NULL, foreign->foreign_col_names, foreign->n_fields, NULL, true, false, NULL, NULL, NULL); - /* New index can be null if InnoDB already dropped - the foreign index when FOREIGN_KEY_CHECKS is - disabled */ - foreign->foreign_index = new_index; - } else { for (unsigned f = 0; f < foreign->n_fields; f++) { @@ -591,7 +589,41 @@ dict_mem_table_col_rename_low( foreign = *it; - ut_ad(foreign->referenced_index != NULL); + if (!foreign->referenced_index) { + /* Referenced index could have been dropped + when foreign_key_checks is disabled. In that case, + rename the corresponding referenced_col_names and + find the equivalent referenced index also */ + for (unsigned f = 0; f < foreign->n_fields; f++) { + + const char*& rc = + foreign->referenced_col_names[f]; + if (strcmp(rc, from)) { + continue; + } + + if (to_len <= strlen(rc)) { + memcpy(const_cast<char*>(rc), to, + to_len + 1); + } else { + rc = static_cast<char*>( + mem_heap_dup( + foreign->heap, + to, to_len + 1)); + } + } + + /* New index can be null if InnoDB already dropped + the referenced index when FOREIGN_KEY_CHECKS is + disabled */ + foreign->referenced_index = dict_foreign_find_index( + foreign->referenced_table, NULL, + foreign->referenced_col_names, + foreign->n_fields, NULL, true, false, + NULL, NULL, NULL); + return; + } + for (unsigned f = 0; f < foreign->n_fields; f++) { /* foreign->referenced_col_names[] need to be diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc index 51ca6de8cd2..89b9bd9aead 100644 --- a/storage/xtradb/dict/dict0mem.cc +++ b/storage/xtradb/dict/dict0mem.cc @@ -416,17 +416,15 @@ dict_mem_table_col_rename_low( } } - dict_index_t* new_index = dict_foreign_find_index( + /* New index can be null if XtraDB already dropped + the foreign index when FOREIGN_KEY_CHECKS is + disabled */ + foreign->foreign_index = dict_foreign_find_index( foreign->foreign_table, NULL, foreign->foreign_col_names, foreign->n_fields, NULL, true, false, NULL, NULL, NULL); - /* New index can be null if XtraDB already dropped - the foreign index when FOREIGN_KEY_CHECKS is - disabled */ - foreign->foreign_index = new_index; - } else { for (unsigned f = 0; f < foreign->n_fields; f++) { @@ -448,7 +446,41 @@ dict_mem_table_col_rename_low( foreign = *it; - ut_ad(foreign->referenced_index != NULL); + if (!foreign->referenced_index) { + /* Referenced index could have been dropped + when foreign_key_checks is disabled. In that case, + rename the corresponding referenced_col_names and + find the equivalent referenced index also */ + for (unsigned f = 0; f < foreign->n_fields; f++) { + + const char*& rc = + foreign->referenced_col_names[f]; + + if (strcmp(rc, from)) { + continue; + } + + if (to_len <= strlen(rc)) { + memcpy(const_cast<char*>(rc), to, + to_len + 1); + } else { + rc = static_cast<char*>( + mem_heap_dup( + foreign->heap, + to, to_len + 1)); + } + } + + /* New index can be null if InnoDB already dropped + the referenced index when FOREIGN_KEY_CHECKS is + disabled */ + foreign->referenced_index = dict_foreign_find_index( + foreign->referenced_table, NULL, + foreign->referenced_col_names, + foreign->n_fields, NULL, true, false, + NULL, NULL, NULL); + return; + } for (unsigned f = 0; f < foreign->n_fields; f++) { /* foreign->referenced_col_names[] need to be |