diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2023-01-18 16:52:14 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2023-01-26 17:15:21 +0300 |
commit | 9de7d1e2bcde319f1ba24aa7b2d0248abc64a688 (patch) | |
tree | 384de7e2cca5dce275a50a7c7340cb04c97a8eee | |
parent | 09ea9ee2a873717000d1942dc30751fbb50ff86e (diff) | |
download | mariadb-git-9de7d1e2bcde319f1ba24aa7b2d0248abc64a688.tar.gz |
MDEV-29779 Unexpected ER_ERROR_ON_RENAME upon CREATE OR REPLACE
When table was renamed to backup its foreign keys was loaded into
cache and checked for validity. We must not load foreign keys in that
case: there is nothing to check as these foreign keys was already
there and we don't need them in cache for temporary table.
-rw-r--r-- | mysql-test/suite/innodb/r/foreign_key.result | 11 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/foreign_key.test | 13 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 44 |
3 files changed, 47 insertions, 21 deletions
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 5489fdd94c9..6a151832c06 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -1089,3 +1089,14 @@ create or replace table t1 (a int) engine=innodb; select * from information_schema.innodb_sys_foreign; ID FOR_NAME REF_NAME N_COLS TYPE drop tables if exists t1, t2; +# +# MDEV-29779 Unexpected ER_ERROR_ON_RENAME upon CREATE OR REPLACE +# +create table t1 (a int) engine=innodb; +create table t2 (pk int primary key) engine=innodb; +create or replace table t1 (a int, foreign key(a) references t2(pk)) engine=innodb; +set foreign_key_checks = off; +alter table t1 modify a bigint; +set foreign_key_checks = on; +create or replace table t1 (a int) engine=innodb; +drop tables t1, t2; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 4d8eaf88c13..8ceaf5ffcbc 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -1101,5 +1101,18 @@ select * from information_schema.innodb_sys_foreign; drop tables if exists t1, t2; +--echo # +--echo # MDEV-29779 Unexpected ER_ERROR_ON_RENAME upon CREATE OR REPLACE +--echo # +create table t1 (a int) engine=innodb; +create table t2 (pk int primary key) engine=innodb; +create or replace table t1 (a int, foreign key(a) references t2(pk)) engine=innodb; + +set foreign_key_checks = off; +alter table t1 modify a bigint; +set foreign_key_checks = on; + +create or replace table t1 (a int) engine=innodb; +drop tables t1, t2; --source include/wait_until_count_sessions.inc diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 22a302f5de1..12d8b528db9 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2779,39 +2779,41 @@ row_rename_table_for_mysql( an ALTER TABLE, not in a RENAME. */ dict_names_t fk_tables; - err = dict_load_foreigns( - new_name, nullptr, trx->id, - !old_is_tmp || trx->check_foreigns, - fk == RENAME_FK || fk == RENAME_ALTER_COPY - ? DICT_ERR_IGNORE_NONE - : DICT_ERR_IGNORE_FK_NOKEY, - fk_tables); + if (!(new_is_tmp && fk == RENAME_FK)) { + err = dict_load_foreigns( + new_name, nullptr, trx->id, + !old_is_tmp || trx->check_foreigns, + fk == RENAME_FK || fk == RENAME_ALTER_COPY + ? DICT_ERR_IGNORE_NONE + : DICT_ERR_IGNORE_FK_NOKEY, + fk_tables); - if (err != DB_SUCCESS) { - if (old_is_tmp) { - /* In case of copy alter, ignore the - loading of foreign key constraint - when foreign_key_check is disabled */ - ib::error_or_warn(trx->check_foreigns) + if (err != DB_SUCCESS) { + if (old_is_tmp) { + /* In case of copy alter, ignore the + loading of foreign key constraint + when foreign_key_check is disabled */ + ib::error_or_warn(trx->check_foreigns) << "In ALTER TABLE " << ut_get_name(trx, new_name) << " has or is referenced in foreign" " key constraints which are not" " compatible with the new table" " definition."; - if (!trx->check_foreigns) { - err = DB_SUCCESS; - break; - } - } else { - ib::error() << "In RENAME TABLE table " + if (!trx->check_foreigns) { + err = DB_SUCCESS; + break; + } + } else { + ib::error() << "In RENAME TABLE table " << ut_get_name(trx, new_name) << " is referenced in foreign key" " constraints which are not compatible" " with the new table definition."; - } + } - goto rollback_and_exit; + goto rollback_and_exit; + } } /* Check whether virtual column or stored column affects |