Skip to content

Commit d2bb29a

Browse files
committed
MDEV-40776 Atomic CREATE OR REPLACE silently breaks the foreign key
Give an error if one tries to drop a table referenced by a foreign keys This is needed as innodb will keep the reference to the origina table even when it is renamed to a temporary name as part of create or replace. Other things: - Changed the error message for ER_TRUNCATE_ILLEGAL_FK to say "Cannot drop or truncate a table ..."
1 parent 34b9dc4 commit d2bb29a

17 files changed

Lines changed: 122 additions & 29 deletions

mysql-test/main/create_or_replace.result

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -933,14 +933,19 @@ drop prepare stmt;
933933
create table t1 (x int primary key, y int) engine innodb;
934934
create table t2 (x int references t1(x)) engine innodb;
935935
create or replace table t1 (x int primary key);
936+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`x`) REFERENCES `test`.`t1` (`x`))
936937
create table t3 (x int);
937938
create or replace table t1 like t3;
939+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`x`) REFERENCES `test`.`t1` (`x`))
938940
create or replace table t1 select * from t3;
941+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`x`) REFERENCES `test`.`t1` (`x`))
939942
show create table t1;
940943
Table Create Table
941944
t1 CREATE TABLE `t1` (
942-
`x` int(11) DEFAULT NULL
943-
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
945+
`x` int(11) NOT NULL,
946+
`y` int(11) DEFAULT NULL,
947+
PRIMARY KEY (`x`)
948+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
944949
drop tables t3, t2, t1;
945950
# UNIQUE
946951
create table t1 (pk int auto_increment primary key, a varchar(2300), unique (a)) engine aria character set latin1;

mysql-test/main/create_or_replace.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,9 +684,12 @@ drop prepare stmt;
684684
--list_files $MYSQLD_DATADIR/test *sql*
685685
create table t1 (x int primary key, y int) engine innodb;
686686
create table t2 (x int references t1(x)) engine innodb;
687+
--error ER_TRUNCATE_ILLEGAL_FK
687688
create or replace table t1 (x int primary key);
688689
create table t3 (x int);
690+
--error ER_TRUNCATE_ILLEGAL_FK
689691
create or replace table t1 like t3;
692+
--error ER_TRUNCATE_ILLEGAL_FK
690693
create or replace table t1 select * from t3;
691694
show create table t1;
692695
drop tables t3, t2, t1;

mysql-test/main/trigger-trans.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ CREATE TRIGGER t1_ad AFTER DELETE ON t1 FOR EACH ROW SET @b = 1;
160160
SET @a = 0;
161161
SET @b = 0;
162162
TRUNCATE t1;
163-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`a`))
163+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`a`))
164164
SELECT @a, @b;
165165
@a @b
166166
0 0

mysql-test/suite/atomic/create_fk.result

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,51 @@ select * from t1;
4949
a b c
5050
1 1 1
5151
drop table t1;
52+
#
53+
# MDEV-40776 Atomic CREATE OR REPLACE silently breaks the foreign key
54+
#
55+
create table t1 (pk int primary key, a int) engine=InnoDB;
56+
create table t2 (pk int primary key, b int, foreign key(b) references t1(pk)) engine=InnoDB;
57+
insert into t1 values (1,10),(2,20);
58+
insert into t2 values (1,1),(2,2);
59+
create or replace table t1 (pk int primary key, a int) engine=InnoDB;
60+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`pk`))
61+
select * from t1;
62+
pk a
63+
1 10
64+
2 20
65+
select * from t2;
66+
pk b
67+
1 1
68+
2 2
69+
show create table t2;
70+
Table Create Table
71+
t2 CREATE TABLE `t2` (
72+
`pk` int(11) NOT NULL,
73+
`b` int(11) DEFAULT NULL,
74+
PRIMARY KEY (`pk`),
75+
KEY `b` (`b`),
76+
CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `t1` (`pk`)
77+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
78+
set @@foreign_key_checks=0;
79+
create or replace table t1 (pk int primary key, a int) engine=InnoDB;
80+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `test`.`t1` (`pk`))
81+
select * from t1;
82+
pk a
83+
1 10
84+
2 20
85+
select * from t2;
86+
pk b
87+
1 1
88+
2 2
89+
show create table t2;
90+
Table Create Table
91+
t2 CREATE TABLE `t2` (
92+
`pk` int(11) NOT NULL,
93+
`b` int(11) DEFAULT NULL,
94+
PRIMARY KEY (`pk`),
95+
KEY `b` (`b`),
96+
CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `t1` (`pk`)
97+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
98+
set @@foreign_key_checks=default;
99+
drop table if exists t2, t1;

mysql-test/suite/atomic/create_fk.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,28 @@ insert into t1 values (1,1,1);
5252
create or replace table t1 (a int primary key, b int, c int, g int, constraint d foreign key e (b) references t1 (a)) engine=innodb select 1 as a ,2 as b,3 as c;
5353
select * from t1;
5454
drop table t1;
55+
56+
--echo #
57+
--echo # MDEV-40776 Atomic CREATE OR REPLACE silently breaks the foreign key
58+
--echo #
59+
60+
create table t1 (pk int primary key, a int) engine=InnoDB;
61+
create table t2 (pk int primary key, b int, foreign key(b) references t1(pk)) engine=InnoDB;
62+
insert into t1 values (1,10),(2,20);
63+
insert into t2 values (1,1),(2,2);
64+
65+
--error ER_TRUNCATE_ILLEGAL_FK
66+
create or replace table t1 (pk int primary key, a int) engine=InnoDB;
67+
select * from t1;
68+
select * from t2;
69+
show create table t2;
70+
71+
set @@foreign_key_checks=0;
72+
--error ER_TRUNCATE_ILLEGAL_FK
73+
create or replace table t1 (pk int primary key, a int) engine=InnoDB;
74+
select * from t1;
75+
select * from t2;
76+
show create table t2;
77+
set @@foreign_key_checks=default;
78+
drop table if exists t2, t1;
79+

mysql-test/suite/innodb/r/foreign_key.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ INSERT INTO child SET a=1;
10731073
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`))
10741074
connection default;
10751075
TRUNCATE TABLE parent;
1076-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`))
1076+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`))
10771077
DROP TABLE parent;
10781078
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
10791079
SET innodb_lock_wait_timeout=0;
@@ -1104,7 +1104,7 @@ ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
11041104
ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT;
11051105
SET foreign_key_checks=ON;
11061106
TRUNCATE TABLE parent;
1107-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`))
1107+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`))
11081108
ALTER TABLE parent FORCE, ALGORITHM=COPY;
11091109
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
11101110
RENAME TABLE parent TO transparent;

mysql-test/suite/innodb/r/innodb-truncate.result

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=INNODB;
88
CREATE TABLE t2 (fk INT NOT NULL, FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=INNODB;
99
TRUNCATE TABLE t1;
10-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`))
10+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`))
1111
# Truncation of child should succeed.
1212
TRUNCATE TABLE t2;
1313
DROP TABLE t2;
@@ -32,15 +32,15 @@ TRUNCATE TABLE t2;
3232
TRUNCATE TABLE t3;
3333
SET @@SESSION.foreign_key_checks = 1;
3434
TRUNCATE TABLE t1;
35-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`))
35+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`))
3636
TRUNCATE TABLE t2;
3737
TRUNCATE TABLE t3;
3838
LOCK TABLES t1 WRITE;
3939
SET @@SESSION.foreign_key_checks = 0;
4040
TRUNCATE TABLE t1;
4141
SET @@SESSION.foreign_key_checks = 1;
4242
TRUNCATE TABLE t1;
43-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`))
43+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fk`) REFERENCES `test`.`t1` (`pk`))
4444
UNLOCK TABLES;
4545
DROP TABLE t3,t2,t1;
4646
SET @@SESSION.foreign_key_checks = @old_foreign_key_checks;
@@ -88,7 +88,7 @@ ERROR HY000: Can't create table `test`.`t3` (errno: 150 "Foreign key constraint
8888
ALTER TABLE t1 RENAME TO t3;
8989
ALTER TABLE t3 FORCE;
9090
TRUNCATE TABLE t3;
91-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`f2`) REFERENCES `test`.`t3` (`f2`))
91+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`f2`) REFERENCES `test`.`t3` (`f2`))
9292
DROP TABLE t2, t3;
9393
#
9494
# MDEV-24861 Assertion `trx->rsegs.m_redo.rseg' failed

mysql-test/suite/innodb/r/innodb.result

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2410,15 +2410,15 @@ SELECT * FROM t1;
24102410
id
24112411
1
24122412
TRUNCATE t1;
2413-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`id`) REFERENCES `test`.`t1` (`id`))
2413+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`id`) REFERENCES `test`.`t1` (`id`))
24142414
INSERT INTO t1 (id) VALUES (NULL);
24152415
SELECT * FROM t1;
24162416
id
24172417
1
24182418
2
24192419
DELETE FROM t1;
24202420
TRUNCATE t1;
2421-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`id`) REFERENCES `test`.`t1` (`id`))
2421+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`id`) REFERENCES `test`.`t1` (`id`))
24222422
INSERT INTO t1 (id) VALUES (NULL);
24232423
SELECT * FROM t1;
24242424
id
@@ -2596,15 +2596,15 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail
25962596
update t4 set a=2;
25972597
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
25982598
truncate t1;
2599-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`))
2599+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`))
26002600
truncate t3;
2601-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t4`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`t3` (`a`))
2601+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t4`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`t3` (`a`))
26022602
truncate t2;
26032603
truncate t4;
26042604
truncate t1;
2605-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`))
2605+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`))
26062606
truncate t3;
2607-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t4`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`t3` (`a`))
2607+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t4`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`t3` (`a`))
26082608
drop table t4,t3,t2,t1;
26092609
create table t1 (a varchar(255) character set utf8mb3,
26102610
b varchar(255) character set utf8mb3,

mysql-test/suite/innodb/r/innodb_mysql.result

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,7 +2449,7 @@ INSERT INTO t2 VALUES (3,2);
24492449
SET AUTOCOMMIT = 0;
24502450
START TRANSACTION;
24512451
TRUNCATE TABLE t1;
2452-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`))
2452+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`))
24532453
SELECT * FROM t1;
24542454
id
24552455
1
@@ -2461,7 +2461,7 @@ id
24612461
2
24622462
START TRANSACTION;
24632463
TRUNCATE TABLE t1;
2464-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`))
2464+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`))
24652465
SELECT * FROM t1;
24662466
id
24672467
1
@@ -2479,7 +2479,7 @@ id
24792479
2
24802480
COMMIT;
24812481
TRUNCATE TABLE t1;
2482-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`))
2482+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`))
24832483
SELECT * FROM t1;
24842484
id
24852485
1
@@ -2491,7 +2491,7 @@ id
24912491
1
24922492
2
24932493
TRUNCATE TABLE t1;
2494-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`))
2494+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`t1_id`) REFERENCES `test`.`t1` (`id`))
24952495
ROLLBACK;
24962496
SELECT * FROM t1;
24972497
id

mysql-test/suite/innodb/r/truncate_foreign.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ON UPDATE CASCADE)
55
ENGINE=InnoDB;
66
INSERT INTO child SET a=1;
77
TRUNCATE TABLE parent;
8-
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`))
8+
ERROR 42000: Cannot drop or truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`))
99
TRUNCATE TABLE child;
1010
INSERT INTO child SET a=1;
1111
UPDATE parent SET a=2;

0 commit comments

Comments
 (0)