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.
parent dc9ac926
......@@ -654,3 +654,34 @@ t2 CREATE TABLE `t2` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t2;
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;
ERROR HY000: Can't create table `test`.`t3` (errno: 150 "Foreign key constraint is incorrectly formed")
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 t1 FORCE;
TRUNCATE TABLE t1;
ALTER TABLE t3 FORCE;
TRUNCATE TABLE t3;
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;
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;
drop table t2;
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;
--error ER_CANT_CREATE_TABLE
CREATE TABLE t3 (a INT) ENGINE=InnoDB;
--replace_result $datadir ./
--error ER_ERROR_ON_RENAME
ALTER TABLE t1 RENAME TO t3;
ALTER TABLE t1 FORCE;
ALTER TABLE t3 FORCE;
--error ER_TRUNCATE_ILLEGAL_FK
TRUNCATE TABLE t1;
DROP TABLE t2, t1;
TRUNCATE TABLE t3;
DROP TABLE t2, t3;
# 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);
index;
index = dict_table_get_next_index(index)) {
if (types_idx != index
&& !index->to_be_dropped
if (!index->to_be_dropped
&& !dict_index_is_online_ddl(index)
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment