mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
MDEV-6697: Improve foreign keys warnings/errors
There is several different ways to incorrectly define foreign key constraint. In many cases earlier MariaDB versions the error messages produced by these cases are not very clear and helpful. This patch improves the warning messages produced by foreign key parsing.
This commit is contained in:
@@ -10,11 +10,96 @@ id int(11) NOT NULL PRIMARY KEY,
|
||||
a int(11) NOT NULL,
|
||||
b int(11) NOT NULL,
|
||||
c int not null,
|
||||
CONSTRAINT mytest FOREIGN KEY (c) REFERENCES t1(id),
|
||||
CONSTRAINT test FOREIGN KEY (b) REFERENCES t2 (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 121)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 121 InnoDB: foreign key constraint name `test/test` already exists on data dictionary. Foreign key constraint names need to be unique in database. Error in foreign key definition: CONSTRAINT `test` FOREIGN KEY (`b`) REFERENCES `test`.`t2` (`id`).
|
||||
Warning 121 Create or Alter table `test`.`t2` with foreign key constraint failed. Foreign key constraint `test/test` already exists on data dictionary. Foreign key constraint names need to be unique in database. Error in foreign key definition: CONSTRAINT `test` FOREIGN KEY (`b`) REFERENCES `test`.`t2` (`id`).
|
||||
Error 1005 Can't create table 'test.t2' (errno: 121)
|
||||
drop table t1;
|
||||
create table t1(a int) engine=innodb;
|
||||
create table t2(a int, constraint a foreign key a (a) references t1(a)) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key a (a) references t1(a)) engine=innodb.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 150)
|
||||
drop table t1;
|
||||
create table t1(a int not null primary key, b int) engine=innodb;
|
||||
create table t2(a int, b int, constraint a foreign key a (a) references t1(a),
|
||||
constraint a foreign key a (a) references t1(b)) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key a (a) references t1(b)) engine=innodb.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 150)
|
||||
create table t2(a int, b int, constraint a foreign key a (a) references t1(a)) engine=innodb;
|
||||
alter table t2 add constraint b foreign key (b) references t2(b);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key (b) references t2(b).
|
||||
Error 1005 Can't create table '#sql-temporary' (errno: 150)
|
||||
drop table t2, t1;
|
||||
create table t1 (f1 integer primary key) engine=innodb;
|
||||
alter table t1 add constraint c1 foreign key (f1) references t11(f1);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t11` not found in the data dictionary close to foreign key (f1) references t11(f1).
|
||||
Error 1005 Can't create table '#sql-temporary' (errno: 150)
|
||||
drop table t1;
|
||||
create temporary table t1(a int not null primary key, b int, key(b)) engine=innodb;
|
||||
create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Create table `mysqld.1`.`t2` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(a) references t1(a)) engine=innodb.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 150)
|
||||
alter table t1 add foreign key(b) references t1(a);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(b) references t1(a).
|
||||
Error 1005 Can't create table '#sql-temporary' (errno: 150)
|
||||
drop table t1;
|
||||
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
|
||||
alter table t1 add foreign key(a,b) references t1(a);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Foreign key constraint parse error in foreign key(a,b) references t1(a) close to ). Too few referenced columns, you have 1 when you should have 2.
|
||||
Error 1005 Can't create table '#sql-temporary' (errno: 150)
|
||||
drop table t1;
|
||||
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
|
||||
alter table t1 add foreign key(a) references t1(a,b);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Foreign key constraint parse error in foreign key(a) references t1(a,b) close to ). Too few referenced columns, you have 2 when you should have 1.
|
||||
Error 1005 Can't create table '#sql-temporary' (errno: 150)
|
||||
drop table t1;
|
||||
create table t1 (f1 integer not null primary key) engine=innodb;
|
||||
alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update set null;
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Alter table `test`.`t1` with foreign key constraint failed. You have defined a SET NULL condition but column f1 is defined as NOT NULL in foreign key (f1) references t1(f1) on update set null close to on update set null.
|
||||
Error 1005 Can't create table '#sql-temporary' (errno: 150)
|
||||
create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Create table `test`.`t2` with foreign key constraint failed. You have defined a SET NULL condition but column a is defined as NOT NULL in foreign key(a) references t1(f1) on delete set null) engine=innodb close to on delete set null) engine=innodb.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 150)
|
||||
drop table t1;
|
||||
create table t1 (id int not null primary key, f1 int, f2 int, key(f1)) engine=innodb;
|
||||
create table t2(a char(20), key(a), foreign key(a) references t1(f1)) engine=innodb;
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Create table `test`.`t2` with foreign key constraint failed. Field type or character set for column a does not mach referenced column f1 close to foreign key(a) references t1(f1)) engine=innodb
|
||||
Error 1005 Can't create table 'test.t2' (errno: 150)
|
||||
drop table t1;
|
||||
|
||||
@@ -50,6 +50,8 @@ CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE
|
||||
ERROR HY000: Can't create table 'test.t2' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Create table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary close to FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB.
|
||||
Error 1005 Can't create table 'test.t2' (errno: 150)
|
||||
CREATE TABLE t2 (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
@@ -62,6 +64,7 @@ ALTER TABLE t2 ADD CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary close to FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE.
|
||||
Error 1005 Can't create table '#sql-temporary' (errno: 150)
|
||||
drop table t2;
|
||||
drop table t1;
|
||||
|
||||
@@ -21,9 +21,110 @@ CREATE TABLE t2 (
|
||||
a int(11) NOT NULL,
|
||||
b int(11) NOT NULL,
|
||||
c int not null,
|
||||
CONSTRAINT mytest FOREIGN KEY (c) REFERENCES t1(id),
|
||||
CONSTRAINT test FOREIGN KEY (b) REFERENCES t2 (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
show warnings;
|
||||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# MDEV-6697: Improve foreign keys warnings/errors
|
||||
#
|
||||
|
||||
#
|
||||
# No index for referenced columns
|
||||
#
|
||||
create table t1(a int) engine=innodb;
|
||||
--error 1005
|
||||
create table t2(a int, constraint a foreign key a (a) references t1(a)) engine=innodb;
|
||||
show warnings;
|
||||
drop table t1;
|
||||
|
||||
create table t1(a int not null primary key, b int) engine=innodb;
|
||||
--error 1005
|
||||
create table t2(a int, b int, constraint a foreign key a (a) references t1(a),
|
||||
constraint a foreign key a (a) references t1(b)) engine=innodb;
|
||||
show warnings;
|
||||
create table t2(a int, b int, constraint a foreign key a (a) references t1(a)) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
alter table t2 add constraint b foreign key (b) references t2(b);
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
drop table t2, t1;
|
||||
|
||||
#
|
||||
# Referenced table does not exists
|
||||
#
|
||||
|
||||
create table t1 (f1 integer primary key) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
alter table t1 add constraint c1 foreign key (f1) references t11(f1);
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Foreign key on temporal tables
|
||||
#
|
||||
|
||||
create temporary table t1(a int not null primary key, b int, key(b)) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
alter table t1 add foreign key(b) references t1(a);
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Column numbers do not match
|
||||
#
|
||||
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
alter table t1 add foreign key(a,b) references t1(a);
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
drop table t1;
|
||||
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
alter table t1 add foreign key(a) references t1(a,b);
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# ON UPDATE/DELETE SET NULL on NOT NULL column
|
||||
#
|
||||
create table t1 (f1 integer not null primary key) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update set null;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Incorrect types
|
||||
#
|
||||
create table t1 (id int not null primary key, f1 int, f2 int, key(f1)) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
--error 1005
|
||||
create table t2(a char(20), key(a), foreign key(a) references t1(f1)) engine=innodb;
|
||||
--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
|
||||
show warnings;
|
||||
drop table t1;
|
||||
|
||||
Reference in New Issue
Block a user