summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2023-01-18 16:52:14 +0300
committerAleksey Midenkov <midenok@gmail.com>2023-01-26 17:15:21 +0300
commit9de7d1e2bcde319f1ba24aa7b2d0248abc64a688 (patch)
tree384de7e2cca5dce275a50a7c7340cb04c97a8eee
parent09ea9ee2a873717000d1942dc30751fbb50ff86e (diff)
downloadmariadb-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.result11
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test13
-rw-r--r--storage/innobase/row/row0mysql.cc44
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