mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-29092 FOREIGN_KEY_CHECKS does not prevent non-copy alter from creating invalid FK structure
Problem: ======== - InnoDB should have two keys on the same column for the self referencing foreign key relation. Solution: ========= - Allow self referential foreign key relation to work with one key.
This commit is contained in:
@ -654,3 +654,34 @@ t2 CREATE TABLE `t2` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
drop table t2;
|
drop table t2;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-29092 FOREIGN_KEY_CHECKS does not prevent non-copy
|
||||||
|
# alter from creating invalid FK structures
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(f1 INT, KEY(f1),
|
||||||
|
FOREIGN KEY(f1) references t1(f1))ENGINE=InnoDB;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`f1` int(11) DEFAULT NULL,
|
||||||
|
KEY `f1` (`f1`),
|
||||||
|
CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(f1 INT, KEY(f1),
|
||||||
|
FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=InnoDB;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`f1` int(11) DEFAULT NULL,
|
||||||
|
KEY `f1` (`f1`),
|
||||||
|
CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
ALTER TABLE t1 DROP KEY f1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`f1` int(11) DEFAULT NULL,
|
||||||
|
CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -86,8 +86,7 @@ CREATE TABLE t2 (f2 INT, FOREIGN KEY(f2) REFERENCES t1 (f2)) ENGINE=InnoDB;
|
|||||||
CREATE TABLE t3 (a INT) ENGINE=InnoDB;
|
CREATE TABLE t3 (a INT) ENGINE=InnoDB;
|
||||||
ERROR HY000: Can't create table `test`.`t3` (errno: 150 "Foreign key constraint is incorrectly formed")
|
ERROR HY000: Can't create table `test`.`t3` (errno: 150 "Foreign key constraint is incorrectly formed")
|
||||||
ALTER TABLE t1 RENAME TO t3;
|
ALTER TABLE t1 RENAME TO t3;
|
||||||
ERROR HY000: Error on rename of './test/t1' to './test/t3' (errno: 150 "Foreign key constraint is incorrectly formed")
|
ALTER TABLE t3 FORCE;
|
||||||
ALTER TABLE t1 FORCE;
|
TRUNCATE TABLE t3;
|
||||||
TRUNCATE TABLE t1;
|
|
||||||
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `test`.`t3` (`f2`))
|
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `test`.`t3` (`f2`))
|
||||||
DROP TABLE t2, t1;
|
DROP TABLE t2, t3;
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
call mtr.add_suppression("In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition.");
|
|
||||||
# restart
|
|
||||||
create table t1 (f1 integer primary key) engine innodb;
|
|
||||||
alter table t1 add constraint c1 foreign key (f1) references t1(f1);
|
|
||||||
ERROR HY000: Error on rename of '#sql-temporary' to './test/t1' (errno: 150 "Foreign key constraint is incorrectly formed")
|
|
||||||
drop table t1;
|
|
@ -511,3 +511,19 @@ alter table t2 drop key t,algorithm=inplace;
|
|||||||
show create table t2;
|
show create table t2;
|
||||||
drop table t2;
|
drop table t2;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-29092 FOREIGN_KEY_CHECKS does not prevent non-copy
|
||||||
|
--echo # alter from creating invalid FK structures
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1(f1 INT, KEY(f1),
|
||||||
|
FOREIGN KEY(f1) references t1(f1))ENGINE=InnoDB;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1(f1 INT, KEY(f1),
|
||||||
|
FOREIGN KEY(f1) REFERENCES t1(f1))ENGINE=InnoDB;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
ALTER TABLE t1 DROP KEY f1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -85,10 +85,8 @@ SET FOREIGN_KEY_CHECKS= ON;
|
|||||||
CREATE TABLE t2 (f2 INT, FOREIGN KEY(f2) REFERENCES t1 (f2)) ENGINE=InnoDB;
|
CREATE TABLE t2 (f2 INT, FOREIGN KEY(f2) REFERENCES t1 (f2)) ENGINE=InnoDB;
|
||||||
--error ER_CANT_CREATE_TABLE
|
--error ER_CANT_CREATE_TABLE
|
||||||
CREATE TABLE t3 (a INT) ENGINE=InnoDB;
|
CREATE TABLE t3 (a INT) ENGINE=InnoDB;
|
||||||
--replace_result $datadir ./
|
|
||||||
--error ER_ERROR_ON_RENAME
|
|
||||||
ALTER TABLE t1 RENAME TO t3;
|
ALTER TABLE t1 RENAME TO t3;
|
||||||
ALTER TABLE t1 FORCE;
|
ALTER TABLE t3 FORCE;
|
||||||
--error ER_TRUNCATE_ILLEGAL_FK
|
--error ER_TRUNCATE_ILLEGAL_FK
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t3;
|
||||||
DROP TABLE t2, t1;
|
DROP TABLE t2, t3;
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
# Bug 12902967: Creating self referencing fk on same index unhandled,
|
|
||||||
# confusing error
|
|
||||||
#
|
|
||||||
# Creating a self referencing foreign key on the same
|
|
||||||
# column/index is an unhandled exception, it should throw a sensible
|
|
||||||
# error but instead implies that your data dictionary may now be out
|
|
||||||
# of sync:
|
|
||||||
|
|
||||||
--source include/have_innodb.inc
|
|
||||||
--source include/not_embedded.inc
|
|
||||||
|
|
||||||
call mtr.add_suppression("In ALTER TABLE .* has or is referenced in foreign key constraints which are not compatible with the new table definition.");
|
|
||||||
|
|
||||||
let error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
|
||||||
--source include/restart_mysqld.inc
|
|
||||||
|
|
||||||
create table t1 (f1 integer primary key) engine innodb;
|
|
||||||
|
|
||||||
# The below statement should produce error message in error log.
|
|
||||||
# This error message should mention problem with foreign keys
|
|
||||||
# rather than with data dictionary.
|
|
||||||
--replace_regex /'\.\/test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
|
|
||||||
--error ER_ERROR_ON_RENAME
|
|
||||||
alter table t1 add constraint c1 foreign key (f1) references t1(f1);
|
|
||||||
drop table t1;
|
|
@ -2697,8 +2697,7 @@ dict_foreign_find_index(
|
|||||||
for (dict_index_t* index = dict_table_get_first_index(table);
|
for (dict_index_t* index = dict_table_get_first_index(table);
|
||||||
index;
|
index;
|
||||||
index = dict_table_get_next_index(index)) {
|
index = dict_table_get_next_index(index)) {
|
||||||
if (types_idx != index
|
if (!index->to_be_dropped
|
||||||
&& !index->to_be_dropped
|
|
||||||
&& !dict_index_is_online_ddl(index)
|
&& !dict_index_is_online_ddl(index)
|
||||||
&& dict_foreign_qualify_index(
|
&& dict_foreign_qualify_index(
|
||||||
table, col_names, columns, n_cols,
|
table, col_names, columns, n_cols,
|
||||||
|
Reference in New Issue
Block a user