diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2020-06-29 20:57:20 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2020-08-24 15:56:35 +0300 |
commit | 18dc5580d863054fc1a819a075b547cdbd38f50e (patch) | |
tree | b47baf11eeb008ed3238d164a948ded984fa8482 | |
parent | 6ce3b4758d6ac5f89b25273ec9b7e251e837c26f (diff) | |
download | mariadb-git-bb-10.5-midenok-MDEV-16417.tar.gz |
MDEV-21052 InnoDB foreign key refactoring for TABLE_SHARE::foreign_keysbb-10.5-midenok-MDEV-16417
Refactor dict_load_foreigns() for synchronising TABLE_SHARE foreign
data with dict_table_t cache.
Remove a number of routines working with SYS_FOREIGNS and
SYS_FOREIGN_COLS. innobase_update_foreign_try() is now used solely for
ER_FK_INCORRECT_OPTION check.
Prelock parent tables as well as child tables. This is done for the
case when parent table doesn't know about its children when they
created before parent with foreign_key_checks=0. Opening the parent
table initiates fk_resolve_referenced_keys() which updates its
referenced_keys. Due to CREATE TABLE doesn't not know about "illegal"
children it can not check for foreign consistency. F.ex. this would
succeed:
set foreign_key_checks= 0;
create table child (fk int references parent (id)) engine=innodb;
set foreign_key_checks= 1;
create table parent (id bigint primary key) engine=innodb;
In the above case dict_load_foreigns() deduces which tables are
unknown to opened parent (tables_missing) and reloads their foreign
data via recursion. Infinite recursion is not possible via test case:
a table cannot be "parent after child" and "child before parent"
simultaneously. Though infinite recursion is possible via malicously
crafted FRM file, there is no protection from that at InnoDB level but
there is protection at SQL level: thd->fk_circular_check.
Later though it would not allow DML on child as well as on parent (see
innodb.foreign_key MDEV-10083). So this is pretty acceptable:
foreign_key_checks is unnormal setting, checking parent on CREATE
TABLE would impose all frms scanning which is not acceptable.
ha_innobase::open() then synchronizes these referenced_keys with its
referenced_set cache by calling dict_load_foreigns().
Disable self-references on same column. The Bug 12902967 restricted
them on some condition of "same column/index" (see
innodb_bug12902967.test), though such self-references were not
completely disabled (see other self-ref cases changed in this
patch). It is not clear why they worked if they are "self-refs on same
column/index".
94 files changed, 1148 insertions, 3917 deletions
diff --git a/mysql-test/include/have_innodb.combinations b/mysql-test/include/have_innodb.combinations index f1131c448f3..7282d848e9f 100644 --- a/mysql-test/include/have_innodb.combinations +++ b/mysql-test/include/have_innodb.combinations @@ -12,8 +12,6 @@ innodb-buffer-page innodb-buffer-page-lru innodb-sys-columns innodb-sys-fields -innodb-sys-foreign -innodb-sys-foreign-cols innodb-sys-indexes innodb-sys-tables innodb-sys-virtual @@ -32,8 +30,6 @@ innodb-buffer-page innodb-buffer-page-lru innodb-sys-columns innodb-sys-fields -innodb-sys-foreign -innodb-sys-foreign-cols innodb-sys-indexes innodb-sys-tables innodb-sys-virtual diff --git a/mysql-test/main/create.result b/mysql-test/main/create.result index 802c41af05d..b827a8e2adf 100644 --- a/mysql-test/main/create.result +++ b/mysql-test/main/create.result @@ -959,7 +959,7 @@ drop table if exists t1,t2; create table t1(a int not null, b int not null, primary key (a, b)); create table t2(a int not null, b int not null, c int not null, primary key (a), foreign key fk_bug26104 (b,c) references t1(a)); -ERROR 42000: Incorrect foreign key definition for 'fk_bug26104': Key reference and table reference don't match +ERROR 42000: Incorrect foreign key definition for 'fk_bug26104' drop table t1; create table t1(f1 int,f2 int); insert into t1 value(1,1),(1,2),(1,3),(2,1),(2,2),(2,3); diff --git a/mysql-test/main/foreign_key.result b/mysql-test/main/foreign_key.result index f0c6ca9eddd..3f915f82ae5 100644 --- a/mysql-test/main/foreign_key.result +++ b/mysql-test/main/foreign_key.result @@ -132,6 +132,34 @@ create table t1 (id int primary key); create table t2 (id int references t1(id)) select id from t1; flush tables; drop table t2, t1; +create database D; +create table D.T1(id int primary key); +create table t2(id int primary key, f1 int references D.T1(id)); +select * from D.T1; +id +drop table t2; +flush tables; +drop table D.T1; +drop database D; +# Check duplicate id +create or replace table t1 (id int primary key) engine innodb; +create or replace table t2 (id2 int, +constraint c foreign key (id2) references t1 (id), +constraint c foreign key (id2) references t1 (id)); +ERROR HY000: Duplicate FOREIGN KEY constraint name 'c' +create or replace table t2 (id2 int, constraint c foreign key (id2) references t1 (id)); +alter table t2 add constraint c foreign key (id2) references t1 (id); +ERROR HY000: Duplicate FOREIGN KEY constraint name 'c' +create or replace table t3 (id2 int, constraint c foreign key (id2) references t1 (id)); +ERROR HY000: Duplicate FOREIGN KEY constraint name 'c' +create or replace table t3 (id2 int, constraint C foreign key (id2) references t1 (id)); +create or replace table t3 (id2 int); +alter table t2 add constraint c foreign key (id2) references t1 (id); +ERROR HY000: Duplicate FOREIGN KEY constraint name 'c' +alter table t2 add constraint fk_t3 foreign key (id2) references t1 (id); +alter table t3 add foreign key (id2) references t1 (id); +ERROR HY000: Duplicate FOREIGN KEY constraint name 'fk_t3' +drop tables t3, t2, t1; # Check rename column, lock tables create or replace table t1 (id int primary key); create or replace table t2 (id int primary key); @@ -312,6 +340,13 @@ ERROR HY000: Cannot drop index 'fk': needed in a foreign key constraint alter table t2 drop foreign key fk; drop tables t1, t2; # Check self-references +create or replace table t1 (f1 integer primary key references t1(f1)); +ERROR 42000: Incorrect foreign key definition for 'f1' +create or replace table t1 (f1 integer primary key, foreign key (f1) references t1(f1)); +ERROR 42000: Incorrect foreign key definition for 'f1' +create or replace table t1 (f1 integer primary key); +alter table t1 add constraint c1 foreign key (f1) references t1(f1); +ERROR 42000: Incorrect foreign key definition for 'c1' create or replace table t1 (id int primary key, id2 int references t1 (id)); flush tables t1; show create table t1; diff --git a/mysql-test/main/foreign_key.test b/mysql-test/main/foreign_key.test index 64e00b402d6..437d93e6bdb 100644 --- a/mysql-test/main/foreign_key.test +++ b/mysql-test/main/foreign_key.test @@ -169,6 +169,36 @@ create table t2 (id int references t1(id)) select id from t1; flush tables; drop table t2, t1; +create database D; +create table D.T1(id int primary key); +create table t2(id int primary key, f1 int references D.T1(id)); +select * from D.T1; +drop table t2; +flush tables; +drop table D.T1; +drop database D; + +--echo # Check duplicate id +create or replace table t1 (id int primary key) engine innodb; +--error ER_DUP_CONSTRAINT_NAME +create or replace table t2 (id2 int, + constraint c foreign key (id2) references t1 (id), + constraint c foreign key (id2) references t1 (id)); + +create or replace table t2 (id2 int, constraint c foreign key (id2) references t1 (id)); +--error ER_DUP_CONSTRAINT_NAME +alter table t2 add constraint c foreign key (id2) references t1 (id); +--error ER_DUP_CONSTRAINT_NAME +create or replace table t3 (id2 int, constraint c foreign key (id2) references t1 (id)); +create or replace table t3 (id2 int, constraint C foreign key (id2) references t1 (id)); +create or replace table t3 (id2 int); +--error ER_DUP_CONSTRAINT_NAME +alter table t2 add constraint c foreign key (id2) references t1 (id); +alter table t2 add constraint fk_t3 foreign key (id2) references t1 (id); +--error ER_DUP_CONSTRAINT_NAME +alter table t3 add foreign key (id2) references t1 (id); +drop tables t3, t2, t1; + --echo # Check rename column, lock tables create or replace table t1 (id int primary key); create or replace table t2 (id int primary key); @@ -306,6 +336,14 @@ alter table t2 drop foreign key fk; drop tables t1, t2; --echo # Check self-references +--error ER_WRONG_FK_DEF +create or replace table t1 (f1 integer primary key references t1(f1)); +--error ER_WRONG_FK_DEF +create or replace table t1 (f1 integer primary key, foreign key (f1) references t1(f1)); +create or replace table t1 (f1 integer primary key); +--error ER_WRONG_FK_DEF +alter table t1 add constraint c1 foreign key (f1) references t1(f1); + create or replace table t1 (id int primary key, id2 int references t1 (id)); flush tables t1; show create table t1; diff --git a/mysql-test/main/information_schema_all_engines-master.opt b/mysql-test/main/information_schema_all_engines-master.opt index 7ba5aa5b8b3..4c67a5559f5 100644 --- a/mysql-test/main/information_schema_all_engines-master.opt +++ b/mysql-test/main/information_schema_all_engines-master.opt @@ -9,8 +9,6 @@ --loose-innodb-lock-waits --loose-innodb-sys-columns --loose-innodb-sys-fields ---loose-innodb-sys-foreign ---loose-innodb-sys-foreign-cols --loose-innodb-sys-tables --loose-innodb-sys-tablestats --loose-innodb-mutexes diff --git a/mysql-test/main/information_schema_all_engines.result b/mysql-test/main/information_schema_all_engines.result index 46a50716c08..50b4956f547 100644 --- a/mysql-test/main/information_schema_all_engines.result +++ b/mysql-test/main/information_schema_all_engines.result @@ -32,8 +32,6 @@ INNODB_METRICS INNODB_MUTEXES INNODB_SYS_COLUMNS INNODB_SYS_FIELDS -INNODB_SYS_FOREIGN -INNODB_SYS_FOREIGN_COLS INNODB_SYS_INDEXES INNODB_SYS_TABLES INNODB_SYS_TABLESTATS @@ -112,8 +110,6 @@ INNODB_METRICS NAME INNODB_MUTEXES NAME INNODB_SYS_COLUMNS TABLE_ID INNODB_SYS_FIELDS INDEX_ID -INNODB_SYS_FOREIGN ID -INNODB_SYS_FOREIGN_COLS ID INNODB_SYS_INDEXES INDEX_ID INNODB_SYS_TABLES TABLE_ID INNODB_SYS_TABLESTATS TABLE_ID @@ -192,8 +188,6 @@ INNODB_METRICS NAME INNODB_MUTEXES NAME INNODB_SYS_COLUMNS TABLE_ID INNODB_SYS_FIELDS INDEX_ID -INNODB_SYS_FOREIGN ID -INNODB_SYS_FOREIGN_COLS ID INNODB_SYS_INDEXES INDEX_ID INNODB_SYS_TABLES TABLE_ID INNODB_SYS_TABLESTATS TABLE_ID @@ -277,8 +271,6 @@ INNODB_METRICS information_schema.INNODB_METRICS 1 INNODB_MUTEXES information_schema.INNODB_MUTEXES 1 INNODB_SYS_COLUMNS information_schema.INNODB_SYS_COLUMNS 1 INNODB_SYS_FIELDS information_schema.INNODB_SYS_FIELDS 1 -INNODB_SYS_FOREIGN information_schema.INNODB_SYS_FOREIGN 1 -INNODB_SYS_FOREIGN_COLS information_schema.INNODB_SYS_FOREIGN_COLS 1 INNODB_SYS_INDEXES information_schema.INNODB_SYS_INDEXES 1 INNODB_SYS_TABLES information_schema.INNODB_SYS_TABLES 1 INNODB_SYS_TABLESTATS information_schema.INNODB_SYS_TABLESTATS 1 @@ -347,8 +339,6 @@ Database: information_schema | INNODB_MUTEXES | | INNODB_SYS_COLUMNS | | INNODB_SYS_FIELDS | -| INNODB_SYS_FOREIGN | -| INNODB_SYS_FOREIGN_COLS | | INNODB_SYS_INDEXES | | INNODB_SYS_TABLES | | INNODB_SYS_TABLESTATS | @@ -417,8 +407,6 @@ Database: INFORMATION_SCHEMA | INNODB_MUTEXES | | INNODB_SYS_COLUMNS | | INNODB_SYS_FIELDS | -| INNODB_SYS_FOREIGN | -| INNODB_SYS_FOREIGN_COLS | | INNODB_SYS_INDEXES | | INNODB_SYS_TABLES | | INNODB_SYS_TABLESTATS | @@ -459,5 +447,5 @@ Wildcard: inf_rmation_schema | information_schema | SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 65 +information_schema 63 mysql 31 diff --git a/mysql-test/suite/innodb/include/innodb_dict.inc b/mysql-test/suite/innodb/include/innodb_dict.inc index 1e05181272d..fa0c03a835b 100644 --- a/mysql-test/suite/innodb/include/innodb_dict.inc +++ b/mysql-test/suite/innodb/include/innodb_dict.inc @@ -5,5 +5,3 @@ INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; diff --git a/mysql-test/suite/innodb/r/add_constraint.result b/mysql-test/suite/innodb/r/add_constraint.result deleted file mode 100644 index 9d894e530c3..00000000000 --- a/mysql-test/suite/innodb/r/add_constraint.result +++ /dev/null @@ -1,13 +0,0 @@ -# -# Bug #20762798 FK DDL: CRASH IN DICT_FOREIGN_REMOVE_FROM_CACHE -# -create table t1(a int, b int, key(a),key(b))engine=innodb; -create table t2(a int, b int, key(a),key(b))engine=innodb; -alter table t2 add constraint b foreign key (b) references t1(a); -alter table t1 add constraint b1 foreign key (b) references t2(a); -alter table t2 add constraint b1 foreign key (b) references t1(a); -ERROR HY000: Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update") -alter table t2 drop foreign key b; -alter table t1 drop foreign key b1; -drop table t2; -drop table t1; diff --git a/mysql-test/suite/innodb/r/alter_foreign_crash.result b/mysql-test/suite/innodb/r/alter_foreign_crash.result index 824b4b091a7..7c20ba83c84 100644 --- a/mysql-test/suite/innodb/r/alter_foreign_crash.result +++ b/mysql-test/suite/innodb/r/alter_foreign_crash.result @@ -23,6 +23,5 @@ parent alter table parent row_format=dynamic; Warnings: Warning 1105 Reference hint to non-existent table `bug.child` skipped -Warning 1088 failed to load FOREIGN KEY constraints drop table parent; drop database bug; diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index d3b2acb4509..8460709e510 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -6,7 +6,7 @@ create table t1 (f1 int primary key) engine=InnoDB; create table t2 (f1 int primary key, constraint c1 foreign key (f1) references t1(f1), constraint c1 foreign key (f1) references t1(f1)) engine=InnoDB; -ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Duplicate FOREIGN KEY constraint name 'c1' create table t2 (f1 int primary key, constraint c1 foreign key (f1) references t1(f1)) engine=innodb; alter table t2 add constraint c1 foreign key (f1) references t1(f1); @@ -180,19 +180,19 @@ CREATE DATABASE best default character set latin1; CREATE TABLE t3 (a INT PRIMARY KEY, CONSTRAINT t2_ibfk_1 FOREIGN KEY (a) REFERENCES t1(a)) ENGINE=InnoDB; CREATE TABLE best.t2 (a INT PRIMARY KEY, b TEXT, FULLTEXT INDEX(b), -FOREIGN KEY t2_ibfk_1 (a) REFERENCES test.t1(a)) ENGINE=InnoDB; +FOREIGN KEY (a) REFERENCES test.t1(a)) ENGINE=InnoDB; RENAME TABLE best.t2 TO test.t2; -ERROR 42S01: Table 't2' already exists -SHOW CREATE TABLE best.t2; +SHOW CREATE TABLE test.t2; Table Create Table t2 CREATE TABLE `t2` ( `a` int(11) NOT NULL, `b` text DEFAULT NULL, PRIMARY KEY (`a`), FULLTEXT KEY `b` (`b`), - CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`) + CONSTRAINT `fk_t2` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP DATABASE best; +DROP TABLE t2; # # MDEV-17541 KILL QUERY during lock wait in FOREIGN KEY check hangs # @@ -215,8 +215,8 @@ DROP TABLE t3,t1; # MDEV-18222 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N # or ASAN heap-use-after-free in dict_foreign_remove_from_cache upon CHANGE COLUMN # -CREATE TABLE t1 (a INT, UNIQUE(a), KEY(a)) ENGINE=InnoDB; -ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a); +CREATE TABLE t1 (a INT, UNIQUE(a), KEY(a), c INT) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (c) REFERENCES t1 (a); SET SESSION FOREIGN_KEY_CHECKS = OFF; ALTER TABLE t1 CHANGE COLUMN a a TIME NOT NULL; ALTER TABLE t1 ADD pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY; @@ -237,6 +237,8 @@ SET SESSION FOREIGN_KEY_CHECKS = OFF; ALTER TABLE t1 ADD FOREIGN KEY (f) REFERENCES non_existing_table (x); SET SESSION FOREIGN_KEY_CHECKS = ON; ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f); +Warnings: +Warning 1088 failed to load FOREIGN KEY constraints ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); DROP TABLE t1; CREATE TABLE t1 (f VARCHAR(256), FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY) @@ -362,14 +364,14 @@ update t1 set data=10 where pk+1>10; show status like '%opened_tab%'; Variable_name Value Opened_table_definitions 5 -Opened_tables 4 +Opened_tables 5 flush tables; flush status; update t2 set t1_pk=11 where t1_pk+1>10; show status like '%opened_tab%'; Variable_name Value -Opened_table_definitions 4 -Opened_tables 4 +Opened_table_definitions 5 +Opened_tables 5 flush tables; flush status; lock tables t1 write; @@ -396,7 +398,7 @@ foo() show status like '%opened_tab%'; Variable_name Value Opened_table_definitions 6 -Opened_tables 5 +Opened_tables 6 drop function foo; drop table t2, t1; # Start of 10.2 tests @@ -728,7 +730,9 @@ t2 CREATE TABLE `t2` ( `f1` int(11) NOT NULL, `f2` int(11) NOT NULL, `f3` int(11) NOT NULL, - PRIMARY KEY (`f3`) + PRIMARY KEY (`f3`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f2`) ON DELETE CASCADE, + CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1 CREATE TABLE t2 (f1 INT NOT NULL)ENGINE=InnoDB; ERROR 42S01: Table 't2' already exists @@ -736,7 +740,7 @@ DROP TABLE t2, t1; # End of 10.2 tests CREATE TABLE t1 (a GEOMETRY, INDEX(a(8)), FOREIGN KEY (a) REFERENCES x (xx)) ENGINE=InnoDB; -ERROR 42S02: Table 'test.x' doesn't exist +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") # End of 10.4 tests # # MDEV-20729 Fix REFERENCES constraint in column definition @@ -809,3 +813,97 @@ create or replace table t2 (pk int primary key, a varchar(4096) unique, foreign ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") drop table t1; # End of 10.5 tests +# +# Bug #20762798 FK DDL: CRASH IN DICT_FOREIGN_REMOVE_FROM_CACHE +# +create table t1(a int, b int, key(a),key(b))engine=innodb; +create table t2(a int, b int, key(a),key(b))engine=innodb; +alter table t2 add constraint b foreign key (b) references t1(a); +alter table t1 add constraint b1 foreign key (b) references t2(a); +alter table t2 add constraint b1 foreign key (b) references t1(a); +alter table t2 drop foreign key b; +alter table t1 drop foreign key b1; +drop table t2; +drop table t1; +set global innodb_file_per_table = 1; +drop table if exists b; +drop database if exists bug_fk; +create database bug_fk; +use bug_fk; +CREATE TABLE b ( +b int unsigned NOT NULL, +d1 datetime NOT NULL, +PRIMARY KEY (b,d1) +) ENGINE=InnoDB; +CREATE TABLE c ( +b int unsigned NOT NULL, +d1 datetime NOT NULL, +d2 datetime NOT NULL, +PRIMARY KEY (b,d1), +CONSTRAINT b_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; +insert into b values (1, '1980-01-01 00:00:00'); +insert into c values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:00'); +delete from b; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`bug_fk`.`c`, CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`)) +update c set b= 2; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`bug_fk`.`c`, CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`)) +show warnings; +Level Code Message +Error 1452 Cannot add or update a child row: a foreign key constraint fails (`bug_fk`.`c`, CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`)) +set foreign_key_checks = 0; +DROP TABLE IF EXISTS b; +show create table c; +Table Create Table +c CREATE TABLE `c` ( + `b` int(10) unsigned NOT NULL, + `d1` datetime NOT NULL, + `d2` datetime NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +CREATE TABLE b ( +b bigint unsigned NOT NULL, +d1 date NOT NULL, +PRIMARY KEY (b,d1) +) ENGINE=InnoDB; +show warnings; +Level Code Message +DROP TABLE IF EXISTS d; +Warnings: +Note 1051 Unknown table 'bug_fk.d' +CREATE TABLE d ( +b bigint unsigned NOT NULL, +d1 date NOT NULL, +PRIMARY KEY (b,d1), +CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; +show warnings; +Level Code Message +set foreign_key_checks = 1; +show create table c; +Table Create Table +c CREATE TABLE `c` ( + `b` int(10) unsigned NOT NULL, + `d1` datetime NOT NULL, + `d2` datetime NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table d; +Table Create Table +d CREATE TABLE `d` ( + `b` bigint(20) unsigned NOT NULL, + `d1` date NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `bd_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +update c set b= 2; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`bug_fk`.`c`, CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`)) +insert into c values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:00'); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`bug_fk`.`c`, CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`)) +insert into b values (2, '1980-01-01 00:00:00'); +insert into c values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:00'); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`bug_fk`.`c`, CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`)) +insert into d values (2, '1980-01-01 00:00:00'); +drop database bug_fk; diff --git a/mysql-test/suite/innodb/r/information_schema_grants.result b/mysql-test/suite/innodb/r/information_schema_grants.result index 622faa2920a..6da95db244c 100644 --- a/mysql-test/suite/innodb/r/information_schema_grants.result +++ b/mysql-test/suite/innodb/r/information_schema_grants.result @@ -48,10 +48,6 @@ create sql security invoker view i_sys_datafiles as select * from information_sc create sql security definer view d_sys_datafiles as select * from information_schema.innodb_sys_datafiles; create sql security invoker view i_sys_fields as select * from information_schema.innodb_sys_fields; create sql security definer view d_sys_fields as select * from information_schema.innodb_sys_fields; -create sql security invoker view i_sys_foreign as select * from information_schema.innodb_sys_foreign; -create sql security definer view d_sys_foreign as select * from information_schema.innodb_sys_foreign; -create sql security invoker view i_sys_foreign_cols as select * from information_schema.innodb_sys_foreign_cols; -create sql security definer view d_sys_foreign_cols as select * from information_schema.innodb_sys_foreign_cols; create sql security invoker view i_sys_indexes as select * from information_schema.innodb_sys_indexes; create sql security definer view d_sys_indexes as select * from information_schema.innodb_sys_indexes; create sql security invoker view i_sys_semaphore_waits as select * from information_schema.innodb_sys_semaphore_waits; @@ -219,20 +215,6 @@ ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) select count(*) > -1 from d_sys_fields; count(*) > -1 1 -select count(*) > -1 from information_schema.innodb_sys_foreign; -ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation -select count(*) > -1 from i_sys_foreign; -ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation -select count(*) > -1 from d_sys_foreign; -count(*) > -1 -1 -select count(*) > -1 from information_schema.innodb_sys_foreign_cols; -ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation -select count(*) > -1 from i_sys_foreign_cols; -ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation -select count(*) > -1 from d_sys_foreign_cols; -count(*) > -1 -1 select count(*) > -1 from information_schema.innodb_sys_indexes; ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation select count(*) > -1 from i_sys_indexes; diff --git a/mysql-test/suite/innodb/r/innodb-alter-debug.result b/mysql-test/suite/innodb/r/innodb-alter-debug.result index 4644c124a45..a1ba9cb4876 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-debug.result +++ b/mysql-test/suite/innodb/r/innodb-alter-debug.result @@ -1,30 +1,3 @@ -SET NAMES utf8; -CREATE TABLE ① ( -c1 INT PRIMARY KEY, c2 INT DEFAULT 1, ct TEXT, INDEX(c2)) -ENGINE = InnoDB; -CREATE TABLE t1ć (c1 INT PRIMARY KEY, c2 INT, INDEX(c2), -CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES ①(c2)) -ENGINE=InnoDB; -INSERT INTO ① SET c1 = 1; -SET @saved_debug_dbug = @@SESSION.debug_dbug; -SET DEBUG_DBUG = '+d,ib_drop_foreign_error'; -ALTER TABLE t1ć DROP FOREIGN KEY t1c2, RENAME TO ②; -ERROR HY000: The table 't1ć' is full -SET DEBUG_DBUG = @saved_debug_dbug; -SET DEBUG_DBUG = '+d,ib_rename_column_error'; -ALTER TABLE ① CHANGE c2 š INT; -ERROR HY000: The table '①' is full -SET DEBUG_DBUG = @saved_debug_dbug; -SHOW CREATE TABLE t1ć; -Table Create Table -t1ć CREATE TABLE `t1ć` ( - `c1` int(11) NOT NULL, - `c2` int(11) DEFAULT NULL, - PRIMARY KEY (`c1`), - KEY `c2` (`c2`), - CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `①` (`c2`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -DROP TABLE t1ć, ①; # # Bug #21364096 THE BOGUS DUPLICATE KEY ERROR IN ONLINE DDL # WITH INCORRECT KEY NAME diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result index 520d4430173..984f66b108d 100644 --- a/mysql-test/suite/innodb/r/innodb-alter.result +++ b/mysql-test/suite/innodb/r/innodb-alter.result @@ -13,14 +13,6 @@ CREATE TABLE t1c (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX(c2), INDEX(c3), CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES t1(c2), CONSTRAINT t1c3 FOREIGN KEY (c3) REFERENCES t1p(c2)) ENGINE=InnoDB; -CREATE TABLE sys_foreign SELECT i.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i -WHERE FOR_NAME LIKE 'test/t%'; -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c2 0 -test/t1c3 c3 c2 0 SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; @@ -33,11 +25,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c2 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c2 0 -test/t1c3 c3 c2 0 SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -69,11 +56,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c2 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c2 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE c2 c2 INT AFTER c1; ALTER TABLE t1 CHANGE c1 c1 INT FIRST; SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN @@ -88,11 +70,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c2 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c2 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE C2 c3 INT; SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i @@ -106,11 +83,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE c3 C INT; SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i @@ -124,17 +96,7 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 C -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 C 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE C Cöŀumň_TWO INT; -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 Cöŀumň_TWO 0 -test/t1c3 c3 c2 0 SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; @@ -147,11 +109,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 Cöŀumň_TWO -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 Cöŀumň_TWO 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE cöĿǖmň_two c3 INT; ERROR 42S22: Unknown column 'cöĿǖmň_two' in 't1' ALTER TABLE t1 CHANGE cÖĿUMŇ_two c3 INT, RENAME TO t3; @@ -246,11 +203,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 DROP INDEX c2; ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint ALTER TABLE t1 DROP INDEX c4; @@ -304,11 +256,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 -test/t1c3 c3 c2 0 CREATE TABLE t1p (c1 INT PRIMARY KEY, c2 INT, INDEX(c2)) ENGINE=InnoDB; ALTER TABLE t1c DROP INDEX C2, DROP INDEX C3; ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint @@ -340,11 +287,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 -test/t1c3 c3 c2 0 ALTER TABLE t1c DROP FOREIGN KEY t1C3; SHOW CREATE TABLE t1c; Table Create Table @@ -368,10 +310,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 ALTER TABLE t1c DROP INDEX c2, DROP FOREIGN KEY t1C2; SHOW CREATE TABLE t1c; Table Create Table @@ -393,9 +331,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS ALTER TABLE t1 DROP INDEX c2, CHANGE c3 c2 INT; SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i @@ -408,9 +343,6 @@ SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS CREATE TABLE t1o LIKE t1; ALTER TABLE t1 ADD FULLTEXT INDEX (ct), CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt, @@ -426,9 +358,6 @@ NAME POS MTYPE PRTYPE LEN SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS SHOW CREATE TABLE tt; Table Create Table tt CREATE TABLE `tt` ( @@ -623,13 +552,11 @@ t1o CREATE TABLE `t1o` ( `cu` text DEFAULT NULL, PRIMARY KEY (`foo_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign; +DROP TABLE t1c, t1p, sys_tables, sys_indexes; CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1o'; CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; -CREATE TABLE sys_foreign SELECT i.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i WHERE FOR_NAME='test/t1o'; SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; @@ -642,9 +569,6 @@ SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 foo_id -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(FTS_DOC_ID), ADD FULLTEXT INDEX(ct), CHANGE foo_id FTS_DOC_ID BIGINT UNSIGNED NOT NULL; @@ -670,10 +594,7 @@ NAME POS NAME PRIMARY 0 FTS_DOC_ID FTS_DOC_ID_INDEX 0 FTS_DOC_ID ct 0 ct -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign; +DROP TABLE tt, t1o, sys_tables, sys_indexes; CREATE TABLE t (t TEXT, FULLTEXT(t)) ENGINE=InnoDB; DROP INDEX t ON t; SELECT SUBSTRING(name, LOCATE('_', name) - 3, 5) AS prefix, name @@ -766,11 +687,6 @@ INFORMATION_SCHEMA.INNODB_SYS_TABLES T ON I.TABLE_ID=T.TABLE_ID WHERE T.NAME='test/t1' AND I.NAME='PRIMARY'; NAME c5 -SELECT C.REF_COL_NAME, C.FOR_COL_NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS C INNER JOIN -INFORMATION_SCHEMA.INNODB_SYS_FOREIGN F ON C.ID=F.ID -WHERE F.FOR_NAME='test/t2'; -REF_COL_NAME FOR_COL_NAME -c5 c6 DROP TABLE t2, t1; # virtual columns case too CREATE TABLE t1 (a INT, b INT GENERATED ALWAYS AS (a) VIRTUAL) ENGINE = InnoDB; diff --git a/mysql-test/suite/innodb/r/innodb-fk-virtual.result b/mysql-test/suite/innodb/r/innodb-fk-virtual.result index cdc4189e623..c71e85b9dfe 100644 --- a/mysql-test/suite/innodb/r/innodb-fk-virtual.result +++ b/mysql-test/suite/innodb/r/innodb-fk-virtual.result @@ -74,7 +74,7 @@ select * from b; cola v_cola p_cola c_cola 10 2 2 12 insert into b(cola, v_cola, p_cola) values (10,1,1); -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `p_cola_fk` FOREIGN KEY (`p_cola`) REFERENCES `a` (`p_cola`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `p_cola_fk` FOREIGN KEY (`p_cola`) REFERENCES `a` (`p_cola`) ON DELETE NO ACTION ON UPDATE NO ACTION) delete from a; ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `c_cola_fk` FOREIGN KEY (`c_cola`) REFERENCES `a` (`cola`)) select * from a; diff --git a/mysql-test/suite/innodb/r/innodb-fk-warnings.result b/mysql-test/suite/innodb/r/innodb-fk-warnings.result index 4f1cea06bd0..cf1c7822a52 100644 --- a/mysql-test/suite/innodb/r/innodb-fk-warnings.result +++ b/mysql-test/suite/innodb/r/innodb-fk-warnings.result @@ -1,25 +1,3 @@ -CREATE TABLE t1 ( -id int(11) NOT NULL PRIMARY KEY, -a int(11) NOT NULL, -b int(11) NOT NULL, -c int not null, -CONSTRAINT test FOREIGN KEY (b) REFERENCES t1 (id) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; -CREATE TABLE t2 ( -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 "Duplicate key on write or update") -show warnings; -Level Code Message -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 "Duplicate key on write or update") -Warning 1022 Can't write; duplicate key in table 't2' -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 "Foreign key constraint is incorrectly formed") @@ -41,19 +19,16 @@ 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 "Foreign key constraint is incorrectly formed") +ERROR HY000: Duplicate FOREIGN KEY constraint name 'a' show warnings; Level Code Message -Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") -Warning 1215 Cannot add foreign key constraint for `t2` +Error 1826 Duplicate FOREIGN KEY constraint name 'a' 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 `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR 42000: Incorrect foreign key definition for 'b' show warnings; Level Code Message -Warning 150 Alter table `test`.`t2` with foreign key `b` constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. -Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") -Warning 1215 Cannot add foreign key constraint for `t2` +Error 1239 Incorrect foreign key definition for 'b' 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); @@ -90,26 +65,24 @@ Warning 1215 Cannot add foreign key constraint for `t1` 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 42000: Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match +ERROR 42000: Incorrect foreign key definition for 'foreign key without name' show warnings; Level Code Message -Error 1239 Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match +Error 1239 Incorrect foreign key definition for 'foreign key without name' 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 42000: Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match +ERROR 42000: Incorrect foreign key definition for 'foreign key without name' show warnings; Level Code Message -Error 1239 Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match +Error 1239 Incorrect foreign key definition for 'foreign key without name' 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 `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR 42000: Incorrect foreign key definition for 'c1' show warnings; Level Code Message -Warning 150 Alter table `test`.`t1` with foreign key `c1` constraint failed. You have defined a SET NULL condition but column 'f1' is defined as NOT NULL. -Error 1005 Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") -Warning 1215 Cannot add foreign key constraint for `t1` +Error 1239 Incorrect foreign key definition for 'c1' 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 "Foreign key constraint is incorrectly formed") show warnings; diff --git a/mysql-test/suite/innodb/r/innodb-fk.result b/mysql-test/suite/innodb/r/innodb-fk.result index 8408e54fe0a..0ce40383ce5 100644 --- a/mysql-test/suite/innodb/r/innodb-fk.result +++ b/mysql-test/suite/innodb/r/innodb-fk.result @@ -30,7 +30,7 @@ drop table t1; create table t1 (f1 int primary key) engine=innodb; # restart delete from t1 where f1 = 29; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`fk_29`, CONSTRAINT `pc29` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`fk_29`, CONSTRAINT `pc29` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON DELETE NO ACTION ON UPDATE NO ACTION) select * from fk_29; f1 29 @@ -95,7 +95,7 @@ CREATE TABLE `kg_test2`.`person2` ( `Id` INT(11) NOT NULL AUTO_INCREMENT, `Name` VARCHAR(50) NOT NULL, PRIMARY KEY (`Id`), -CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) +CONSTRAINT `fk_person_group2` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8; show create table `kg_test2`.`person2`; Table Create Table @@ -103,7 +103,7 @@ person2 CREATE TABLE `person2` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(50) NOT NULL, PRIMARY KEY (`Id`), - CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) + CONSTRAINT `fk_person_group2` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 SHOW WARNINGS; Level Code Message diff --git a/mysql-test/suite/innodb/r/innodb-fkcheck.result b/mysql-test/suite/innodb/r/innodb-fkcheck.result deleted file mode 100644 index efa227e4035..00000000000 --- a/mysql-test/suite/innodb/r/innodb-fkcheck.result +++ /dev/null @@ -1,89 +0,0 @@ -set global innodb_file_per_table = 1; -drop table if exists b; -drop database if exists bug_fk; -create database bug_fk; -use bug_fk; -CREATE TABLE b ( -b int unsigned NOT NULL, -d1 datetime NOT NULL, -PRIMARY KEY (b,d1) -) ENGINE=InnoDB; -CREATE TABLE c ( -b int unsigned NOT NULL, -d1 datetime NOT NULL, -d2 datetime NOT NULL, -PRIMARY KEY (b,d1), -CONSTRAINT b_fk FOREIGN KEY (b) REFERENCES b (b) -) ENGINE=InnoDB; -show warnings; -Level Code Message -set foreign_key_checks = 0; -DROP TABLE IF EXISTS b; -show create table c; -Table Create Table -c CREATE TABLE `c` ( - `b` int(10) unsigned NOT NULL, - `d1` datetime NOT NULL, - `d2` datetime NOT NULL, - PRIMARY KEY (`b`,`d1`), - CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -CREATE TABLE b ( -b bigint unsigned NOT NULL, -d1 date NOT NULL, -PRIMARY KEY (b,d1) -) ENGINE=InnoDB; -ERROR HY000: Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed") -show warnings; -Level Code Message -Error 1005 Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed") -Warning 1215 Cannot add foreign key constraint for `b` -DROP TABLE IF EXISTS d; -Warnings: -Note 1051 Unknown table 'bug_fk.d' -CREATE TABLE d ( -b bigint unsigned NOT NULL, -d1 date NOT NULL, -PRIMARY KEY (b,d1), -CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b) -) ENGINE=InnoDB; -show warnings; -Level Code Message -set foreign_key_checks = 1; -show create table c; -Table Create Table -c CREATE TABLE `c` ( - `b` int(10) unsigned NOT NULL, - `d1` datetime NOT NULL, - `d2` datetime NOT NULL, - PRIMARY KEY (`b`,`d1`), - CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -show create table d; -Table Create Table -d CREATE TABLE `d` ( - `b` bigint(20) unsigned NOT NULL, - `d1` date NOT NULL, - PRIMARY KEY (`b`,`d1`), - CONSTRAINT `bd_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -CREATE TABLE b ( -b bigint unsigned NOT NULL, -d1 date NOT NULL, -PRIMARY KEY (b,d1) -) ENGINE=InnoDB; -ERROR HY000: Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed") -show warnings; -Level Code Message -Error 1005 Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed") -Warning 1215 Cannot add foreign key constraint for `b` -set foreign_key_checks=0; -drop table c; -drop table d; -create table b(id int) engine=innodb; -show warnings; -Level Code Message -b.frm -b.ibd -drop table if exists b; -drop database if exists bug_fk; diff --git a/mysql-test/suite/innodb/r/innodb-index-online-fk.result b/mysql-test/suite/innodb/r/innodb-index-online-fk.result index ecb17e3c7cc..c0288c7ea7f 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online-fk.result +++ b/mysql-test/suite/innodb/r/innodb-index-online-fk.result @@ -12,12 +12,6 @@ SET foreign_key_checks = 0; ALTER TABLE child ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a2 b 0 ALTER TABLE child ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; @@ -52,21 +46,6 @@ REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ADD INDEX idx1(a1,a ALGORITHM = INPLACE; ALTER TABLE child ADD CONSTRAINT fk_3 FOREIGN KEY (a1, a2) REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -test/fk_10 test/child test/parent 2 5 -test/fk_2 test/child test/parent 2 5 -test/fk_3 test/child test/parent 2 5 -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a2 b 0 -test/fk_10 a1 a 0 -test/fk_10 a2 b 1 -test/fk_2 a1 a 0 -test/fk_2 a2 b 1 -test/fk_3 a1 a 0 -test/fk_3 a2 b 1 SET foreign_key_checks = 1; INSERT INTO child VALUES(5,4); ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `fk_1` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE) @@ -96,24 +75,6 @@ ALTER TABLE child ADD CONSTRAINT fk_4 FOREIGN KEY (a1, a2) REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ALGORITHM = INPLACE; SET DEBUG_DBUG = @saved_debug_dbug; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -test/fk_10 test/child test/parent 2 5 -test/fk_2 test/child test/parent 2 5 -test/fk_3 test/child test/parent 2 5 -test/fk_4 test/child test/parent 2 5 -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a2 b 0 -test/fk_10 a1 a 0 -test/fk_10 a2 b 1 -test/fk_2 a1 a 0 -test/fk_2 a2 b 1 -test/fk_3 a1 a 0 -test/fk_3 a2 b 1 -test/fk_4 a1 a 0 -test/fk_4 a2 b 1 SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; name name test/child a1 @@ -121,8 +82,6 @@ test/child a2 SELECT NAME FROM information_schema.INNODB_SYS_TABLES; NAME SYS_DATAFILES -SYS_FOREIGN -SYS_FOREIGN_COLS SYS_TABLESPACES SYS_VIRTUAL mysql/innodb_index_stats @@ -148,24 +107,6 @@ SET DEBUG_DBUG = @saved_debug_dbug; SHOW ERRORS; Level Code Message Error 1821 Failed to add the foreign key constaint. Missing index for constraint 'fk_40' in the foreign table '#child' -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -test/fk_10 test/child test/parent 2 5 -test/fk_2 test/child test/parent 2 5 -test/fk_3 test/child test/parent 2 5 -test/fk_4 test/child test/parent 2 5 -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a2 b 0 -test/fk_10 a1 a 0 -test/fk_10 a2 b 1 -test/fk_2 a1 a 0 -test/fk_2 a2 b 1 -test/fk_3 a1 a 0 -test/fk_3 a2 b 1 -test/fk_4 a1 a 0 -test/fk_4 a2 b 1 SET DEBUG_DBUG = '+d,innodb_test_no_reference_idx'; ALTER TABLE child ADD CONSTRAINT fk_42 FOREIGN KEY (a1, a2) REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, @@ -181,33 +122,9 @@ REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ALGORITHM = INPLACE; ERROR HY000: Failed to add the foreign key constraint on table 'child'. Incorrect options in FOREIGN KEY constraint 'test/fk_42' SET DEBUG_DBUG = @saved_debug_dbug; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -test/fk_10 test/child test/parent 2 5 -test/fk_2 test/child test/parent 2 5 -test/fk_3 test/child test/parent 2 5 -test/fk_4 test/child test/parent 2 5 -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a2 b 0 -test/fk_10 a1 a 0 -test/fk_10 a2 b 1 -test/fk_2 a1 a 0 -test/fk_2 a2 b 1 -test/fk_3 a1 a 0 -test/fk_3 a2 b 1 -test/fk_4 a1 a 0 -test/fk_4 a2 b 1 -SET DEBUG_DBUG = '+d,innodb_test_cannot_add_fk_system'; -ALTER TABLE `#child` ADD CONSTRAINT fk_43 FOREIGN KEY (a1, a2) -REFERENCES `#parent`(a, b) ON DELETE CASCADE ON UPDATE CASCADE, -ALGORITHM = INPLACE; -ERROR HY000: Failed to add the foreign key constraint 'test/fk_43' to system tables -SET DEBUG_DBUG = @saved_debug_dbug; SHOW ERRORS; Level Code Message -Error 1823 Failed to add the foreign key constraint 'test/fk_43' to system tables +Error 1825 Failed to add the foreign key constraint on table 'child'. Incorrect options in FOREIGN KEY constraint 'test/fk_42' DROP TABLE `#child`; DROP TABLE `#parent`; SET foreign_key_checks = 0; @@ -216,29 +133,6 @@ ON DELETE SET NULL ON UPDATE CASCADE, ADD CONSTRAINT fk_6 FOREIGN KEY (a1, a2) REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ALGORITHM = INPLACE; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -test/fk_10 test/child test/parent 2 5 -test/fk_2 test/child test/parent 2 5 -test/fk_3 test/child test/parent 2 5 -test/fk_4 test/child test/parent 2 5 -test/fk_5 test/child test/parent 1 6 -test/fk_6 test/child test/parent 2 5 -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a2 b 0 -test/fk_10 a1 a 0 -test/fk_10 a2 b 1 -test/fk_2 a1 a 0 -test/fk_2 a2 b 1 -test/fk_3 a1 a 0 -test/fk_3 a2 b 1 -test/fk_4 a1 a 0 -test/fk_4 a2 b 1 -test/fk_5 a2 b 0 -test/fk_6 a1 a 0 -test/fk_6 a2 b 1 DROP TABLE child; DROP TABLE parent; CREATE TABLE parent (a INT PRIMARY KEY, b INT NOT NULL) ENGINE = InnoDB; @@ -261,12 +155,6 @@ child CREATE TABLE `child` ( KEY `fk_4` (`a2`), CONSTRAINT `fk_4` FOREIGN KEY (`a2`) REFERENCES `parent` (`b`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_4 test/child test/parent 1 5 -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_4 a2 b 0 SET foreign_key_checks = 1; DROP TABLE child; DROP TABLE parent; @@ -295,17 +183,6 @@ INSERT INTO parent VALUES(10,20),(20,30); CREATE TABLE child (a1 INT NOT NULL, a2 INT) ENGINE = InnoDB; CREATE INDEX tb ON child(a2); SET foreign_key_checks = 0; -SET DEBUG_DBUG = '+d,innodb_test_cannot_add_fk_system'; -ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT, -ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b) -ON DELETE SET NULL ON UPDATE CASCADE, -ALGORITHM = INPLACE; -ERROR HY000: Failed to add the foreign key constraint 'test/fk_1' to system tables -SET DEBUG_DBUG = @saved_debug_dbug; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; name name test/child a1 @@ -313,8 +190,6 @@ test/child a2 SELECT NAME FROM information_schema.INNODB_SYS_TABLES; NAME SYS_DATAFILES -SYS_FOREIGN -SYS_FOREIGN_COLS SYS_TABLESPACES SYS_VIRTUAL mysql/innodb_index_stats @@ -328,12 +203,6 @@ ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; Warnings: Warning 1280 Name 'idx' ignored for PRIMARY key. -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a2 b 0 SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; name name test/child a2 @@ -341,8 +210,6 @@ test/child a3 SELECT NAME FROM information_schema.INNODB_SYS_TABLES; NAME SYS_DATAFILES -SYS_FOREIGN -SYS_FOREIGN_COLS SYS_TABLESPACES SYS_VIRTUAL mysql/innodb_index_stats @@ -367,12 +234,6 @@ ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; Warnings: Warning 1280 Name 'idx' ignored for PRIMARY key. -SELECT * from information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a2 b 0 SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; name name test/child a1 @@ -380,8 +241,6 @@ test/child a2 SELECT NAME FROM information_schema.INNODB_SYS_TABLES; NAME SYS_DATAFILES -SYS_FOREIGN -SYS_FOREIGN_COLS SYS_TABLESPACES SYS_VIRTUAL mysql/innodb_index_stats @@ -404,12 +263,6 @@ ALTER TABLE child CHANGE a1 a3 INT, ADD CONSTRAINT fk_1 FOREIGN KEY (a3) REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; -SELECT * from information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_1 test/child test/parent 1 6 -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_1 a3 b 0 SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; name name test/child a2 @@ -417,8 +270,6 @@ test/child a3 SELECT NAME FROM information_schema.INNODB_SYS_TABLES; NAME SYS_DATAFILES -SYS_FOREIGN -SYS_FOREIGN_COLS SYS_TABLESPACES SYS_VIRTUAL mysql/innodb_index_stats @@ -467,14 +318,6 @@ child CREATE TABLE `child` ( CONSTRAINT `fk_a` FOREIGN KEY (`a2_new`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `fk_b` FOREIGN KEY (`a1_new`) REFERENCES `parent` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT * from information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_a test/child test/parent 1 6 -test/fk_b test/child test/parent 1 0 -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_a a2_new b 0 -test/fk_b a1_new a 0 ALTER TABLE child ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1_new) REFERENCES parent(b), ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2_new) REFERENCES parent(a), @@ -492,14 +335,6 @@ child CREATE TABLE `child` ( CONSTRAINT `fk_a` FOREIGN KEY (`a2_new`) REFERENCES `parent` (`b`) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT `fk_b` FOREIGN KEY (`a1_new`) REFERENCES `parent` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT * from information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_a test/child test/parent 1 6 -test/fk_b test/child test/parent 1 0 -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_a a2_new b 0 -test/fk_b a1_new a 0 ALTER TABLE child ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1_new) REFERENCES parent(b), ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2_new) REFERENCES parent(a), @@ -520,20 +355,6 @@ child CREATE TABLE `child` ( CONSTRAINT `fk_new_2` FOREIGN KEY (`a2_new`) REFERENCES `parent` (`a`), CONSTRAINT `fk_new_3` FOREIGN KEY (`a3`) REFERENCES `parent` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT * from information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_a test/child test/parent 1 6 -test/fk_b test/child test/parent 1 0 -test/fk_new_1 test/child test/parent 1 0 -test/fk_new_2 test/child test/parent 1 0 -test/fk_new_3 test/child test/parent 1 0 -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_a a2_new b 0 -test/fk_b a1_new a 0 -test/fk_new_1 a1_new b 0 -test/fk_new_2 a2_new a 0 -test/fk_new_3 a3 a 0 DROP TABLE child; CREATE TABLE child (a1 INT NOT NULL, a2 INT, a3 INT) ENGINE = InnoDB; CREATE INDEX tb ON child(a2); @@ -551,10 +372,6 @@ child CREATE TABLE `child` ( `a3` int(11) DEFAULT NULL, KEY `tb` (`a2`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT * from information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS ALTER TABLE child ADD PRIMARY KEY idx (a1), ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1) REFERENCES parent(b), ADD CONSTRAINT fk_new_2 FOREIGN KEY (a2) REFERENCES parent(a), @@ -575,16 +392,6 @@ child CREATE TABLE `child` ( CONSTRAINT `fk_new_2` FOREIGN KEY (`a2`) REFERENCES `parent` (`a`), CONSTRAINT `fk_new_3` FOREIGN KEY (`a3`) REFERENCES `parent` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -SELECT * from information_schema.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/fk_new_1 test/child test/parent 1 0 -test/fk_new_2 test/child test/parent 1 0 -test/fk_new_3 test/child test/parent 1 0 -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/fk_new_1 a1 b 0 -test/fk_new_2 a2 a 0 -test/fk_new_3 a3 a 0 SET foreign_key_checks = 1; DROP TABLE child; DROP TABLE parent; @@ -606,15 +413,5 @@ CREATE TABLE `t3`(a int,c int,d int) ENGINE=INNODB; CREATE INDEX idx ON t3(a); ALTER TABLE `t2` ADD CONSTRAINT `fw` FOREIGN KEY (`c`) REFERENCES t3 (a); ALTER TABLE `t2` ADD CONSTRAINT `e` foreign key (`d`) REFERENCES t3(a); -ALTER TABLE `t3` ADD CONSTRAINT `e` foreign key (`c`) REFERENCES `t2`(`c`) ON UPDATE SET NULL; -ERROR HY000: Failed to add the foreign key constraint 'test/e' to system tables -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/e test/t2 test/t3 1 0 -test/fw test/t2 test/t3 1 0 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/e d a 0 -test/fw c a 0 DROP TABLE t2; DROP TABLE t3; diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 8eebece46b5..659ad4984d4 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -72,7 +72,7 @@ ERROR 23000: Duplicate entry '4' for key 'c2' connection default; DELETE FROM t1 WHERE c1 = 7; connection con1; -ALTER TABLE t1 ADD FOREIGN KEY(c2) REFERENCES t1(c2), ALGORITHM = INPLACE; +ALTER TABLE t1 ADD FOREIGN KEY(c1) REFERENCES t1(c2), ALGORITHM = INPLACE; ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Adding foreign keys needs foreign_key_checks=OFF. Try ALGORITHM=COPY ALTER TABLE t1 ADD UNIQUE INDEX(c2), LOCK = EXCLUSIVE, ALGORITHM = INPLACE; DROP INDEX c2 ON t1; diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index 2a23990dbac..484323a980e 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -508,10 +508,10 @@ t4 CREATE TABLE `t4` ( CONSTRAINT `dc` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 alter table t3 add constraint dc foreign key (a) references t1(a); -ERROR HY000: Can't create table `test`.`t3` (errno: 121 "Duplicate key on write or update") +ERROR HY000: Duplicate FOREIGN KEY constraint name 'dc' SET FOREIGN_KEY_CHECKS=0; alter table t3 add constraint dc foreign key (a) references t1(a); -ERROR HY000: Failed to add the foreign key constraint 'test/dc' to system tables +ERROR HY000: Duplicate FOREIGN KEY constraint name 'dc' SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; show create table t3; Table Create Table diff --git a/mysql-test/suite/innodb/r/innodb-system-table-view.result b/mysql-test/suite/innodb/r/innodb-system-table-view.result index 11fc1ae8cf9..0da3edb0245 100644 --- a/mysql-test/suite/innodb/r/innodb-system-table-view.result +++ b/mysql-test/suite/innodb/r/innodb-system-table-view.result @@ -7,45 +7,31 @@ WHERE name = 'mysql/innodb_index_stats'; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE table_id NOT IN (@table_stats_id, @index_stats_id) ORDER BY table_id; TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE -11 SYS_FOREIGN 0 7 0 Redundant 0 System -12 SYS_FOREIGN_COLS 0 7 0 Redundant 0 System -13 SYS_TABLESPACES 0 6 0 Redundant 0 System -14 SYS_DATAFILES 0 5 0 Redundant 0 System -15 SYS_VIRTUAL 0 6 0 Redundant 0 System -18 mysql/transaction_registry 33 8 3 Dynamic 0 Single +11 SYS_TABLESPACES 0 6 0 Redundant 0 System +12 SYS_DATAFILES 0 5 0 Redundant 0 System +13 SYS_VIRTUAL 0 6 0 Redundant 0 System +16 mysql/transaction_registry 33 8 3 Dynamic 0 Single SELECT table_id,pos,mtype,prtype,len,name FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE table_id NOT IN (@table_stats_id, @index_stats_id) ORDER BY table_id, pos; table_id pos mtype prtype len name -11 0 1 524292 0 ID -11 1 1 524292 0 FOR_NAME -11 2 1 524292 0 REF_NAME -11 3 6 0 4 N_COLS -12 0 1 524292 0 ID -12 1 6 0 4 POS -12 2 1 524292 0 FOR_COL_NAME -12 3 1 524292 0 REF_COL_NAME -13 0 6 0 4 SPACE -13 1 1 524292 0 NAME -13 2 6 0 4 FLAGS -14 0 6 0 4 SPACE -14 1 1 524292 0 PATH -15 0 6 0 8 TABLE_ID -15 1 6 0 4 POS -15 2 6 0 4 BASE_POS -18 0 6 1800 8 transaction_id -18 1 6 1800 8 commit_id -18 2 3 526087 7 begin_timestamp -18 3 3 526087 7 commit_timestamp -18 4 6 1022 1 isolation_level +11 0 6 0 4 SPACE +11 1 1 524292 0 NAME +11 2 6 0 4 FLAGS +12 0 6 0 4 SPACE +12 1 1 524292 0 PATH +13 0 6 0 8 TABLE_ID +13 1 6 0 4 POS +13 2 6 0 4 BASE_POS +16 0 6 1800 8 transaction_id +16 1 6 1800 8 commit_id +16 2 3 526087 7 begin_timestamp +16 3 3 526087 7 commit_timestamp +16 4 6 1022 1 isolation_level SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE table_id NOT IN (@table_stats_id, @index_stats_id) ORDER BY index_id; INDEX_ID NAME TABLE_ID TYPE N_FIELDS PAGE_NO SPACE MERGE_THRESHOLD -# ID_IND # 3 1 # # 50 -# FOR_IND # 0 1 # # 50 -# REF_IND # 0 1 # # 50 -# ID_IND # 3 2 # # 50 # SYS_TABLESPACES_SPACE # 3 1 # # 50 # SYS_DATAFILES_SPACE # 3 1 # # 50 # BASE_IDX # 3 3 # # 50 @@ -57,25 +43,16 @@ SELECT index_id,pos,name FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS WHERE name NOT IN ('database_name', 'table_name', 'index_name', 'stat_name') ORDER BY index_id, pos; index_id pos name -11 0 ID -12 0 FOR_NAME -13 0 REF_NAME -14 0 ID -14 1 POS -15 0 SPACE -16 0 SPACE -17 0 TABLE_ID -17 1 POS -17 2 BASE_POS -20 0 transaction_id -21 0 commit_id -22 0 begin_timestamp -23 0 commit_timestamp -23 1 transaction_id -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS +11 0 SPACE +12 0 SPACE +13 0 TABLE_ID +13 1 POS +13 2 BASE_POS +16 0 transaction_id +17 0 commit_id +18 0 begin_timestamp +19 0 commit_timestamp +19 1 transaction_id CREATE TABLE t_redundant (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb; CREATE TABLE t_compact (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb; CREATE TABLE t_compressed (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb KEY_BLOCK_SIZE=2; @@ -95,7 +72,7 @@ test/t_dynamic DEFAULT DEFAULT MYSQLD_DATADIR/test/t_dynamic.ibd DROP TABLE t_redundant, t_compact, t_compressed, t_dynamic; SELECT count(*) FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS; count(*) -8 +6 CREATE TABLE parent (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; CREATE TABLE child (id INT, parent_id INT, @@ -103,12 +80,6 @@ INDEX par_ind (parent_id), CONSTRAINT constraint_test FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE) ENGINE=INNODB; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/constraint_test test/child test/parent 1 1 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/constraint_test parent_id id 0 INSERT INTO parent VALUES(1); InnoDB 0 transactions not purged SELECT name, num_rows, ref_count @@ -120,8 +91,6 @@ SELECT NAME, FLAG, N_COLS FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE name NOT LIKE 'sys/%'; NAME FLAG N_COLS SYS_DATAFILES 0 5 -SYS_FOREIGN 0 7 -SYS_FOREIGN_COLS 0 7 SYS_TABLESPACES 0 6 SYS_VIRTUAL 0 6 mysql/innodb_index_stats 33 11 @@ -161,13 +130,6 @@ INDEX par_ind (parent_id), CONSTRAINT constraint_test FOREIGN KEY (id, parent_id) REFERENCES parent(id, newid) ON DELETE CASCADE) ENGINE=INNODB; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/constraint_test test/child test/parent 2 1 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/constraint_test id id 0 -test/constraint_test parent_id newid 1 INSERT INTO parent VALUES(1, 9); SELECT * FROM parent WHERE id IN (SELECT id FROM parent); id newid diff --git a/mysql-test/suite/innodb/r/innodb-truncate.result b/mysql-test/suite/innodb/r/innodb-truncate.result index 0d358327fe3..a41a3ea04e5 100644 --- a/mysql-test/suite/innodb/r/innodb-truncate.result +++ b/mysql-test/suite/innodb/r/innodb-truncate.result @@ -83,8 +83,6 @@ SET FOREIGN_KEY_CHECKS= OFF; CREATE TABLE t1 (f2 INT, f4 INT, KEY(f2), FOREIGN KEY (f4) REFERENCES t3 (f4)) ENGINE=InnoDB; SET FOREIGN_KEY_CHECKS= ON; 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 42S02: Table 'test.t3' doesn't exist ALTER TABLE t1 FORCE; diff --git a/mysql-test/suite/innodb/r/innodb-wl5980-alter.result b/mysql-test/suite/innodb/r/innodb-wl5980-alter.result index 08ee9688603..cdf8a8f6222 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5980-alter.result +++ b/mysql-test/suite/innodb/r/innodb-wl5980-alter.result @@ -20,14 +20,6 @@ CREATE TABLE t1c (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX(c2), INDEX(c3), CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES t1(c2), CONSTRAINT t1c3 FOREIGN KEY (c3) REFERENCES t1p(c2)) ENGINE=InnoDB DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir'; -CREATE TABLE sys_foreign SELECT i.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i -WHERE FOR_NAME LIKE 'test/t%'; -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c2 0 -test/t1c3 c3 c2 0 SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; @@ -40,11 +32,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c2 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c2 0 -test/t1c3 c3 c2 0 SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -66,8 +53,6 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/' ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -93,17 +78,10 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c2 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c2 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE c2 c2 INT AFTER c1; ALTER TABLE t1 CHANGE c1 c1 INT FIRST; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -129,16 +107,9 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c2 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c2 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE C2 c3 INT; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -164,16 +135,9 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE c3 C INT; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -199,16 +163,9 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 C -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 C 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE C Cöŀumň_TWO INT; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -222,11 +179,6 @@ t1p.ibd ### files in MYSQL_TMP_DIR/alt_dir/test t1.ibd t1c.ibd -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 Cöŀumň_TWO 0 -test/t1c3 c3 c2 0 SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; @@ -239,18 +191,11 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 Cöŀumň_TWO -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 Cöŀumň_TWO 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 CHANGE cöĿǖmň_two c3 INT; ERROR 42S22: Unknown column 'cöĿǖmň_two' in 't1' ALTER TABLE t1 CHANGE cÖĿUMŇ_two c3 INT, RENAME TO t3; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -297,8 +242,6 @@ ALTER TABLE t3 CHANGE c3 `1234567890123456789012345678901234567890123456789012345678901234` INT; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -334,8 +277,6 @@ ALTER TABLE t3 CHANGE `倀倁倂倃倄倅倆倇倈倉倊個倌倍倎倏倐們倒倓倔倕倖倗倘候倚倛倜倝倞借倠倡倢倣値倥倦倧倨倩倪倫倬倭倮倯倰倱倲倳倴倵倶倷倸倹债倻值倽倾ä` INT; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -354,8 +295,6 @@ ALTER TABLE t3 CHANGE c3 INT; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -376,8 +315,6 @@ ERROR HY000: Invalid utf8mb4 character string: '\xF0\x9F\x98\xB2' ALTER TABLE t3 RENAME TO t2; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -413,8 +350,6 @@ NAME NAME test/t1 test/t1 ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -440,11 +375,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 -test/t1c3 c3 c2 0 ALTER TABLE t1 DROP INDEX c2; ERROR HY000: Cannot drop index 'c2': needed in a foreign key constraint ALTER TABLE t1 DROP INDEX c4; @@ -488,8 +418,6 @@ t1c CREATE TABLE `t1c` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir/' ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -513,11 +441,6 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 -test/t1c3 c3 c2 0 CREATE TABLE t1p (c1 INT PRIMARY KEY, c2 INT, INDEX(c2)) ENGINE=InnoDB DATA DIRECTORY='MYSQL_TMP_DIR/alt_dir'; ALTER TABLE t1c DROP INDEX C2, DROP INDEX C3; @@ -528,8 +451,6 @@ SET foreign_key_checks=0; ALTER TABLE t1c DROP INDEX C3; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -568,16 +489,9 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 -test/t1c3 c3 c2 0 ALTER TABLE t1c DROP FOREIGN KEY t1C3; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -614,15 +528,9 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS -test/t1c2 c2 c3 0 ALTER TABLE t1c DROP INDEX c2, DROP FOREIGN KEY t1C2; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -657,14 +565,9 @@ INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 c2 0 c3 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS ALTER TABLE t1 DROP INDEX c2, CHANGE c3 c2 INT; ### files in MYSQL_DATA_DIR/test db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -690,9 +593,6 @@ SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 c1 -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS CREATE TABLE t1o LIKE t1; ALTER TABLE t1 ADD FULLTEXT INDEX (ct), CHANGE c1 pk INT, ALTER c2 SET DEFAULT 42, RENAME TO tt, @@ -714,8 +614,6 @@ FTS_AUX_CONFIG.isl FTS_AUX_DELETED.isl FTS_AUX_DELETED_CACHE.isl db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -750,9 +648,6 @@ NAME POS MTYPE PRTYPE LEN SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS SHOW CREATE TABLE tt; Table Create Table tt CREATE TABLE `tt` ( @@ -809,8 +704,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -871,8 +764,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -927,8 +818,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -984,8 +873,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1050,8 +937,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1119,8 +1004,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1185,8 +1068,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1243,8 +1124,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1299,8 +1178,6 @@ FTS_AUX_CONFIG.isl FTS_AUX_DELETED.isl FTS_AUX_DELETED_CACHE.isl db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1355,8 +1232,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1417,8 +1292,6 @@ FTS_AUX_CONFIG.isl FTS_AUX_DELETED.isl FTS_AUX_DELETED_CACHE.isl db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1454,13 +1327,11 @@ t1o CREATE TABLE `t1o` ( `ct` text DEFAULT NULL, PRIMARY KEY (`foo_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 -DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign; +DROP TABLE t1c, t1p, sys_tables, sys_indexes; CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1o'; CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; -CREATE TABLE sys_foreign SELECT i.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i WHERE FOR_NAME='test/t1o'; SELECT i.NAME,i.POS,i.MTYPE,i.PRTYPE,i.LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; @@ -1472,9 +1343,6 @@ SELECT si.NAME,i.POS,i.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS i INNER JOIN sys_indexes si ON i.INDEX_ID=si.INDEX_ID; NAME POS NAME PRIMARY 0 foo_id -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS ALTER TABLE t1o ADD UNIQUE INDEX FTS_DOC_ID_INDEX(foo_id); ### files in MYSQL_DATA_DIR/test FTS_AUX_INDEX_1.isl @@ -1489,8 +1357,6 @@ FTS_AUX_CONFIG.isl FTS_AUX_DELETED.isl FTS_AUX_DELETED_CACHE.isl db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1538,8 +1404,6 @@ FTS_AUX_CONFIG.ibd FTS_AUX_DELETED.ibd FTS_AUX_DELETED_CACHE.ibd db.opt -sys_foreign.frm -sys_foreign.ibd sys_indexes.frm sys_indexes.ibd sys_tables.frm @@ -1579,13 +1443,10 @@ NAME POS NAME PRIMARY 0 FTS_DOC_ID FTS_DOC_ID_INDEX 0 FTS_DOC_ID ct 0 ct -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; -ID FOR_COL_NAME REF_COL_NAME POS # # Cleanup # -DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign; +DROP TABLE tt, t1o, sys_tables, sys_indexes; ### files in MYSQL_DATA_DIR/test db.opt ### files in MYSQL_TMP_DIR/alt_dir/test diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index e77e82d57de..898ec2218a6 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -1555,7 +1555,7 @@ t2 CREATE TABLE `t2` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2; create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb; -ERROR 42000: Incorrect foreign key definition for 't1_id_fk': Key reference and table reference don't match +ERROR 42000: Incorrect foreign key definition for 't1_id_fk' create table t2 (a int auto_increment primary key, b int, index(b), foreign key (b) references t1(id), unique(b)) engine=innodb; show create table t2; Table Create Table @@ -2531,9 +2531,11 @@ disconnect b; set foreign_key_checks=0; create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; create table t1(a char(10) primary key, b varchar(20)) engine = innodb; -ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") set foreign_key_checks=1; -drop table t2; +insert into t1 values (1, 1); +insert into t2 values (1, 1); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_t2` FOREIGN KEY (`b`) REFERENCES `t1` (`a`)) +drop tables t2, t1; set foreign_key_checks=0; create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8; @@ -2541,25 +2543,11 @@ ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint set foreign_key_checks=1; drop table t1; set foreign_key_checks=0; -create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb; -create table t1(a varchar(10) primary key) engine = innodb; -alter table t1 modify column a int; -set foreign_key_checks=1; -drop table t2,t1; -set foreign_key_checks=0; create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; alter table t1 convert to character set utf8; set foreign_key_checks=1; drop table t2,t1; -call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`.`t1` has or is referenced in foreign key constraints which are not compatible with the new table definition."); -set foreign_key_checks=0; -create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; -create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; -rename table t3 to t1; -ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150 "Foreign key constraint is incorrectly formed") -set foreign_key_checks=1; -drop table t2,t3; create table t1(a int primary key) row_format=redundant engine=innodb; create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb; create table t3(a int primary key) row_format=compact engine=innodb; diff --git a/mysql-test/suite/innodb/r/innodb_bug12902967.result b/mysql-test/suite/innodb/r/innodb_bug12902967.result deleted file mode 100644 index ddb2e12f26a..00000000000 --- a/mysql-test/suite/innodb/r/innodb_bug12902967.result +++ /dev/null @@ -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-alter' to './test/t1' (errno: 150 "Foreign key constraint is incorrectly formed") -drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb_bug21704.result b/mysql-test/suite/innodb/r/innodb_bug21704.result index c0bc3af2f20..cc5c7a35a16 100644 --- a/mysql-test/suite/innodb/r/innodb_bug21704.result +++ b/mysql-test/suite/innodb/r/innodb_bug21704.result @@ -76,14 +76,6 @@ t3 CREATE TABLE `t3` ( KEY `b` (`g`), CONSTRAINT `fk2` FOREIGN KEY (`g`) REFERENCES `t3` (`f`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -SELECT f.*, c.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS c -INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FOREIGN f -ON c.ID=f.ID -WHERE FOR_NAME LIKE 'test/t%'; -ID FOR_NAME REF_NAME N_COLS TYPE ID FOR_COL_NAME REF_COL_NAME POS -test/fk1 test/t2 test/t1 1 0 test/fk1 z e 0 -test/fk2 test/t3 test/t3 1 0 test/fk2 g f 0 DROP TABLE t3; DROP TABLE t2; DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb_bug57255.result b/mysql-test/suite/innodb/r/innodb_bug57255.result index d61a0d42ba3..818fe32fd06 100644 --- a/mysql-test/suite/innodb/r/innodb_bug57255.result +++ b/mysql-test/suite/innodb/r/innodb_bug57255.result @@ -8,3 +8,4 @@ DELETE FROM A where id = 1; DROP TABLE C; DROP TABLE B; DROP TABLE A; +flush tables; diff --git a/mysql-test/suite/innodb/r/innodb_bug60049.result b/mysql-test/suite/innodb/r/innodb_bug60049.result index 47b02dedd01..223080db0a1 100644 --- a/mysql-test/suite/innodb/r/innodb_bug60049.result +++ b/mysql-test/suite/innodb/r/innodb_bug60049.result @@ -5,5 +5,5 @@ SELECT @@innodb_fast_shutdown; @@innodb_fast_shutdown 0 Last record of ID_IND root page (9): -18080000180500c0000000000000000c5359535f464f524549474e5f434f4c53 +4143455315080000180500c1000000000000000c5359535f4441544146494c45 # restart diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index aa9ab6c176f..7fce1ab0ae7 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2109,10 +2109,10 @@ DROP TABLE t1, t2; CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) engine=innodb; CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), CONSTRAINT c2 FOREIGN KEY f2 (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb; -ERROR 42000: Incorrect foreign key definition for 'f2': Key reference and table reference don't match +ERROR 42000: Incorrect foreign key definition for 'c2' CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb; -ERROR 42000: Incorrect foreign key definition for 'c2': Key reference and table reference don't match +ERROR 42000: Incorrect foreign key definition for 'c2' CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), CONSTRAINT c1 FOREIGN KEY c2 (c) REFERENCES t1 (a) ON DELETE NO ACTION, CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb; @@ -2120,10 +2120,10 @@ ALTER TABLE t2 DROP FOREIGN KEY c2; DROP TABLE t2; CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), FOREIGN KEY (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb; -ERROR 42000: Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match +ERROR 42000: Incorrect foreign key definition for 'foreign key without name' CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), FOREIGN KEY f1 (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb; -ERROR 42000: Incorrect foreign key definition for 'f1': Key reference and table reference don't match +ERROR 42000: Incorrect foreign key definition for 'f1' CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), CONSTRAINT c1 FOREIGN KEY f1 (c) REFERENCES t1 (a) ON DELETE NO ACTION, CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION, @@ -3200,7 +3200,7 @@ Table Create Table t2 CREATE TABLE `t2` ( `fk` int(11) DEFAULT NULL, KEY `x` (`fk`), - CONSTRAINT `x` FOREIGN KEY (`fk`) REFERENCES `t1` (`pk`) + CONSTRAINT `x` FOREIGN KEY (`FK`) REFERENCES `t1` (`PK`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2, t1; # diff --git a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result index 9ab72408274..4d1d86ea994 100644 --- a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result +++ b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result @@ -370,14 +370,6 @@ select * from information_schema.innodb_sys_fields; INDEX_ID NAME POS Warnings: Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_sys_fields but the InnoDB storage engine is not installed -select * from information_schema.innodb_sys_foreign; -ID FOR_NAME REF_NAME N_COLS TYPE -Warnings: -Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_sys_foreign but the InnoDB storage engine is not installed -select * from information_schema.innodb_sys_foreign_cols; -ID FOR_COL_NAME REF_COL_NAME POS -Warnings: -Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_sys_foreign_cols but the InnoDB storage engine is not installed select * from information_schema.innodb_sys_tablespaces; SPACE NAME FLAG ROW_FORMAT PAGE_SIZE ZIP_PAGE_SIZE FS_BLOCK_SIZE FILE_SIZE ALLOCATED_SIZE Warnings: diff --git a/mysql-test/suite/innodb/r/instant_alter_index_rename.result b/mysql-test/suite/innodb/r/instant_alter_index_rename.result index 988aaf80d60..d4fa3a66111 100644 --- a/mysql-test/suite/innodb/r/instant_alter_index_rename.result +++ b/mysql-test/suite/innodb/r/instant_alter_index_rename.result @@ -181,7 +181,7 @@ drop table rename_column_and_index; create table t1 (f1 int, f2 int, f3 int); create table t2 (f2 int primary key); alter table t1 add foreign key f (f2) references t2(f2); -alter table t1 add foreign key (f2) references t1(f2), add key (f3), add key (f1); +alter table t1 add foreign key (f1) references t1(f2), add key (f3), add key (f1); drop tables t1, t2; # # MDEV-21669 InnoDB: Table ... contains <n> indexes inside InnoDB, which is different from the number of indexes <n> defined in the MariaDB diff --git a/mysql-test/suite/innodb/r/table_flags,32k,debug.rdiff b/mysql-test/suite/innodb/r/table_flags,32k,debug.rdiff index 7e851cf5634..e06c8197a1b 100644 --- a/mysql-test/suite/innodb/r/table_flags,32k,debug.rdiff +++ b/mysql-test/suite/innodb/r/table_flags,32k,debug.rdiff @@ -1,6 +1,6 @@ ---- suite/innodb/r/table_flags.result -+++ suite/innodb/r/table_flags,32k,debug.reject -@@ -5,96 +5,98 @@ +--- ./table_flags.result 2020-07-28 12:33:31.937242985 +0300 ++++ ./table_flags,32k,debug.reject 2020-07-28 14:51:37.080663807 +0300 +@@ -6,6 +6,8 @@ SET innodb_strict_mode=OFF; CREATE TABLE tz(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; @@ -9,121 +9,9 @@ SET innodb_strict_mode=ON; CREATE TABLE tp(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=DYNAMIC PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9; - SYS_TABLES clustered index root page (8): - N_RECS=10; LEVEL=0; INDEX_ID=0x0000000000000001 --header=0x01000003016e (NAME=0x696e66696d756d00) --header=0x00002815008d (NAME='SYS_DATAFILES', -+header=0x0100000301bf (NAME=0x696e66696d756d00) -+header=0x0000301500de (NAME='SYS_DATAFILES', - DB_TRX_ID=0x000000000000, +@@ -87,7 +89,7 @@ DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000e, -+ ID=0x000000000000000f, - N_COLS=0x00000002, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x0000101500d5 (NAME='SYS_FOREIGN', -+header=0x000018150126 (NAME='SYS_FOREIGN', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000b, -+ ID=0x000000000000000c, - N_COLS=0x00000004, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x000018150122 (NAME='SYS_FOREIGN_COLS', -+header=0x000020150173 (NAME='SYS_FOREIGN_COLS', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000c, -+ ID=0x000000000000000d, - N_COLS=0x00000004, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x0400201501b8 (NAME='SYS_TABLESPACES', -+header=0x040028150209 (NAME='SYS_TABLESPACES', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000d, -+ ID=0x000000000000000e, - N_COLS=0x00000003, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x000030150244 (NAME='SYS_VIRTUAL', -+header=0x000038150251 (NAME='SYS_VIRTUAL', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000f, -+ ID=0x0000000000000010, - N_COLS=0x00000003, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x000040150288 (NAME='test/tc', -+header=0x000040150295 (NAME='test/tc', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000011, -+ ID=0x0000000000000012, - N_COLS=0x80000001, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000050, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000002) --header=0x000048150310 (NAME='test/td', -+header=0x00004815031d (NAME='test/td', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000012, -+ ID=0x0000000000000013, - N_COLS=0x80000001, - TYPE=0x00000021, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000050, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000003) --header=0x000058150200 (NAME='test/tp', -+header=0x00005815008d (NAME='test/tp', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000014, -+ ID=0x0000000000000015, - N_COLS=0x80000001, - TYPE=0x000009a1, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000050, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000005) --header=0x0000381502cc (NAME='test/tr', -+header=0x0000101502d9 (NAME='test/tr', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000010, -+ ID=0x0000000000000011, - N_COLS=0x00000001, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, -@@ -104,9 +106,9 @@ - header=0x000050150074 (NAME='test/tz', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000013, -+ ID=0x0000000000000014, + ID=0x0000000000000011, N_COLS=0x80000001, - TYPE=0x00000023, + TYPE=0x00000021, diff --git a/mysql-test/suite/innodb/r/table_flags,64k,debug.rdiff b/mysql-test/suite/innodb/r/table_flags,64k,debug.rdiff index da52f17fa68..a1b13f38b2b 100644 --- a/mysql-test/suite/innodb/r/table_flags,64k,debug.rdiff +++ b/mysql-test/suite/innodb/r/table_flags,64k,debug.rdiff @@ -1,6 +1,6 @@ ---- suite/innodb/r/table_flags.result -+++ suite/innodb/r/table_flags,64k,debug.reject -@@ -5,96 +5,98 @@ +--- ./table_flags.result 2020-07-28 12:33:31.937242985 +0300 ++++ ./table_flags,64k,debug.reject 2020-07-28 14:51:55.346069234 +0300 +@@ -6,6 +6,8 @@ SET innodb_strict_mode=OFF; CREATE TABLE tz(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; @@ -9,121 +9,9 @@ SET innodb_strict_mode=ON; CREATE TABLE tp(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=DYNAMIC PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9; - SYS_TABLES clustered index root page (8): - N_RECS=10; LEVEL=0; INDEX_ID=0x0000000000000001 --header=0x01000003016e (NAME=0x696e66696d756d00) --header=0x00002815008d (NAME='SYS_DATAFILES', -+header=0x0100000301bf (NAME=0x696e66696d756d00) -+header=0x0000301500de (NAME='SYS_DATAFILES', - DB_TRX_ID=0x000000000000, +@@ -87,7 +89,7 @@ DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000e, -+ ID=0x000000000000000f, - N_COLS=0x00000002, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x0000101500d5 (NAME='SYS_FOREIGN', -+header=0x000018150126 (NAME='SYS_FOREIGN', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000b, -+ ID=0x000000000000000c, - N_COLS=0x00000004, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x000018150122 (NAME='SYS_FOREIGN_COLS', -+header=0x000020150173 (NAME='SYS_FOREIGN_COLS', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000c, -+ ID=0x000000000000000d, - N_COLS=0x00000004, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x0400201501b8 (NAME='SYS_TABLESPACES', -+header=0x040028150209 (NAME='SYS_TABLESPACES', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000d, -+ ID=0x000000000000000e, - N_COLS=0x00000003, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x000030150244 (NAME='SYS_VIRTUAL', -+header=0x000038150251 (NAME='SYS_VIRTUAL', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x000000000000000f, -+ ID=0x0000000000000010, - N_COLS=0x00000003, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) --header=0x000040150288 (NAME='test/tc', -+header=0x000040150295 (NAME='test/tc', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000011, -+ ID=0x0000000000000012, - N_COLS=0x80000001, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000050, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000002) --header=0x000048150310 (NAME='test/td', -+header=0x00004815031d (NAME='test/td', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000012, -+ ID=0x0000000000000013, - N_COLS=0x80000001, - TYPE=0x00000021, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000050, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000003) --header=0x000058150200 (NAME='test/tp', -+header=0x00005815008d (NAME='test/tp', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000014, -+ ID=0x0000000000000015, - N_COLS=0x80000001, - TYPE=0x000009a1, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000050, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000005) --header=0x0000381502cc (NAME='test/tr', -+header=0x0000101502d9 (NAME='test/tr', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000010, -+ ID=0x0000000000000011, - N_COLS=0x00000001, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, -@@ -104,9 +106,9 @@ - header=0x000050150074 (NAME='test/tz', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, -- ID=0x0000000000000013, -+ ID=0x0000000000000014, + ID=0x0000000000000011, N_COLS=0x80000001, - TYPE=0x00000023, + TYPE=0x00000021, diff --git a/mysql-test/suite/innodb/r/table_flags.result b/mysql-test/suite/innodb/r/table_flags.result index 82935944027..af55b68d5f2 100644 --- a/mysql-test/suite/innodb/r/table_flags.result +++ b/mysql-test/suite/innodb/r/table_flags.result @@ -10,39 +10,29 @@ SET innodb_strict_mode=ON; CREATE TABLE tp(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=DYNAMIC PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9; SYS_TABLES clustered index root page (8): -N_RECS=10; LEVEL=0; INDEX_ID=0x0000000000000001 -header=0x01000003016e (NAME=0x696e66696d756d00) -header=0x00002815008d (NAME='SYS_DATAFILES', +N_RECS=8; LEVEL=0; INDEX_ID=0x0000000000000001 +header=0x0100000300d9 (NAME=0x696e66696d756d00) +header=0x00001815008d (NAME='SYS_DATAFILES', DB_TRX_ID=0x000000000000, DB_ROLL_PTR=0x80000000000000, - ID=0x000000000000000e, + ID=0x000000000000000c, N_COLS=0x00000002, TYPE=0x00000001, MIX_ID=0x0000000000000000, MIX_LEN=0x00000040, CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000000) -header=0x0000101500d5 (NAME='SYS_FOREIGN', +header=0x000010150123 (NAME='SYS_TABLESPACES', DB_TRX_ID=0x000000000000, DB_ROLL_PTR=0x80000000000000, ID=0x000000000000000b, - N_COLS=0x00000004, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) -header=0x000018150122 (NAME='SYS_FOREIGN_COLS', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, - ID=0x000000000000000c, - N_COLS=0x00000004, + N_COLS=0x00000003, TYPE=0x00000001, MIX_ID=0x0000000000000000, MIX_LEN=0x00000040, CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000000) -header=0x0400201501b8 (NAME='SYS_TABLESPACES', +header=0x0000201501af (NAME='SYS_VIRTUAL', DB_TRX_ID=0x000000000000, DB_ROLL_PTR=0x80000000000000, ID=0x000000000000000d, @@ -52,67 +42,57 @@ header=0x0400201501b8 (NAME='SYS_TABLESPACES', MIX_LEN=0x00000040, CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000000) -header=0x000030150244 (NAME='SYS_VIRTUAL', +header=0x0400301501f3 (NAME='test/tc', DB_TRX_ID=0x000000000000, DB_ROLL_PTR=0x80000000000000, ID=0x000000000000000f, - N_COLS=0x00000003, - TYPE=0x00000001, - MIX_ID=0x0000000000000000, - MIX_LEN=0x00000040, - CLUSTER_NAME=NULL(0 bytes), - SPACE=0x00000000) -header=0x000040150288 (NAME='test/tc', - DB_TRX_ID=0x000000000000, - DB_ROLL_PTR=0x80000000000000, - ID=0x0000000000000011, N_COLS=0x80000001, TYPE=0x00000001, MIX_ID=0x0000000000000000, MIX_LEN=0x00000050, CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000002) -header=0x000048150310 (NAME='test/td', +header=0x00003815027b (NAME='test/td', DB_TRX_ID=0x000000000000, DB_ROLL_PTR=0x80000000000000, - ID=0x0000000000000012, + ID=0x0000000000000010, N_COLS=0x80000001, TYPE=0x00000021, MIX_ID=0x0000000000000000, MIX_LEN=0x00000050, CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000003) -header=0x000058150200 (NAME='test/tp', +header=0x00004815016b (NAME='test/tp', DB_TRX_ID=0x000000000000, DB_ROLL_PTR=0x80000000000000, - ID=0x0000000000000014, + ID=0x0000000000000012, N_COLS=0x80000001, TYPE=0x000009a1, MIX_ID=0x0000000000000000, MIX_LEN=0x00000050, CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000005) -header=0x0000381502cc (NAME='test/tr', +header=0x000028150237 (NAME='test/tr', DB_TRX_ID=0x000000000000, DB_ROLL_PTR=0x80000000000000, - ID=0x0000000000000010, + ID=0x000000000000000e, N_COLS=0x00000001, TYPE=0x00000001, MIX_ID=0x0000000000000000, MIX_LEN=0x00000050, CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000001) -header=0x000050150074 (NAME='test/tz', +header=0x000040150074 (NAME='test/tz', DB_TRX_ID=0x000000000000, DB_ROLL_PTR=0x80000000000000, - ID=0x0000000000000013, + ID=0x0000000000000011, N_COLS=0x80000001, TYPE=0x00000023, MIX_ID=0x0000000000000000, MIX_LEN=0x00000050, CLUSTER_NAME=NULL(0 bytes), SPACE=0x00000004) -header=0x070008030000 (NAME=0x73757072656d756d00) +header=0x050008030000 (NAME=0x73757072656d756d00) # restart: with restart_parameters SHOW CREATE TABLE tr; ERROR 42S02: Table 'test.tr' doesn't exist in engine diff --git a/mysql-test/suite/innodb/r/truncate_foreign.result b/mysql-test/suite/innodb/r/truncate_foreign.result index d391436dec1..19edeacd892 100644 --- a/mysql-test/suite/innodb/r/truncate_foreign.result +++ b/mysql-test/suite/innodb/r/truncate_foreign.result @@ -45,14 +45,17 @@ connection default; SET DEBUG_SYNC='now WAIT_FOR fk'; SET foreign_key_checks=0; TRUNCATE TABLE parent; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction SET DEBUG_SYNC='now SIGNAL go'; connection dml; -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `fk_child` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON UPDATE CASCADE) SELECT * FROM parent; a +3 +5 SELECT * FROM child; a 3 +5 disconnect dml; connection default; SET DEBUG_SYNC = RESET; diff --git a/mysql-test/suite/innodb/t/add_constraint.test b/mysql-test/suite/innodb/t/add_constraint.test deleted file mode 100644 index f43f2977020..00000000000 --- a/mysql-test/suite/innodb/t/add_constraint.test +++ /dev/null @@ -1,20 +0,0 @@ ---source include/have_innodb.inc - ---echo # ---echo # Bug #20762798 FK DDL: CRASH IN DICT_FOREIGN_REMOVE_FROM_CACHE ---echo # - -create table t1(a int, b int, key(a),key(b))engine=innodb; -create table t2(a int, b int, key(a),key(b))engine=innodb; - -alter table t2 add constraint b foreign key (b) references t1(a); -alter table t1 add constraint b1 foreign key (b) references t2(a); - ---error ER_CANT_CREATE_TABLE -alter table t2 add constraint b1 foreign key (b) references t1(a); - -alter table t2 drop foreign key b; -alter table t1 drop foreign key b1; - -drop table t2; -drop table t1; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index e5582a76d3e..fe05ce63ee7 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -8,7 +8,7 @@ --echo # create table t1 (f1 int primary key) engine=InnoDB; ---error ER_CANT_CREATE_TABLE +--error ER_DUP_CONSTRAINT_NAME create table t2 (f1 int primary key, constraint c1 foreign key (f1) references t1(f1), constraint c1 foreign key (f1) references t1(f1)) engine=InnoDB; @@ -159,12 +159,11 @@ CREATE DATABASE best default character set latin1; CREATE TABLE t3 (a INT PRIMARY KEY, CONSTRAINT t2_ibfk_1 FOREIGN KEY (a) REFERENCES t1(a)) ENGINE=InnoDB; CREATE TABLE best.t2 (a INT PRIMARY KEY, b TEXT, FULLTEXT INDEX(b), -FOREIGN KEY t2_ibfk_1 (a) REFERENCES test.t1(a)) ENGINE=InnoDB; ---replace_regex /Table '.*t2'/Table 't2'/ ---error ER_TABLE_EXISTS_ERROR +FOREIGN KEY (a) REFERENCES test.t1(a)) ENGINE=InnoDB; RENAME TABLE best.t2 TO test.t2; -SHOW CREATE TABLE best.t2; +SHOW CREATE TABLE test.t2; DROP DATABASE best; +DROP TABLE t2; --echo # --echo # MDEV-17541 KILL QUERY during lock wait in FOREIGN KEY check hangs @@ -202,8 +201,8 @@ DROP TABLE t3,t1; --echo # MDEV-18222 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N --echo # or ASAN heap-use-after-free in dict_foreign_remove_from_cache upon CHANGE COLUMN --echo # -CREATE TABLE t1 (a INT, UNIQUE(a), KEY(a)) ENGINE=InnoDB; -ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (a); +CREATE TABLE t1 (a INT, UNIQUE(a), KEY(a), c INT) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (c) REFERENCES t1 (a); SET SESSION FOREIGN_KEY_CHECKS = OFF; ALTER TABLE t1 CHANGE COLUMN a a TIME NOT NULL; ALTER TABLE t1 ADD pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY; @@ -724,7 +723,7 @@ DROP TABLE t2, t1; # MDEV-21792 Server aborts upon attempt to create foreign key on spatial field # Fail to create foreign key for spatial fields ---error ER_NO_SUCH_TABLE +--error ER_CANT_CREATE_TABLE CREATE TABLE t1 (a GEOMETRY, INDEX(a(8)), FOREIGN KEY (a) REFERENCES x (xx)) ENGINE=InnoDB; @@ -789,3 +788,116 @@ drop table t1; --echo # End of 10.5 tests --source include/wait_until_count_sessions.inc + +--echo # +--echo # Bug #20762798 FK DDL: CRASH IN DICT_FOREIGN_REMOVE_FROM_CACHE +--echo # + +create table t1(a int, b int, key(a),key(b))engine=innodb; +create table t2(a int, b int, key(a),key(b))engine=innodb; + +alter table t2 add constraint b foreign key (b) references t1(a); +alter table t1 add constraint b1 foreign key (b) references t2(a); + +alter table t2 add constraint b1 foreign key (b) references t1(a); + +alter table t2 drop foreign key b; +alter table t1 drop foreign key b1; + +drop table t2; +drop table t1; + +# +# MDEV-10083: Orphan ibd file when playing with foreign keys +# +--disable_query_log +SET @start_global_fpt = @@global.innodb_file_per_table; +SET @start_global_fkc = @@global.foreign_key_checks; +--enable_query_log + +set global innodb_file_per_table = 1; + +--disable_warnings +drop table if exists b; +drop database if exists bug_fk; +--enable_warnings + +let $MYSQLD_DATADIR = `select @@datadir`; + +create database bug_fk; +use bug_fk; + +CREATE TABLE b ( + b int unsigned NOT NULL, + d1 datetime NOT NULL, + PRIMARY KEY (b,d1) +) ENGINE=InnoDB; + +CREATE TABLE c ( + b int unsigned NOT NULL, + d1 datetime NOT NULL, + d2 datetime NOT NULL, + PRIMARY KEY (b,d1), + CONSTRAINT b_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; + +insert into b values (1, '1980-01-01 00:00:00'); +insert into c values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:00'); +--error ER_ROW_IS_REFERENCED_2 +delete from b; +--error ER_NO_REFERENCED_ROW_2 +update c set b= 2; + +show warnings; + +set foreign_key_checks = 0; + +DROP TABLE IF EXISTS b; + +show create table c; + +# +# Note that column b has different type in parent table +# +CREATE TABLE b ( + b bigint unsigned NOT NULL, + d1 date NOT NULL, + PRIMARY KEY (b,d1) +) ENGINE=InnoDB; + +show warnings; + +DROP TABLE IF EXISTS d; + +CREATE TABLE d ( + b bigint unsigned NOT NULL, + d1 date NOT NULL, + PRIMARY KEY (b,d1), + CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; + +show warnings; + +set foreign_key_checks = 1; + +show create table c; +show create table d; + +--error ER_NO_REFERENCED_ROW_2 +update c set b= 2; +--error ER_NO_REFERENCED_ROW_2 +insert into c values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:00'); +insert into b values (2, '1980-01-01 00:00:00'); +--error ER_NO_REFERENCED_ROW_2 +insert into c values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:00'); +insert into d values (2, '1980-01-01 00:00:00'); + +# +# Cleanup +# +--disable_query_log +SET @@global.innodb_file_per_table = @start_global_fpt; +SET @@global.foreign_key_checks = @start_global_fkc; +--enable_query_log + +drop database bug_fk; diff --git a/mysql-test/suite/innodb/t/information_schema_grants.opt b/mysql-test/suite/innodb/t/information_schema_grants.opt index 38c5e3cf1cd..93fbafe22f0 100644 --- a/mysql-test/suite/innodb/t/information_schema_grants.opt +++ b/mysql-test/suite/innodb/t/information_schema_grants.opt @@ -22,8 +22,6 @@ --enable-plugin-innodb-sys-indexes --enable-plugin-innodb-sys-columns --enable-plugin-innodb-sys-fields ---enable-plugin-innodb-sys-foreign ---enable-plugin-innodb-sys-foreign-cols --enable-plugin-innodb-sys-tablespaces --enable-plugin-innodb-sys-datafiles --enable-plugin-innodb-sys-virtual diff --git a/mysql-test/suite/innodb/t/information_schema_grants.test b/mysql-test/suite/innodb/t/information_schema_grants.test index 72982b3ec1c..1322606536a 100644 --- a/mysql-test/suite/innodb/t/information_schema_grants.test +++ b/mysql-test/suite/innodb/t/information_schema_grants.test @@ -76,12 +76,6 @@ create sql security definer view d_sys_datafiles as select * from information_sc create sql security invoker view i_sys_fields as select * from information_schema.innodb_sys_fields; create sql security definer view d_sys_fields as select * from information_schema.innodb_sys_fields; -create sql security invoker view i_sys_foreign as select * from information_schema.innodb_sys_foreign; -create sql security definer view d_sys_foreign as select * from information_schema.innodb_sys_foreign; - -create sql security invoker view i_sys_foreign_cols as select * from information_schema.innodb_sys_foreign_cols; -create sql security definer view d_sys_foreign_cols as select * from information_schema.innodb_sys_foreign_cols; - create sql security invoker view i_sys_indexes as select * from information_schema.innodb_sys_indexes; create sql security definer view d_sys_indexes as select * from information_schema.innodb_sys_indexes; @@ -237,18 +231,6 @@ select count(*) > -1 from i_sys_fields; select count(*) > -1 from d_sys_fields; --error ER_SPECIFIC_ACCESS_DENIED_ERROR -select count(*) > -1 from information_schema.innodb_sys_foreign; ---error ER_SPECIFIC_ACCESS_DENIED_ERROR -select count(*) > -1 from i_sys_foreign; -select count(*) > -1 from d_sys_foreign; - ---error ER_SPECIFIC_ACCESS_DENIED_ERROR -select count(*) > -1 from information_schema.innodb_sys_foreign_cols; ---error ER_SPECIFIC_ACCESS_DENIED_ERROR -select count(*) > -1 from i_sys_foreign_cols; -select count(*) > -1 from d_sys_foreign_cols; - ---error ER_SPECIFIC_ACCESS_DENIED_ERROR select count(*) > -1 from information_schema.innodb_sys_indexes; --error ER_SPECIFIC_ACCESS_DENIED_ERROR select count(*) > -1 from i_sys_indexes; diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test index 7fbbb3159ee..c3eb9dfa4ff 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-debug.test +++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test @@ -4,33 +4,6 @@ --source include/count_sessions.inc -SET NAMES utf8; - -CREATE TABLE ① ( - c1 INT PRIMARY KEY, c2 INT DEFAULT 1, ct TEXT, INDEX(c2)) -ENGINE = InnoDB; - -CREATE TABLE t1ć (c1 INT PRIMARY KEY, c2 INT, INDEX(c2), - CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES ①(c2)) -ENGINE=InnoDB; - -INSERT INTO ① SET c1 = 1; - -SET @saved_debug_dbug = @@SESSION.debug_dbug; -SET DEBUG_DBUG = '+d,ib_drop_foreign_error'; ---error ER_RECORD_FILE_FULL -ALTER TABLE t1ć DROP FOREIGN KEY t1c2, RENAME TO ②; -SET DEBUG_DBUG = @saved_debug_dbug; - -SET DEBUG_DBUG = '+d,ib_rename_column_error'; ---error ER_RECORD_FILE_FULL -ALTER TABLE ① CHANGE c2 š INT; -SET DEBUG_DBUG = @saved_debug_dbug; - -SHOW CREATE TABLE t1ć; - -DROP TABLE t1ć, ①; - --echo # --echo # Bug #21364096 THE BOGUS DUPLICATE KEY ERROR IN ONLINE DDL --echo # WITH INCORRECT KEY NAME diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test index f72935ebc3c..002589ec412 100644 --- a/mysql-test/suite/innodb/t/innodb-alter.test +++ b/mysql-test/suite/innodb/t/innodb-alter.test @@ -22,13 +22,6 @@ CREATE TABLE t1c (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX(c2), INDEX(c3), CONSTRAINT t1c3 FOREIGN KEY (c3) REFERENCES t1p(c2)) ENGINE=InnoDB; -CREATE TABLE sys_foreign SELECT i.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i -WHERE FOR_NAME LIKE 'test/t%'; - -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; - -- source suite/innodb/include/innodb_dict.inc SHOW CREATE TABLE t1; @@ -53,9 +46,6 @@ ALTER TABLE t1 CHANGE c3 C INT; ALTER TABLE t1 CHANGE C Cöŀumň_TWO INT; -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; - -- source suite/innodb/include/innodb_dict.inc -- error ER_BAD_FIELD_ERROR @@ -360,7 +350,7 @@ DROP INDEX ct, ALGORITHM=INPLACE; SHOW CREATE TABLE t1o; -DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign; +DROP TABLE t1c, t1p, sys_tables, sys_indexes; # Check the internal schemata of tt, t1o. @@ -368,8 +358,6 @@ CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1o'; CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; -CREATE TABLE sys_foreign SELECT i.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i WHERE FOR_NAME='test/t1o'; -- source suite/innodb/include/innodb_dict.inc @@ -393,7 +381,7 @@ INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; -- source suite/innodb/include/innodb_dict.inc -DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign; +DROP TABLE tt, t1o, sys_tables, sys_indexes; CREATE TABLE t (t TEXT, FULLTEXT(t)) ENGINE=InnoDB; DROP INDEX t ON t; @@ -455,10 +443,6 @@ SELECT F.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS F INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES T ON I.TABLE_ID=T.TABLE_ID WHERE T.NAME='test/t1' AND I.NAME='PRIMARY'; -SELECT C.REF_COL_NAME, C.FOR_COL_NAME FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS C INNER JOIN - INFORMATION_SCHEMA.INNODB_SYS_FOREIGN F ON C.ID=F.ID - WHERE F.FOR_NAME='test/t2'; - DROP TABLE t2, t1; --echo # virtual columns case too CREATE TABLE t1 (a INT, b INT GENERATED ALWAYS AS (a) VIRTUAL) ENGINE = InnoDB; diff --git a/mysql-test/suite/innodb/t/innodb-fk-warnings.test b/mysql-test/suite/innodb/t/innodb-fk-warnings.test index b0034f80345..9f3214eb5bc 100644 --- a/mysql-test/suite/innodb/t/innodb-fk-warnings.test +++ b/mysql-test/suite/innodb/t/innodb-fk-warnings.test @@ -1,35 +1,6 @@ --source include/have_innodb.inc # -# MDEV-8524: Improve error messaging when there is duplicate key or foreign key names -# -CREATE TABLE t1 ( - id int(11) NOT NULL PRIMARY KEY, - a int(11) NOT NULL, - b int(11) NOT NULL, - c int not null, - CONSTRAINT test FOREIGN KEY (b) REFERENCES t1 (id) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; - -# -# Below create table fails because constraint name test -# is reserved for above table. -# ---error ER_CANT_CREATE_TABLE -CREATE TABLE t2 ( - 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; - -show warnings; - -drop table t1; - -# # MDEV-6697: Improve foreign keys warnings/errors # @@ -49,12 +20,12 @@ show warnings; drop table t1; create table t1(a int not null primary key, b int) engine=innodb; ---error ER_CANT_CREATE_TABLE +--error ER_DUP_CONSTRAINT_NAME 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; ---error ER_CANT_CREATE_TABLE +--error ER_WRONG_FK_DEF alter table t2 add constraint b foreign key (b) references t2(b); show warnings; drop table t2, t1; @@ -115,7 +86,7 @@ drop table t1; # ON UPDATE/DELETE SET NULL on NOT NULL column # create table t1 (f1 integer not null primary key) engine=innodb; ---error ER_CANT_CREATE_TABLE +--error ER_WRONG_FK_DEF alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update set null; show warnings; --error ER_CANT_CREATE_TABLE diff --git a/mysql-test/suite/innodb/t/innodb-fk.test b/mysql-test/suite/innodb/t/innodb-fk.test index 09ec0727b9b..6157a429ff4 100644 --- a/mysql-test/suite/innodb/t/innodb-fk.test +++ b/mysql-test/suite/innodb/t/innodb-fk.test @@ -155,7 +155,7 @@ CREATE TABLE `kg_test2`.`person2` ( `Id` INT(11) NOT NULL AUTO_INCREMENT, `Name` VARCHAR(50) NOT NULL, PRIMARY KEY (`Id`), -CONSTRAINT `fk_person_group` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) +CONSTRAINT `fk_person_group2` FOREIGN KEY (`Id`) REFERENCES `kg_test1`.`group` (`Id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8; show create table `kg_test2`.`person2`; diff --git a/mysql-test/suite/innodb/t/innodb-fkcheck.test b/mysql-test/suite/innodb/t/innodb-fkcheck.test deleted file mode 100644 index 4657edc4d65..00000000000 --- a/mysql-test/suite/innodb/t/innodb-fkcheck.test +++ /dev/null @@ -1,116 +0,0 @@ ---source include/have_innodb.inc ---source include/default_charset.inc - -# -# MDEV-10083: Orphan ibd file when playing with foreign keys -# ---disable_query_log -SET @start_global_fpt = @@global.innodb_file_per_table; -SET @start_global_fkc = @@global.foreign_key_checks; ---enable_query_log - -set global innodb_file_per_table = 1; - ---disable_warnings -drop table if exists b; -drop database if exists bug_fk; ---enable_warnings - -let $MYSQLD_DATADIR = `select @@datadir`; - -create database bug_fk; -use bug_fk; - -CREATE TABLE b ( - b int unsigned NOT NULL, - d1 datetime NOT NULL, - PRIMARY KEY (b,d1) -) ENGINE=InnoDB; - -CREATE TABLE c ( - b int unsigned NOT NULL, - d1 datetime NOT NULL, - d2 datetime NOT NULL, - PRIMARY KEY (b,d1), - CONSTRAINT b_fk FOREIGN KEY (b) REFERENCES b (b) -) ENGINE=InnoDB; - -show warnings; - -set foreign_key_checks = 0; - -DROP TABLE IF EXISTS b; - -show create table c; - -# -# Note that column b has different type in parent table -# ---error 1005 -CREATE TABLE b ( - b bigint unsigned NOT NULL, - d1 date NOT NULL, - PRIMARY KEY (b,d1) -) ENGINE=InnoDB; - -show warnings; - -DROP TABLE IF EXISTS d; - -CREATE TABLE d ( - b bigint unsigned NOT NULL, - d1 date NOT NULL, - PRIMARY KEY (b,d1), - CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b) -) ENGINE=InnoDB; - -show warnings; - -set foreign_key_checks = 1; - -show create table c; -show create table d; - -# -# Table c column b used on foreign key has different type -# compared referenced column b in table b, but this -# create still produced b.ibd file. This is because -# we row_drop_table_for_mysql was called and referenced -# table is not allowed to be dropped even in case -# when actual create is not successfull. -# ---error 1005 -CREATE TABLE b ( - b bigint unsigned NOT NULL, - d1 date NOT NULL, - PRIMARY KEY (b,d1) -) ENGINE=InnoDB; - -show warnings; - ---list_files $MYSQLD_DATADIR/bug_fk b* - -set foreign_key_checks=0; - -drop table c; -drop table d; - ---list_files $MYSQLD_DATADIR/bug_fk b* - -create table b(id int) engine=innodb; -show warnings; - ---list_files $MYSQLD_DATADIR/bug_fk b* - -# -# Cleanup -# ---disable_query_log -SET @@global.innodb_file_per_table = @start_global_fpt; -SET @@global.foreign_key_checks = @start_global_fkc; ---enable_query_log - ---disable_warnings -drop table if exists b; -drop database if exists bug_fk; ---enable_warnings diff --git a/mysql-test/suite/innodb/t/innodb-index-online-fk.opt b/mysql-test/suite/innodb/t/innodb-index-online-fk.opt index 345d5529dce..24ad32542fe 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online-fk.opt +++ b/mysql-test/suite/innodb/t/innodb-index-online-fk.opt @@ -1,4 +1,2 @@ --loose-innodb-sys-tables --loose-innodb-sys-columns ---loose-innodb-sys-foreign ---loose-innodb-sys-foreign-cols diff --git a/mysql-test/suite/innodb/t/innodb-index-online-fk.test b/mysql-test/suite/innodb/t/innodb-index-online-fk.test index 5c8954064ce..e80fb507f68 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online-fk.test +++ b/mysql-test/suite/innodb/t/innodb-index-online-fk.test @@ -24,10 +24,6 @@ ALTER TABLE child ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; - -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; - # duplicated foreign key name --error ER_DUP_CONSTRAINT_NAME ALTER TABLE child ADD CONSTRAINT fk_1 FOREIGN KEY (a2) @@ -69,10 +65,6 @@ ALGORITHM = INPLACE; ALTER TABLE child ADD CONSTRAINT fk_3 FOREIGN KEY (a1, a2) REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; - -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; - SET foreign_key_checks = 1; --error ER_NO_REFERENCED_ROW_2 @@ -99,10 +91,6 @@ REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ALGORITHM = INPLACE; SET DEBUG_DBUG = @saved_debug_dbug; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; - -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; - SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; SELECT NAME FROM information_schema.INNODB_SYS_TABLES; @@ -137,10 +125,6 @@ SET DEBUG_DBUG = @saved_debug_dbug; SHOW ERRORS; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; - -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; - # This is to test the scenario no index on referenced table, # alter table should fail SET DEBUG_DBUG = '+d,innodb_test_no_reference_idx'; @@ -161,19 +145,6 @@ REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ALGORITHM = INPLACE; SET DEBUG_DBUG = @saved_debug_dbug; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; - -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; - -# This is to test the scenario cannot add fk to the system table, -# alter table should fail -SET DEBUG_DBUG = '+d,innodb_test_cannot_add_fk_system'; ---error ER_FK_FAIL_ADD_SYSTEM -ALTER TABLE `#child` ADD CONSTRAINT fk_43 FOREIGN KEY (a1, a2) -REFERENCES `#parent`(a, b) ON DELETE CASCADE ON UPDATE CASCADE, -ALGORITHM = INPLACE; -SET DEBUG_DBUG = @saved_debug_dbug; - SHOW ERRORS; DROP TABLE `#child`; @@ -188,10 +159,6 @@ ADD CONSTRAINT fk_6 FOREIGN KEY (a1, a2) REFERENCES parent(a, b) ON DELETE CASCADE ON UPDATE CASCADE, ALGORITHM = INPLACE; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; - -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; - DROP TABLE child; DROP TABLE parent; @@ -220,10 +187,6 @@ ALGORITHM = INPLACE; SHOW CREATE TABLE child; -SELECT * FROM information_schema.INNODB_SYS_FOREIGN; - -SELECT * FROM information_schema.INNODB_SYS_FOREIGN_COLS; - SET foreign_key_checks = 1; DROP TABLE child; @@ -274,18 +237,8 @@ CREATE INDEX tb ON child(a2); SET foreign_key_checks = 0; -# Let's rebuild the table and add the FK, make the add FK failed. +# Let's rebuild the table and add the FK -SET DEBUG_DBUG = '+d,innodb_test_cannot_add_fk_system'; ---error ER_FK_FAIL_ADD_SYSTEM -ALTER TABLE child ADD PRIMARY KEY idx (a3), CHANGE a1 a3 INT, -ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b) -ON DELETE SET NULL ON UPDATE CASCADE, -ALGORITHM = INPLACE; -SET DEBUG_DBUG = @saved_debug_dbug; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; SELECT NAME FROM information_schema.INNODB_SYS_TABLES; @@ -297,8 +250,6 @@ ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; SELECT NAME FROM information_schema.INNODB_SYS_TABLES; @@ -314,8 +265,6 @@ ADD CONSTRAINT fk_1 FOREIGN KEY (a2) REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; -SELECT * from information_schema.INNODB_SYS_FOREIGN; -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; SELECT NAME FROM information_schema.INNODB_SYS_TABLES; @@ -330,8 +279,6 @@ ADD CONSTRAINT fk_1 FOREIGN KEY (a3) REFERENCES parent(b) ON DELETE SET NULL ON UPDATE CASCADE, ALGORITHM = INPLACE; -SELECT * from information_schema.INNODB_SYS_FOREIGN; -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; SELECT t2.name, t1.name FROM information_schema.innodb_sys_columns t1, information_schema.innodb_sys_tables t2 WHERE t1.table_id = t2.table_id AND t2.name LIKE "%child" ORDER BY t1.name; SELECT NAME FROM information_schema.INNODB_SYS_TABLES; @@ -371,9 +318,6 @@ ALTER TABLE child CHANGE a2 a2_new INT, CHANGE a1 a1_new INT; SHOW CREATE TABLE child; -SELECT * from information_schema.INNODB_SYS_FOREIGN; -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; - # The third add FK will fail --error ER_FK_NO_INDEX_PARENT ALTER TABLE child @@ -385,10 +329,6 @@ ALGORITHM = INPLACE; # It should still have only 2 FKs SHOW CREATE TABLE child; -SELECT * from information_schema.INNODB_SYS_FOREIGN; - -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; - #Now let's make it successful ALTER TABLE child ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1_new) REFERENCES parent(b), @@ -399,10 +339,6 @@ ALGORITHM = INPLACE; # It should still have 5 FKs SHOW CREATE TABLE child; -SELECT * from information_schema.INNODB_SYS_FOREIGN; - -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; - DROP TABLE child; CREATE TABLE child (a1 INT NOT NULL, a2 INT, a3 INT) ENGINE = InnoDB; CREATE INDEX tb ON child(a2); @@ -418,10 +354,6 @@ ALGORITHM = INPLACE; # It should still have no FKs, no PRIMARY SHOW CREATE TABLE child; -SELECT * from information_schema.INNODB_SYS_FOREIGN; - -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; - # make it successful ALTER TABLE child ADD PRIMARY KEY idx (a1), ADD CONSTRAINT fk_new_1 FOREIGN KEY (a1) REFERENCES parent(b), @@ -432,10 +364,6 @@ ALGORITHM = INPLACE; # It should have 3 FKs, a new PRIMARY SHOW CREATE TABLE child; -SELECT * from information_schema.INNODB_SYS_FOREIGN; - -SELECT * from information_schema.INNODB_SYS_FOREIGN_COLS; - SET foreign_key_checks = 1; DROP TABLE child; @@ -473,12 +401,6 @@ ALTER TABLE `t2` ADD CONSTRAINT `fw` FOREIGN KEY (`c`) REFERENCES t3 (a); ALTER TABLE `t2` ADD CONSTRAINT `e` foreign key (`d`) REFERENCES t3(a); ---error ER_FK_FAIL_ADD_SYSTEM -ALTER TABLE `t3` ADD CONSTRAINT `e` foreign key (`c`) REFERENCES `t2`(`c`) ON UPDATE SET NULL; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; - DROP TABLE t2; DROP TABLE t3; diff --git a/mysql-test/suite/innodb/t/innodb-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test index 5e21fa896a4..17bb3aa3163 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online.test +++ b/mysql-test/suite/innodb/t/innodb-index-online.test @@ -84,7 +84,7 @@ DELETE FROM t1 WHERE c1 = 7; connection con1; # ADD FOREIGN KEY is not supported in-place --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON -ALTER TABLE t1 ADD FOREIGN KEY(c2) REFERENCES t1(c2), ALGORITHM = INPLACE; +ALTER TABLE t1 ADD FOREIGN KEY(c1) REFERENCES t1(c2), ALGORITHM = INPLACE; # The previous DEBUG_SYNC should be ignored, because an exclusive lock # has been requested and the online log is not being allocated. ALTER TABLE t1 ADD UNIQUE INDEX(c2), LOCK = EXCLUSIVE, ALGORITHM = INPLACE; diff --git a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test index 810671c54c8..b0fb0769c43 100644 --- a/mysql-test/suite/innodb/t/innodb-index.test +++ b/mysql-test/suite/innodb/t/innodb-index.test @@ -221,10 +221,10 @@ show create table t4; # Embedded server doesn't chdir to data directory --replace_result $MYSQLD_DATADIR ./ master-data/ '' # a foreign key 'test/dc' already exists ---error ER_CANT_CREATE_TABLE +--error ER_DUP_CONSTRAINT_NAME alter table t3 add constraint dc foreign key (a) references t1(a); SET FOREIGN_KEY_CHECKS=0; ---error ER_FK_FAIL_ADD_SYSTEM +--error ER_DUP_CONSTRAINT_NAME alter table t3 add constraint dc foreign key (a) references t1(a); SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; show create table t3; diff --git a/mysql-test/suite/innodb/t/innodb-system-table-view.opt b/mysql-test/suite/innodb/t/innodb-system-table-view.opt index 4d6858cbe0b..371d5d7a333 100644 --- a/mysql-test/suite/innodb/t/innodb-system-table-view.opt +++ b/mysql-test/suite/innodb/t/innodb-system-table-view.opt @@ -6,7 +6,5 @@ --innodb-sys-columns --innodb-sys-indexes --innodb-sys-fields ---innodb-sys-foreign ---innodb-sys-foreign-cols --character_set_server="latin1" --collation_server="latin1_swedish_ci" diff --git a/mysql-test/suite/innodb/t/innodb-system-table-view.test b/mysql-test/suite/innodb/t/innodb-system-table-view.test index 4f5111eafbc..e817fd4f672 100644 --- a/mysql-test/suite/innodb/t/innodb-system-table-view.test +++ b/mysql-test/suite/innodb/t/innodb-system-table-view.test @@ -33,11 +33,6 @@ SELECT index_id,pos,name FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS WHERE name NOT IN ('database_name', 'table_name', 'index_name', 'stat_name') ORDER BY index_id, pos; ---sorted_result -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; ---sorted_result -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; - CREATE TABLE t_redundant (a INT KEY, b TEXT) ROW_FORMAT=REDUNDANT ENGINE=innodb; CREATE TABLE t_compact (a INT KEY, b TEXT) ROW_FORMAT=COMPACT ENGINE=innodb; CREATE TABLE t_compressed (a INT KEY, b TEXT) ROW_FORMAT=COMPRESSED ENGINE=innodb KEY_BLOCK_SIZE=2; @@ -51,8 +46,6 @@ DROP TABLE t_redundant, t_compact, t_compressed, t_dynamic; SELECT count(*) FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS; # Create a foreign key constraint, and verify the information -# in INFORMATION_SCHEMA.INNODB_SYS_FOREIGN and -# INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS CREATE TABLE parent (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; @@ -62,12 +55,6 @@ CREATE TABLE child (id INT, parent_id INT, FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE) ENGINE=INNODB; ---sorted_result -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; - ---sorted_result -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; - # Insert a row in the table "parent", and see whether that reflected in # INNODB_SYS_TABLESTATS INSERT INTO parent VALUES(1); @@ -118,12 +105,6 @@ CREATE TABLE child (id INT, parent_id INT, FOREIGN KEY (id, parent_id) REFERENCES parent(id, newid) ON DELETE CASCADE) ENGINE=INNODB; ---sorted_result -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; - ---sorted_result -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; - INSERT INTO parent VALUES(1, 9); # Nested query will open the table handle twice diff --git a/mysql-test/suite/innodb/t/innodb-truncate.test b/mysql-test/suite/innodb/t/innodb-truncate.test index 78e3862a909..5413b36b956 100644 --- a/mysql-test/suite/innodb/t/innodb-truncate.test +++ b/mysql-test/suite/innodb/t/innodb-truncate.test @@ -83,8 +83,6 @@ SET FOREIGN_KEY_CHECKS= OFF; CREATE TABLE t1 (f2 INT, f4 INT, KEY(f2), FOREIGN KEY (f4) REFERENCES t3 (f4)) ENGINE=InnoDB; 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_NO_SUCH_TABLE ALTER TABLE t1 RENAME TO t3; diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-alter.test b/mysql-test/suite/innodb/t/innodb-wl5980-alter.test index 1a32b94c140..3c0e1761ecf 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5980-alter.test +++ b/mysql-test/suite/innodb/t/innodb-wl5980-alter.test @@ -38,13 +38,6 @@ eval CREATE TABLE t1c (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX(c2), INDEX(c3), CONSTRAINT t1c3 FOREIGN KEY (c3) REFERENCES t1p(c2)) ENGINE=InnoDB $data_directory_clause; -CREATE TABLE sys_foreign SELECT i.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i -WHERE FOR_NAME LIKE 'test/t%'; - -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; - -- source suite/innodb/include/innodb_dict.inc --replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR @@ -126,9 +119,6 @@ ALTER TABLE t1 CHANGE C Cöŀumň_TWO INT; --cat_file $MYSQL_DATA_DIR.files.txt --remove_file $MYSQL_DATA_DIR.files.txt -SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS i -INNER JOIN sys_foreign sf ON i.ID = sf.ID; - -- source suite/innodb/include/innodb_dict.inc -- error ER_BAD_FIELD_ERROR @@ -638,7 +628,7 @@ DROP INDEX ct, LOCK=NONE; --replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR SHOW CREATE TABLE t1o; -DROP TABLE t1c, t1p, sys_tables, sys_indexes, sys_foreign; +DROP TABLE t1c, t1p, sys_tables, sys_indexes; # Check the internal schemata of tt, t1o. @@ -646,8 +636,6 @@ CREATE TABLE sys_tables SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1o'; CREATE TABLE sys_indexes SELECT i.* FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES i INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; -CREATE TABLE sys_foreign SELECT i.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN i WHERE FOR_NAME='test/t1o'; -- source suite/innodb/include/innodb_dict.inc @@ -693,7 +681,7 @@ INNER JOIN sys_tables st ON i.TABLE_ID=st.TABLE_ID; --echo # Cleanup --echo # -DROP TABLE tt, t1o, sys_tables, sys_indexes, sys_foreign; +DROP TABLE tt, t1o, sys_tables, sys_indexes; --echo ### files in MYSQL_DATA_DIR/test --list_files_write_file $MYSQL_DATA_DIR.files.txt $MYSQL_DATA_DIR/test diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index 95145bd8eeb..d15d43ef19c 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -1598,12 +1598,12 @@ disconnect b; set foreign_key_checks=0; create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; -# Embedded server doesn't chdir to data directory ---replace_result $MYSQLTEST_VARDIR . master-data/ '' ---error ER_CANT_CREATE_TABLE create table t1(a char(10) primary key, b varchar(20)) engine = innodb; set foreign_key_checks=1; -drop table t2; +insert into t1 values (1, 1); +--error ER_NO_REFERENCED_ROW_2 +insert into t2 values (1, 1); +drop tables t2, t1; # test that FKs between different charsets are not accepted in CREATE even # when f_k_c is 0 @@ -1617,15 +1617,6 @@ create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innod set foreign_key_checks=1; drop table t1; -# test that invalid datatype conversions with ALTER are not allowed - -set foreign_key_checks=0; -create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb; -create table t1(a varchar(10) primary key) engine = innodb; -alter table t1 modify column a int; -set foreign_key_checks=1; -drop table t2,t1; - # test that charset conversions with ALTER are allowed when f_k_c is 0 set foreign_key_checks=0; @@ -1635,19 +1626,6 @@ alter table t1 convert to character set utf8; set foreign_key_checks=1; drop table t2,t1; -# test that RENAME does not allow invalid charsets when f_k_c is 0 - -call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`.`t1` has or is referenced in foreign key constraints which are not compatible with the new table definition."); -set foreign_key_checks=0; -create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; -create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; -# Embedded server doesn't chdir to data directory ---replace_result $MYSQLD_DATADIR ./ master-data/ '' --- error 1025 -rename table t3 to t1; -set foreign_key_checks=1; -drop table t2,t3; - # test that foreign key errors are reported correctly (Bug #15550) create table t1(a int primary key) row_format=redundant engine=innodb; diff --git a/mysql-test/suite/innodb/t/innodb_bug12902967.test b/mysql-test/suite/innodb/t/innodb_bug12902967.test deleted file mode 100644 index 5bd32cdf627..00000000000 --- a/mysql-test/suite/innodb/t/innodb_bug12902967.test +++ /dev/null @@ -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-alter-[0-9a-f_\-]*'/'#sql-alter'/ ---error ER_ERROR_ON_RENAME -alter table t1 add constraint c1 foreign key (f1) references t1(f1); -drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb_bug21704.test b/mysql-test/suite/innodb/t/innodb_bug21704.test index 82e7c81d0e4..588bab03bc8 100644 --- a/mysql-test/suite/innodb/t/innodb_bug21704.test +++ b/mysql-test/suite/innodb/t/innodb_bug21704.test @@ -65,12 +65,6 @@ SHOW CREATE TABLE t1; SHOW CREATE TABLE t2; SHOW CREATE TABLE t3; -SELECT f.*, c.* -FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS c -INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_FOREIGN f -ON c.ID=f.ID -WHERE FOR_NAME LIKE 'test/t%'; - DROP TABLE t3; DROP TABLE t2; DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_bug57255.test b/mysql-test/suite/innodb/t/innodb_bug57255.test index cf7982a6ddf..0b0d3506344 100644 --- a/mysql-test/suite/innodb/t/innodb_bug57255.test +++ b/mysql-test/suite/innodb/t/innodb_bug57255.test @@ -36,3 +36,5 @@ DELETE FROM A where id = 1; DROP TABLE C; DROP TABLE B; DROP TABLE A; + +flush tables; diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt index 9f30d81ef9c..87d83110b19 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt +++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt @@ -15,8 +15,6 @@ --loose-innodb_sys_indexes --loose-innodb_sys_columns --loose-innodb_sys_fields ---loose-innodb_sys_foreign ---loose-innodb_sys_foreign_cols --loose-innodb_changed_pages --loose-innodb_rseg --loose-innodb_undo_logs diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test index 15b3bf4f561..7a6ab7a9e4e 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test +++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test @@ -35,10 +35,6 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS; --error 0,1109 SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS; --error 0,1109 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; ---error 0,1109 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; ---error 0,1109 SELECT * FROM INFORMATION_SCHEMA.INNODB_RSEG; --error 0,1109 SELECT * FROM INFORMATION_SCHEMA.INNODB_UNDO_LOGS; diff --git a/mysql-test/suite/innodb/t/innodb_skip_innodb_is_tables.opt b/mysql-test/suite/innodb/t/innodb_skip_innodb_is_tables.opt index 513791a0a88..4a1d3c0a9f2 100644 --- a/mysql-test/suite/innodb/t/innodb_skip_innodb_is_tables.opt +++ b/mysql-test/suite/innodb/t/innodb_skip_innodb_is_tables.opt @@ -23,8 +23,6 @@ --loose-innodb_sys_indexes --loose-innodb_sys_columns --loose-innodb_sys_fields ---loose-innodb_sys_foreign ---loose-innodb_sys_foreign_cols --loose-innodb_sys_tablespaces --loose-innodb_sys_datafiles --loose-innodb_changed_pages @@ -53,8 +51,6 @@ --loose-innodb_sys_indexes --loose-innodb_sys_columns --loose-innodb_sys_fields ---loose-innodb_sys_foreign ---loose-innodb_sys_foreign_cols --loose-innodb_sys_tablespaces --loose-innodb_sys_datafiles --loose-innodb_changed_pages diff --git a/mysql-test/suite/innodb/t/innodb_skip_innodb_is_tables.test b/mysql-test/suite/innodb/t/innodb_skip_innodb_is_tables.test index a5d5d3fe34e..f466e320682 100644 --- a/mysql-test/suite/innodb/t/innodb_skip_innodb_is_tables.test +++ b/mysql-test/suite/innodb/t/innodb_skip_innodb_is_tables.test @@ -25,8 +25,6 @@ select * from information_schema.innodb_sys_tablestats; select * from information_schema.innodb_sys_indexes; select * from information_schema.innodb_sys_columns; select * from information_schema.innodb_sys_fields; -select * from information_schema.innodb_sys_foreign; -select * from information_schema.innodb_sys_foreign_cols; select * from information_schema.innodb_sys_tablespaces; select * from information_schema.innodb_sys_datafiles; --error 0,1109 diff --git a/mysql-test/suite/innodb/t/instant_alter_index_rename.test b/mysql-test/suite/innodb/t/instant_alter_index_rename.test index 3f5234b46f6..051ac02c27f 100644 --- a/mysql-test/suite/innodb/t/instant_alter_index_rename.test +++ b/mysql-test/suite/innodb/t/instant_alter_index_rename.test @@ -192,7 +192,7 @@ drop table rename_column_and_index; create table t1 (f1 int, f2 int, f3 int); create table t2 (f2 int primary key); alter table t1 add foreign key f (f2) references t2(f2); -alter table t1 add foreign key (f2) references t1(f2), add key (f3), add key (f1); +alter table t1 add foreign key (f1) references t1(f2), add key (f3), add key (f1); drop tables t1, t2; --echo # diff --git a/mysql-test/suite/innodb/t/truncate_foreign.test b/mysql-test/suite/innodb/t/truncate_foreign.test index d9d647e69f0..31a29291a64 100644 --- a/mysql-test/suite/innodb/t/truncate_foreign.test +++ b/mysql-test/suite/innodb/t/truncate_foreign.test @@ -53,11 +53,12 @@ send INSERT INTO child SET a=5; connection default; SET DEBUG_SYNC='now WAIT_FOR fk'; SET foreign_key_checks=0; +# NB: child now prelocks parent +--error ER_LOCK_WAIT_TIMEOUT TRUNCATE TABLE parent; SET DEBUG_SYNC='now SIGNAL go'; connection dml; ---error ER_NO_REFERENCED_ROW_2 reap; SELECT * FROM parent; SELECT * FROM child; diff --git a/mysql-test/suite/innodb/t/undo_truncate.test b/mysql-test/suite/innodb/t/undo_truncate.test index b4c8e46150b..6fd08947a1f 100644 --- a/mysql-test/suite/innodb/t/undo_truncate.test +++ b/mysql-test/suite/innodb/t/undo_truncate.test @@ -84,7 +84,7 @@ drop PROCEDURE populate_t2; # Truncation will normally not occur with innodb_page_size=64k, # and occasionally not with innodb_page_size=32k, # because the undo log will not grow enough. -if (`select @@innodb_page_size IN (4096,8192,16384)`) +if (`select @@innodb_page_size IN (8192,16384)`) { let $wait_condition = (SELECT variable_value!=@trunc_start FROM information_schema.global_status @@ -109,7 +109,7 @@ EOF if ($size1 == $size2) { # This fails for innodb_page_size=64k, occasionally also for 32k. - if (`select @@innodb_page_size IN (4096,8192,16384)`) + if (`select @@innodb_page_size IN (8192,16384)`) { echo Truncation did not happen: $size1; } diff --git a/mysql-test/suite/innodb_i_s/innodb_sys_foreign.result b/mysql-test/suite/innodb_i_s/innodb_sys_foreign.result deleted file mode 100644 index 8dc7cbb2c53..00000000000 --- a/mysql-test/suite/innodb_i_s/innodb_sys_foreign.result +++ /dev/null @@ -1,9 +0,0 @@ -SHOW CREATE TABLE INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -Table Create Table -INNODB_SYS_FOREIGN CREATE TEMPORARY TABLE `INNODB_SYS_FOREIGN` ( - `ID` varchar(193) NOT NULL DEFAULT '', - `FOR_NAME` varchar(193) NOT NULL DEFAULT '', - `REF_NAME` varchar(193) NOT NULL DEFAULT '', - `N_COLS` int(11) unsigned NOT NULL DEFAULT 0, - `TYPE` int(11) unsigned NOT NULL DEFAULT 0 -) ENGINE=MEMORY DEFAULT CHARSET=utf8 diff --git a/mysql-test/suite/innodb_i_s/innodb_sys_foreign.test b/mysql-test/suite/innodb_i_s/innodb_sys_foreign.test deleted file mode 100644 index 694a773392e..00000000000 --- a/mysql-test/suite/innodb_i_s/innodb_sys_foreign.test +++ /dev/null @@ -1,3 +0,0 @@ ---source include/have_innodb.inc - -SHOW CREATE TABLE INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; diff --git a/mysql-test/suite/innodb_i_s/innodb_sys_foreign_cols.result b/mysql-test/suite/innodb_i_s/innodb_sys_foreign_cols.result deleted file mode 100644 index 8f1134fb36d..00000000000 --- a/mysql-test/suite/innodb_i_s/innodb_sys_foreign_cols.result +++ /dev/null @@ -1,8 +0,0 @@ -SHOW CREATE TABLE INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -Table Create Table -INNODB_SYS_FOREIGN_COLS CREATE TEMPORARY TABLE `INNODB_SYS_FOREIGN_COLS` ( - `ID` varchar(193) NOT NULL DEFAULT '', - `FOR_COL_NAME` varchar(64) NOT NULL DEFAULT '', - `REF_COL_NAME` varchar(64) NOT NULL DEFAULT '', - `POS` int(11) unsigned NOT NULL DEFAULT 0 -) ENGINE=MEMORY DEFAULT CHARSET=utf8 diff --git a/mysql-test/suite/innodb_i_s/innodb_sys_foreign_cols.test b/mysql-test/suite/innodb_i_s/innodb_sys_foreign_cols.test deleted file mode 100644 index 6afccfc212f..00000000000 --- a/mysql-test/suite/innodb_i_s/innodb_sys_foreign_cols.test +++ /dev/null @@ -1,3 +0,0 @@ ---source include/have_innodb.inc - -SHOW CREATE TABLE INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 95dcbf157d3..5689f4d4d7c 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -4764,21 +4764,15 @@ ER_INCORRECT_GLOBAL_LOCAL_VAR spa "Variable '%-.192s' es una %s variable" swe "Variabel '%-.192s' är av typ %s" ER_WRONG_FK_DEF 42000 - eng "Incorrect foreign key definition for '%-.192s': %s" - ger "Falsche Fremdschlüssel-Definition für '%-.192s': %s" - jpn "外部キー '%-.192s' の定義の不正: %s" - nla "Incorrecte foreign key definitie voor '%-.192s': %s" - por "Definição errada da chave estrangeira para '%-.192s': %s" - spa "Equivocada definición de llave extranjera para '%-.192s': %s" - swe "Felaktig FOREIGN KEY-definition för '%-.192s': %s" -ER_KEY_REF_DO_NOT_MATCH_TABLE_REF - eng "Key reference and table reference don't match" - ger "Schlüssel- und Tabellenverweis passen nicht zusammen" - jpn "外部キーの参照表と定義が一致しません。" - nla "Sleutel- en tabelreferentie komen niet overeen" - por "Referência da chave e referência da tabela não coincidem" - spa "Referencia de llave y referencia de tabla no coinciden" - swe "Nyckelreferensen och tabellreferensen stämmer inte överens" + eng "Incorrect foreign key definition for '%-.192s'" + ger "Falsche Fremdschlüssel-Definition für '%-.192s'" + jpn "外部キー '%-.192s' の定義の不正" + nla "Incorrecte foreign key definitie voor '%-.192s'" + por "Definição errada da chave estrangeira para '%-.192s'" + spa "Equivocada definición de llave extranjera para '%-.192s'" + swe "Felaktig FOREIGN KEY-definition för '%-.192s'" +ER_UNUSED_27 + eng "You should never see it" ER_OPERAND_COLUMNS 21000 eng "Operand should contain %d column(s)" ger "Operand sollte %d Spalte(n) enthalten" @@ -6925,8 +6919,8 @@ ER_FK_NO_INDEX_CHILD ER_FK_NO_INDEX_PARENT eng "Failed to add the foreign key constaint. Missing index for constraint '%s' in the referenced table '%s'" -ER_FK_FAIL_ADD_SYSTEM - eng "Failed to add the foreign key constraint '%s' to system tables" +ER_UNUSED_26 + eng "You should never see it" ER_FK_CANNOT_OPEN_PARENT eng "Failed to open the referenced table '%s'" diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 77831615a8b..a7198483d2c 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -431,8 +431,10 @@ public: bool fk_prepare_rename(THD *thd, TABLE *table, Create_field *def, mbd::set<FK_table_to_lock> &fk_tables_to_lock); bool fk_handle_alter(THD *thd); + bool fk_check_foreign_id(THD *thd); void fk_release_locks(THD *thd); + // Backup for the table we altering. NB: auto-rollback if not committed. FK_table_backup fk_table_backup; // NB: share is owned and released by fk_shares mbd::map<TABLE_SHARE *, FK_ref_backup> fk_ref_backup; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index bf2e639155b..6902f7ebedb 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2015,6 +2015,55 @@ retry_share: tc_add_table(thd, table); } + if (table_list->prelocking_placeholder == TABLE_LIST::PRELOCK_RK) + { + bool share_updated= false; + for (TABLE_LIST *tbl= thd->lex->query_tables; tbl != table_list; tbl= tbl->next_global) + { + DBUG_ASSERT(tbl != NULL); + if (!tbl->table) + continue; + if (tbl->table->s == table->s) + continue; // skip self-references + for (FK_info &fk: tbl->table->s->foreign_keys) + { + if (0 != cmp_table(fk.ref_db(), table_list->db) || + 0 != cmp_table(fk.referenced_table, table_list->table_name)) + continue; + + bool ref_found= false; + + for (FK_info &rk: table->s->referenced_keys) + { + if (0 != cmp_table(rk.foreign_db, tbl->db) || + 0 != cmp_table(rk.foreign_table, tbl->table_name)) + continue; + // NB: rk can be not resolved (see GTS_FK_SHALLOW_HINTS) + if (rk.foreign_fields.elements > 0) + ref_found= true; + break; + } + + if (!ref_found) + { + if (table->s->fk_resolve_referenced_keys(thd, tbl->table->s)) + goto err_lock; + share_updated= true; + break; + } + } + } + if (share_updated) + { + table->file->unbind_psi(); + table->internal_set_needs_reopen(true); + tc_release_table(table); + (void) ot_ctx->request_backoff_action(Open_table_context::OT_REOPEN_TABLES, + NULL); + DBUG_RETURN(TRUE); + } + } + if (!(flags & MYSQL_OPEN_HAS_MDL_LOCK) && table->s->table_category < TABLE_CATEGORY_INFORMATION) { @@ -4514,7 +4563,21 @@ bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db, for (; tl; tl= tl->next_global ) { if (tl->lock_type >= lock_type && - tl->prelocking_placeholder == TABLE_LIST::PRELOCK_FK && + tl->prelocking_placeholder >= TABLE_LIST::PRELOCK_FK && + strcmp(tl->db.str, db->str) == 0 && + strcmp(tl->table_name.str, table->str) == 0) + return true; + } + return false; +} + + +bool table_already_prelocked(TABLE_LIST *tl, LEX_CSTRING *db, + LEX_CSTRING *table, thr_lock_type lock_type) +{ + for (; tl; tl= tl->next_global ) + { + if (tl->lock_type >= lock_type && strcmp(tl->db.str, db->str) == 0 && strcmp(tl->table_name.str, table->str) == 0) return true; @@ -4647,8 +4710,9 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, *need_prelocking= TRUE; TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST)); - tl->init_one_table_for_prelocking(&fk->foreign_db, - &fk->foreign_table, + Table_name for_table= fk->for_table(thd->mem_root); + tl->init_one_table_for_prelocking(&for_table.db, + &for_table.name, NULL, lock_type, TABLE_LIST::PRELOCK_FK, table_list->belong_to_view, op, @@ -4658,6 +4722,42 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, if (arena) thd->restore_active_arena(arena, &backup); } + + if (table->s->foreign_keys.elements && table->s->table_category != TABLE_CATEGORY_SYSTEM) + { + List_iterator<FK_info> fk_list_it(table->s->foreign_keys); + FK_info *fk; + Query_arena *arena, backup; + + arena= thd->activate_stmt_arena_if_needed(&backup); + + while ((fk= fk_list_it++)) + { + uint8 op= table_list->trg_event_map; + thr_lock_type lock_type; + lock_type= TL_READ; + + if (table_already_prelocked(prelocking_ctx->query_tables, + fk->ref_db_ptr(), &fk->referenced_table, + lock_type)) + continue; + + *need_prelocking= TRUE; + + + TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST)); + Table_name ref_table= fk->ref_table(thd->mem_root); + tl->init_one_table_for_prelocking(&ref_table.db, + &ref_table.name, + NULL, lock_type, + TABLE_LIST::PRELOCK_RK, + table_list->belong_to_view, op, + &prelocking_ctx->query_tables_last, + table_list->for_insert_data); + } + if (arena) + thd->restore_active_arena(arena, &backup); + } } /* Open any tables used by DEFAULT (like sequence tables) */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index fd4c2ab0853..4446cd0e83e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -288,22 +288,41 @@ bool foreign_key_prefix(Key *a, Key *b) /* @brief Check if the foreign key options are compatible with the specification - of the columns on which the key is created + of the columns on which the key is created. + + Check self-references for self-column pointing. @retval FALSE The foreign key options are compatible with key columns @retval TRUE Otherwise */ -bool Foreign_key::validate(List<Create_field> &table_fields) +bool Foreign_key::validate(const LEX_CSTRING &db, const LEX_CSTRING &table_name, + List<Create_field> &table_fields, bool &self_ref) { Create_field *sql_field; - Key_part_spec *column; - List_iterator<Key_part_spec> cols(columns); - List_iterator<Create_field> it(table_fields); + Key_part_spec *column, *rcol; + List_iterator_fast<Key_part_spec> cols(columns); + List_iterator_fast<Key_part_spec> rcols(ref_columns); + List_iterator_fast<Create_field> it(table_fields); + // NB: self-references may have no ref_table + self_ref= !ref_table.str || ((!ref_db.str || 0 == cmp_table(db, ref_db)) && + 0 == cmp_table(table_name, ref_table)); DBUG_ENTER("Foreign_key::validate"); + const char *nam= constraint_name.str ? constraint_name.str : name.str; + if (columns.elements != ref_columns.elements) + { + my_error(ER_WRONG_FK_DEF, MYF(0), (nam ? nam : "foreign key without name")); + DBUG_RETURN(TRUE); + } while ((column= cols++)) { + rcol= rcols++; + if (self_ref && 0 == cmp_ident(column->field_name, rcol->field_name)) + { + my_error(ER_WRONG_FK_DEF, MYF(0), (nam ? nam : rcol->field_name.str)); + DBUG_RETURN(TRUE); + } it.rewind(); while ((sql_field= it++) && lex_string_cmp(system_charset_info, @@ -6201,7 +6220,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) replicated_tables_count++; - if (tbl->prelocking_placeholder != TABLE_LIST::PRELOCK_FK) + if (tbl->prelocking_placeholder < TABLE_LIST::PRELOCK_FK) { if (tbl->lock_type <= TL_READ_NO_INSERT) has_read_tables= true; diff --git a/sql/sql_class.h b/sql/sql_class.h index 5328031df22..99c5e132061 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -369,12 +369,16 @@ public: { auto ret= exception_wrapper<std::set<Key, Compare, Allocator> >:: insert(value); + if (ret == std::set<Key, Compare, Allocator>::end()) + return NULL; return &*ret; } const Key* insert(Key&& value) { auto ret= exception_wrapper<std::set<Key, Compare, Allocator> >:: insert(std::forward<Key>(value)); + if (ret == std::set<Key, Compare, Allocator>::end()) + return NULL; return &*ret; } }; @@ -447,6 +451,11 @@ public: } return false; } + // NB: needed for std::set + bool operator<(const Table_name &rhs) const + { + return cmp(rhs) < 0; + } }; /* @@ -678,7 +687,8 @@ public: virtual Key *clone(MEM_ROOT *mem_root) const { return new (mem_root) Foreign_key(*this, mem_root); } /* Used to validate foreign key options */ - bool validate(List<Create_field> &table_fields); + bool validate(const LEX_CSTRING &db, const LEX_CSTRING &table_name, + List<Create_field> &table_fields, bool &self_ref); }; typedef struct st_mysql_lock diff --git a/sql/sql_table.cc b/sql/sql_table.cc index fbc7c335e7a..16b39f2f95b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3834,17 +3834,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (key->foreign) { Foreign_key *fk_key= (Foreign_key*) key; - if (!fk_key->ignore && fk_key->validate(alter_info->create_list)) + bool self_ref; + if (!fk_key->ignore && fk_key->validate(db, table_name, alter_info->create_list, self_ref)) DBUG_RETURN(TRUE); - if (fk_key->ref_columns.elements && - fk_key->ref_columns.elements != fk_key->columns.elements) - { - my_error(ER_WRONG_FK_DEF, MYF(0), - (fk_key->name.str ? fk_key->name.str : - "foreign key without name"), - ER_THD(thd, ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); - DBUG_RETURN(TRUE); - } } (*key_count)++; tmp=file->max_key_parts(); @@ -3930,11 +3922,16 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (key->foreign) { FK_info *fk_info= new (thd->mem_root) FK_info(); - fk_info->assign(*(Foreign_key *) key, {db, table_name}); + Foreign_key &fkey= static_cast<Foreign_key &>(*key); + fk_info->assign(fkey, {db, table_name}); if (!fk_info->foreign_id.str) + { fk_info->foreign_id= make_unique_key_name(thd, table_name, key_names, true); - foreign_keys.push_back(fk_info); + fkey.constraint_name= fk_info->foreign_id; + } + if (foreign_keys.push_back(fk_info)) + DBUG_RETURN(TRUE); if (!key_names.insert(fk_info->foreign_id)) DBUG_RETURN(TRUE); // Out of memory } @@ -4314,10 +4311,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } else if (key->foreign) { - Foreign_key *fkey= static_cast<Foreign_key *>(key); - key_name= fkey->constraint_name.str ? fkey->constraint_name : key->name; + Foreign_key &fkey= static_cast<Foreign_key &>(*key); + key_name= fkey.constraint_name.str ? fkey.constraint_name : key->name; if (!key_name.str) + { key_name= make_unique_key_name(thd, table_name, key_names, true); + fkey.constraint_name= key_name; + } } else if (!(key_name= key->name).str) key_name= make_unique_key_name(thd, sql_field->field_name, @@ -9160,26 +9160,21 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (key->foreign) { Foreign_key *fk= static_cast<Foreign_key*>(key); - if (fk->validate(new_create_list)) + bool self_ref; + if (fk->validate(alter_ctx->new_db, alter_ctx->new_name, new_create_list, self_ref)) goto err; - // self-references have no ref_table and ref_db - DBUG_ASSERT(fk->ref_table.str || fk->ref_db.str); - if (fk->ref_table.str) + if (!self_ref) { Table_name t(fk->ref_db.str ? fk->ref_db : table->s->db, fk->ref_table); if (lower_case_table_names) t.lowercase(thd->mem_root); - if (0 != cmp_table(t.db, table->s->db) || - 0 != cmp_table(t.name, table->s->table_name)) - { - if (alter_ctx->fk_added.push_back({t, fk})) - goto err; - const FK_table_to_lock *x= fk_tables_to_lock.insert(t); - if (!x) - goto err; - const_cast<FK_table_to_lock *>(x)->fail= true; - } + if (alter_ctx->fk_added.push_back({t, fk})) + goto err; + const FK_table_to_lock *x= fk_tables_to_lock.insert(t); + if (!x) + goto err; + const_cast<FK_table_to_lock *>(x)->fail= true; } if (key->name.str) { @@ -10778,6 +10773,14 @@ do_continue:; DBUG_RETURN(true); } + /* + Check for duplicate foreign id. + NB: we cannot do this in mysql_prepare_alter_table() because we must generate + default ids first (mysql_prepare_create_table()). + */ + if (alter_ctx.fk_added.size() && alter_ctx.fk_check_foreign_id(thd)) + goto err_new_table_cleanup; + if (alter_info->algorithm(thd) != Alter_info::ALTER_TABLE_ALGORITHM_COPY) { Alter_inplace_info ha_alter_info(create_info, alter_info, &alter_ctx, @@ -12452,6 +12455,18 @@ bool TABLE_SHARE::fk_handle_create(THD *thd, FK_create_vector &shares) cmp_table(fk.referenced_table, ref_share->table_name)) continue; + // Check for duplicated id + for (const FK_info &rk: ref_share->referenced_keys) + { + DBUG_ASSERT(rk.foreign_id.str); + if (0 == rk.foreign_id.cmp(fk.foreign_id)) + { + my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "FOREIGN KEY", + fk.foreign_id.str); + return true; + } + } + FK_info *dst= fk.clone(&ref_share->mem_root); if (!dst || ref_share->referenced_keys.push_back(dst, &ref_share->mem_root)) @@ -12468,6 +12483,20 @@ bool TABLE_SHARE::fk_handle_create(THD *thd, FK_create_vector &shares) return false; } +/** + @brief Used in ALTER TABLE. Prepares data for conducting update on relates shares + foreign_keys/referenced_keys which is done by fk_handle_alter(). + + Updates table's share as well. This is needed for prepare_create_table() and + for InnoDB engine which doesn't flush foreign cache on inplace alter. + + + @param[in] def Rename column action + @param[out] fk_tables_to_lock Referenced/foreign tables to be locked by + mysql_prepare_alter_table() + + @return Error status +*/ bool Alter_table_ctx::fk_prepare_rename(THD *thd, TABLE *table, Create_field *def, mbd::set<FK_table_to_lock> &fk_tables_to_lock) @@ -12873,6 +12902,32 @@ bool Alter_table_ctx::fk_handle_alter(THD *thd) } +bool Alter_table_ctx::fk_check_foreign_id(THD *thd) +{ + for (const FK_add_new &new_fk: fk_added) + { + auto i= fk_shares.find(new_fk.ref); + if (i == fk_shares.end()) + { + DBUG_ASSERT(!thd->variables.check_foreign()); + continue; + } + TABLE_SHARE *s= i->second.share; + for (const FK_info &rk: s->referenced_keys) + { + DBUG_ASSERT(rk.foreign_id.str); + if (0 == rk.foreign_id.cmp(new_fk.fk->constraint_name)) + { + my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "FOREIGN KEY", + rk.foreign_id.str); + return true; + } + } + } + return false; +} + + FK_ref_backup* Alter_table_ctx::fk_add_backup(TABLE_SHARE *share) { FK_ref_backup fk_bak; diff --git a/sql/table.h b/sql/table.h index c902a8c638c..cf6da372206 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1839,7 +1839,12 @@ class FK_info : public Sql_alloc { public: Lex_cstring foreign_id; - // TODO: use Table_name + + /* + TODO: use Table_name. NB: the below names are in original case. + The share MUST be acquried in case according to lower_case_table_names. + Use for_table(), ref_table() for that (TODO: limit interface). + */ Lex_cstring foreign_db; Lex_cstring foreign_table; Lex_cstring referenced_db; @@ -1858,6 +1863,10 @@ public: { return referenced_db.str ? referenced_db : foreign_db; } + Lex_cstring* ref_db_ptr() + { + return referenced_db.str ? &referenced_db : &foreign_db; + } bool assign(Foreign_key &fk, Table_name table); FK_info * clone(MEM_ROOT *mem_root) const; Table_name for_table(MEM_ROOT *mem_root) const; @@ -2154,7 +2163,7 @@ struct TABLE_LIST enum prelocking_types { - PRELOCK_NONE, PRELOCK_ROUTINE, PRELOCK_FK + PRELOCK_NONE, PRELOCK_ROUTINE, PRELOCK_FK, PRELOCK_RK }; /** @@ -2216,9 +2225,6 @@ struct TABLE_LIST OT_BASE_ONLY); belong_to_view= belong_to_view_arg; trg_event_map= trg_event_map_arg; - /* MDL is enough for read-only FK checks, we don't need the table */ - if (prelocking_type == PRELOCK_FK && lock_type < TL_WRITE_ALLOW_WRITE) - open_strategy= OPEN_STUB; **last_ptr= this; prev_global= *last_ptr; diff --git a/sql/unireg.cc b/sql/unireg.cc index fd091b2975d..25ff0f233f3 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1411,19 +1411,19 @@ bool Foreign_key_io::parse(THD *thd, TABLE_SHARE *s, LEX_CUSTRING& image) "Foreign_key_io failed to read reference hints count"); return true; } - // Resolve hints to referenced keys for non-temporary shares - if (s->tmp_table) - return false; + for (uint i= 0; i < rk_count; ++i) { if (read_string(hint_db, &s->mem_root, p)) return true; if (read_string(hint_table, &s->mem_root, p)) return true; - if (s->open_flags & GTS_FK_SHALLOW_HINTS) + if (s->tmp_table || s->open_flags & GTS_FK_SHALLOW_HINTS) { /* For DROP TABLE we don't need full reference resolution. We just need - to know if anything from the outside references the dropped table. */ + to know if anything from the outside references the dropped table. + Temporary share may have FK columns renamed so we can't resolve by + column names.*/ FK_info *dst= new (&s->mem_root) FK_info; dst->foreign_db= hint_db; dst->foreign_table= hint_table; diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 9c627ecd145..f77caf7935d 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1128,11 +1128,8 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index) if (UNIV_UNLIKELY(!field_max_size)) { switch (col->mtype) { case DATA_VARCHAR: - if (!comp - && (!strcmp(index->table->name.m_name, - "SYS_FOREIGN") - || !strcmp(index->table->name.m_name, - "SYS_FOREIGN_COLS"))) { + if (!comp) { + // TESTME: innodb.alter_algorithm break; } /* fall through */ @@ -1157,21 +1154,6 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index) continue; } - /* SYS_FOREIGN.ID is defined as CHAR in the - InnoDB internal SQL parser, which translates - into the incorrect VARCHAR(0). InnoDB does - not enforce maximum lengths of columns, so - that is why any data can be inserted in the - first place. - - Likewise, SYS_FOREIGN.FOR_NAME, - SYS_FOREIGN.REF_NAME, SYS_FOREIGN_COLS.ID, are - defined as CHAR, and also they are part of a key. */ - - ut_ad(!strcmp(index->table->name.m_name, - "SYS_FOREIGN") - || !strcmp(index->table->name.m_name, - "SYS_FOREIGN_COLS")); ut_ad(!comp); ut_ad(col->mtype == DATA_VARCHAR); diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 7a27160ccd5..46ebe9a02a5 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -1383,151 +1383,6 @@ dict_check_if_system_table_exists( return(error); } -/****************************************************************//** -Creates the foreign key constraints system tables inside InnoDB -at server bootstrap or server start if they are not found or are -not of the right form. -@return DB_SUCCESS or error code */ -dberr_t -dict_create_or_check_foreign_constraint_tables(void) -/*================================================*/ -{ - trx_t* trx; - my_bool srv_file_per_table_backup; - dberr_t err; - dberr_t sys_foreign_err; - dberr_t sys_foreign_cols_err; - - ut_ad(!srv_any_background_activity()); - - /* Note: The master thread has not been started at this point. */ - - - sys_foreign_err = dict_check_if_system_table_exists( - "SYS_FOREIGN", DICT_NUM_FIELDS__SYS_FOREIGN + 1, 3); - sys_foreign_cols_err = dict_check_if_system_table_exists( - "SYS_FOREIGN_COLS", DICT_NUM_FIELDS__SYS_FOREIGN_COLS + 1, 1); - - if (sys_foreign_err == DB_SUCCESS - && sys_foreign_cols_err == DB_SUCCESS) { - return(DB_SUCCESS); - } - - if (srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO) { - return(DB_READ_ONLY); - } - - trx = trx_create(); - - trx_set_dict_operation(trx, TRX_DICT_OP_TABLE); - - trx->op_info = "creating foreign key sys tables"; - - row_mysql_lock_data_dictionary(trx); - - DBUG_EXECUTE_IF( - "create_and_drop_garbage", - err = que_eval_sql( - NULL, - "PROCEDURE CREATE_GARBAGE_TABLE_PROC () IS\n" - "BEGIN\n" - "CREATE TABLE\n" - "\"test/#sql-ib-garbage\"(ID CHAR);\n" - "CREATE UNIQUE CLUSTERED INDEX PRIMARY" - " ON \"test/#sql-ib-garbage\"(ID);\n" - "END;\n", FALSE, trx); - ut_ad(err == DB_SUCCESS); - row_drop_table_for_mysql("test/#sql-ib-garbage", trx, - SQLCOM_DROP_DB, true);); - - /* Check which incomplete table definition to drop. */ - - if (sys_foreign_err == DB_CORRUPTION) { - row_drop_table_after_create_fail("SYS_FOREIGN", trx); - } - - if (sys_foreign_cols_err == DB_CORRUPTION) { - row_drop_table_after_create_fail("SYS_FOREIGN_COLS", trx); - } - - ib::info() << "Creating foreign key constraint system tables."; - - /* NOTE: in dict_load_foreigns we use the fact that - there are 2 secondary indexes on SYS_FOREIGN, and they - are defined just like below */ - - /* NOTE: when designing InnoDB's foreign key support in 2001, we made - an error and made the table names and the foreign key id of type - 'CHAR' (internally, really a VARCHAR). We should have made the type - VARBINARY, like in other InnoDB system tables, to get a clean - design. */ - - srv_file_per_table_backup = srv_file_per_table; - - /* We always want SYSTEM tables to be created inside the system - tablespace. */ - - srv_file_per_table = 0; - - err = que_eval_sql( - NULL, - "PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n" - "BEGIN\n" - "CREATE TABLE\n" - "SYS_FOREIGN(ID CHAR, FOR_NAME CHAR," - " REF_NAME CHAR, N_COLS INT);\n" - "CREATE UNIQUE CLUSTERED INDEX ID_IND" - " ON SYS_FOREIGN (ID);\n" - "CREATE INDEX FOR_IND" - " ON SYS_FOREIGN (FOR_NAME);\n" - "CREATE INDEX REF_IND" - " ON SYS_FOREIGN (REF_NAME);\n" - "CREATE TABLE\n" - "SYS_FOREIGN_COLS(ID CHAR, POS INT," - " FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n" - "CREATE UNIQUE CLUSTERED INDEX ID_IND" - " ON SYS_FOREIGN_COLS (ID, POS);\n" - "END;\n", - FALSE, trx); - - if (UNIV_UNLIKELY(err != DB_SUCCESS)) { - ib::error() << "Creation of SYS_FOREIGN and SYS_FOREIGN_COLS" - " failed: " << err << ". Tablespace is" - " full. Dropping incompletely created tables."; - - ut_ad(err == DB_OUT_OF_FILE_SPACE - || err == DB_TOO_MANY_CONCURRENT_TRXS); - - row_drop_table_after_create_fail("SYS_FOREIGN", trx); - row_drop_table_after_create_fail("SYS_FOREIGN_COLS", trx); - - if (err == DB_OUT_OF_FILE_SPACE) { - err = DB_MUST_GET_MORE_FILE_SPACE; - } - } - - trx_commit_for_mysql(trx); - - row_mysql_unlock_data_dictionary(trx); - - trx->free(); - - srv_file_per_table = srv_file_per_table_backup; - - /* Note: The master thread has not been started at this point. */ - /* Confirm and move to the non-LRU part of the table LRU list. */ - sys_foreign_err = dict_check_if_system_table_exists( - "SYS_FOREIGN", DICT_NUM_FIELDS__SYS_FOREIGN + 1, 3); - ut_a(sys_foreign_err == DB_SUCCESS); - - sys_foreign_cols_err = dict_check_if_system_table_exists( - "SYS_FOREIGN_COLS", DICT_NUM_FIELDS__SYS_FOREIGN_COLS + 1, 1); - ut_a(sys_foreign_cols_err == DB_SUCCESS); - - return(err); -} - /** Creates the virtual column system table (SYS_VIRTUAL) inside InnoDB at server bootstrap or server start if the table is not found or is not of the right form. @@ -1628,304 +1483,6 @@ dict_create_or_check_sys_virtual() return(err); } -/****************************************************************//** -Evaluate the given foreign key SQL statement. -@return error code or DB_SUCCESS */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) -dberr_t -dict_foreign_eval_sql( -/*==================*/ - pars_info_t* info, /*!< in: info struct */ - const char* sql, /*!< in: SQL string to evaluate */ - const char* name, /*!< in: table name (for diagnostics) */ - const char* id, /*!< in: foreign key id */ - trx_t* trx) /*!< in/out: transaction */ -{ - dberr_t error; - FILE* ef = dict_foreign_err_file; - - error = que_eval_sql(info, sql, FALSE, trx); - - if (error == DB_DUPLICATE_KEY) { - mutex_enter(&dict_foreign_err_mutex); - rewind(ef); - ut_print_timestamp(ef); - fputs(" Error in foreign key constraint creation for table ", - ef); - ut_print_name(ef, trx, name); - fputs(".\nA foreign key constraint of name ", ef); - ut_print_name(ef, trx, id); - fputs("\nalready exists." - " (Note that internally InnoDB adds 'databasename'\n" - "in front of the user-defined constraint name.)\n" - "Note that InnoDB's FOREIGN KEY system tables store\n" - "constraint names as case-insensitive, with the\n" - "MySQL standard latin1_swedish_ci collation. If you\n" - "create tables or databases whose names differ only in\n" - "the character case, then collisions in constraint\n" - "names can occur. Workaround: name your constraints\n" - "explicitly with unique names.\n", - ef); - - mutex_exit(&dict_foreign_err_mutex); - - return(error); - } - - if (UNIV_UNLIKELY(error != DB_SUCCESS)) { - ib::error() << "Foreign key constraint creation failed: " - << error; - - mutex_enter(&dict_foreign_err_mutex); - ut_print_timestamp(ef); - fputs(" Internal error in foreign key constraint creation" - " for table ", ef); - ut_print_name(ef, trx, name); - fputs(".\n" - "See the MySQL .err log in the datadir" - " for more information.\n", ef); - mutex_exit(&dict_foreign_err_mutex); - - return(error); - } - - return(DB_SUCCESS); -} - -/********************************************************************//** -Add a single foreign key field definition to the data dictionary tables in -the database. -@return error code or DB_SUCCESS */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) -dberr_t -dict_create_add_foreign_field_to_dictionary( -/*========================================*/ - ulint field_nr, /*!< in: field number */ - const char* table_name, /*!< in: table name */ - const dict_foreign_t* foreign, /*!< in: foreign */ - trx_t* trx) /*!< in/out: transaction */ -{ - DBUG_ENTER("dict_create_add_foreign_field_to_dictionary"); - - pars_info_t* info = pars_info_create(); - - pars_info_add_str_literal(info, "id", foreign->id); - - pars_info_add_int4_literal(info, "pos", field_nr); - - pars_info_add_str_literal(info, "for_col_name", - foreign->foreign_col_names[field_nr]); - - pars_info_add_str_literal(info, "ref_col_name", - foreign->referenced_col_names[field_nr]); - - DBUG_RETURN(dict_foreign_eval_sql( - info, - "PROCEDURE P () IS\n" - "BEGIN\n" - "INSERT INTO SYS_FOREIGN_COLS VALUES" - "(:id, :pos, :for_col_name, :ref_col_name);\n" - "END;\n", - table_name, foreign->id, trx)); -} - -/********************************************************************//** -Construct foreign key constraint defintion from data dictionary information. -*/ -UNIV_INTERN -char* -dict_foreign_def_get( -/*=================*/ - dict_foreign_t* foreign,/*!< in: foreign */ - trx_t* trx) /*!< in: trx */ -{ - char* fk_def = (char *)mem_heap_alloc(foreign->heap, 4*1024); - const char* tbname; - char tablebuf[MAX_TABLE_NAME_LEN + 1] = ""; - unsigned i; - char* bufend; - - tbname = dict_remove_db_name(foreign->id); - bufend = innobase_convert_name(tablebuf, MAX_TABLE_NAME_LEN, - tbname, strlen(tbname), trx->mysql_thd); - tablebuf[bufend - tablebuf] = '\0'; - - sprintf(fk_def, - (char *)"CONSTRAINT %s FOREIGN KEY (", (char *)tablebuf); - - for(i = 0; i < foreign->n_fields; i++) { - char buf[MAX_TABLE_NAME_LEN + 1] = ""; - innobase_convert_name(buf, MAX_TABLE_NAME_LEN, - foreign->foreign_col_names[i], - strlen(foreign->foreign_col_names[i]), - trx->mysql_thd); - strcat(fk_def, buf); - if (i < static_cast<unsigned>(foreign->n_fields-1)) { - strcat(fk_def, (char *)","); - } - } - - strcat(fk_def,(char *)") REFERENCES "); - - bufend = innobase_convert_name(tablebuf, MAX_TABLE_NAME_LEN, - foreign->referenced_table_name, - strlen(foreign->referenced_table_name), - trx->mysql_thd); - tablebuf[bufend - tablebuf] = '\0'; - - strcat(fk_def, tablebuf); - strcat(fk_def, " ("); - - for(i = 0; i < foreign->n_fields; i++) { - char buf[MAX_TABLE_NAME_LEN + 1] = ""; - bufend = innobase_convert_name(buf, MAX_TABLE_NAME_LEN, - foreign->referenced_col_names[i], - strlen(foreign->referenced_col_names[i]), - trx->mysql_thd); - buf[bufend - buf] = '\0'; - strcat(fk_def, buf); - if (i < (uint)foreign->n_fields-1) { - strcat(fk_def, (char *)","); - } - } - strcat(fk_def, (char *)")"); - - return fk_def; -} - -/********************************************************************//** -Convert foreign key column names from data dictionary to SQL-layer. -*/ -static -void -dict_foreign_def_get_fields( -/*========================*/ - dict_foreign_t* foreign,/*!< in: foreign */ - trx_t* trx, /*!< in: trx */ - char** field, /*!< out: foreign column */ - char** field2, /*!< out: referenced column */ - ulint col_no) /*!< in: column number */ -{ - char* bufend; - char* fieldbuf = (char *)mem_heap_alloc(foreign->heap, MAX_TABLE_NAME_LEN+1); - char* fieldbuf2 = (char *)mem_heap_alloc(foreign->heap, MAX_TABLE_NAME_LEN+1); - - bufend = innobase_convert_name(fieldbuf, MAX_TABLE_NAME_LEN, - foreign->foreign_col_names[col_no], - strlen(foreign->foreign_col_names[col_no]), - trx->mysql_thd); - - fieldbuf[bufend - fieldbuf] = '\0'; - - bufend = innobase_convert_name(fieldbuf2, MAX_TABLE_NAME_LEN, - foreign->referenced_col_names[col_no], - strlen(foreign->referenced_col_names[col_no]), - trx->mysql_thd); - - fieldbuf2[bufend - fieldbuf2] = '\0'; - *field = fieldbuf; - *field2 = fieldbuf2; -} - -/********************************************************************//** -Add a foreign key definition to the data dictionary tables. -@return error code or DB_SUCCESS */ -dberr_t -dict_create_add_foreign_to_dictionary( -/*==================================*/ - const char* name, /*!< in: table name */ - const dict_foreign_t* foreign,/*!< in: foreign key */ - trx_t* trx) /*!< in/out: dictionary transaction */ -{ - dberr_t error; - - DBUG_ENTER("dict_create_add_foreign_to_dictionary"); - - pars_info_t* info = pars_info_create(); - - pars_info_add_str_literal(info, "id", foreign->id); - - pars_info_add_str_literal(info, "for_name", name); - - pars_info_add_str_literal(info, "ref_name", - foreign->referenced_table_name); - - pars_info_add_int4_literal(info, "n_cols", - ulint(foreign->n_fields) - | (ulint(foreign->type) << 24)); - - DBUG_PRINT("dict_create_add_foreign_to_dictionary", - ("'%s', '%s', '%s', %d", foreign->id, name, - foreign->referenced_table_name, - foreign->n_fields + (foreign->type << 24))); - - error = dict_foreign_eval_sql(info, - "PROCEDURE P () IS\n" - "BEGIN\n" - "INSERT INTO SYS_FOREIGN VALUES" - "(:id, :for_name, :ref_name, :n_cols);\n" - "END;\n" - , name, foreign->id, trx); - - if (error != DB_SUCCESS) { - - if (error == DB_DUPLICATE_KEY) { - char buf[MAX_TABLE_NAME_LEN + 1] = ""; - char tablename[MAX_TABLE_NAME_LEN + 1] = ""; - char* fk_def; - - innobase_convert_name(tablename, MAX_TABLE_NAME_LEN, - name, strlen(name), trx->mysql_thd); - - innobase_convert_name(buf, MAX_TABLE_NAME_LEN, - foreign->id, strlen(foreign->id), trx->mysql_thd); - - fk_def = dict_foreign_def_get((dict_foreign_t*)foreign, trx); - - ib_push_warning(trx, error, - "Create or Alter table %s with foreign key constraint" - " failed. Foreign key constraint %s" - " already exists on data dictionary." - " Foreign key constraint names need to be unique in database." - " Error in foreign key definition: %s.", - tablename, buf, fk_def); - } - - DBUG_RETURN(error); - } - - for (ulint i = 0; i < foreign->n_fields; i++) { - error = dict_create_add_foreign_field_to_dictionary( - i, name, foreign, trx); - - if (error != DB_SUCCESS) { - char buf[MAX_TABLE_NAME_LEN + 1] = ""; - char tablename[MAX_TABLE_NAME_LEN + 1] = ""; - char* field=NULL; - char* field2=NULL; - char* fk_def; - - innobase_convert_name(tablename, MAX_TABLE_NAME_LEN, - name, strlen(name), trx->mysql_thd); - innobase_convert_name(buf, MAX_TABLE_NAME_LEN, - foreign->id, strlen(foreign->id), trx->mysql_thd); - fk_def = dict_foreign_def_get((dict_foreign_t*)foreign, trx); - dict_foreign_def_get_fields((dict_foreign_t*)foreign, trx, &field, &field2, i); - - ib_push_warning(trx, error, - "Create or Alter table %s with foreign key constraint" - " failed. Error adding foreign key constraint name %s" - " fields %s or %s to the dictionary." - " Error in foreign key definition: %s.", - tablename, buf, i+1, fk_def); - - DBUG_RETURN(error); - } - } - - DBUG_RETURN(error); -} - /** Check if a foreign constraint is on the given column name. @param[in] col_name column name to be searched for fk constraint @param[in] table table to which foreign key constraint belongs @@ -2000,56 +1557,6 @@ dict_foreigns_has_s_base_col( return(false); } -/** Adds the given set of foreign key objects to the dictionary tables -in the database. This function does not modify the dictionary cache. The -caller must ensure that all foreign key objects contain a valid constraint -name in foreign->id. -@param[in] local_fk_set set of foreign key objects, to be added to -the dictionary tables -@param[in] table table to which the foreign key objects in -local_fk_set belong to -@param[in,out] trx transaction -@return error code or DB_SUCCESS */ -dberr_t -dict_create_add_foreigns_to_dictionary( -/*===================================*/ - const dict_foreign_set& local_fk_set, - const dict_table_t* table, - trx_t* trx) -{ - dict_foreign_t* foreign; - dberr_t error; - - ut_ad(mutex_own(&dict_sys.mutex)); - - if (NULL == dict_table_get_low("SYS_FOREIGN")) { - - ib::error() << "Table SYS_FOREIGN not found" - " in internal data dictionary"; - - return(DB_ERROR); - } - - error = DB_SUCCESS; - - for (dict_foreign_set::const_iterator it = local_fk_set.begin(); - it != local_fk_set.end(); - ++it) { - - foreign = *it; - ut_ad(foreign->id != NULL); - - error = dict_create_add_foreign_to_dictionary( - table->name.m_name, foreign, trx); - - if (error != DB_SUCCESS) { - break; - } - } - - return error; -} - /****************************************************************//** Creates the tablespaces and datafiles system tables inside InnoDB at server bootstrap or server start if they are not found or are diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 097c907a826..0402ae5013f 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -1091,11 +1091,7 @@ dict_table_open_on_name( ut_ad(table_name); ut_ad(mutex_own(&dict_sys.mutex)); - table = dict_table_check_if_in_cache_low(table_name); - - if (table == NULL) { - table = dict_load_table(table_name, ignore_err); - } + table = dict_load_table(table_name, ignore_err); ut_ad(!table || table->cached); @@ -2997,6 +2993,7 @@ dict_foreign_add_to_cache( dict_foreign_t* for_in_cache = NULL; dict_index_t* index; ibool added_to_referenced_list= FALSE; + ibool added_to_foreign_list= FALSE; FILE* ef = dict_foreign_err_file; DBUG_ENTER("dict_foreign_add_to_cache"); @@ -3020,10 +3017,16 @@ dict_foreign_add_to_cache( } if (for_in_cache) { - dict_foreign_free(foreign); + if (foreign != for_in_cache) { + if (for_table != for_in_cache->foreign_table) { + dict_foreign_remove_from_cache(for_in_cache); + for_in_cache = foreign; + } else { + dict_foreign_free(foreign); + } + } } else { for_in_cache = foreign; - } if (ref_table && !for_in_cache->referenced_table) { @@ -3110,19 +3113,24 @@ dict_foreign_add_to_cache( ut_a(ret.second); /* second is true if the insertion took place */ + added_to_foreign_list = true; } /* We need to move the table to the non-LRU end of the table LRU list. Otherwise it will be evicted from the cache. */ - if (ref_table != NULL) { + if (ref_table != NULL && added_to_referenced_list) { dict_sys.prevent_eviction(ref_table); } - if (for_table != NULL) { + if (for_table != NULL && added_to_foreign_list) { dict_sys.prevent_eviction(for_table); } + if (!for_in_cache->v_cols && (added_to_foreign_list || added_to_referenced_list)) { + dict_mem_foreign_fill_vcol_set(for_in_cache); + } + ut_ad(dict_lru_validate()); DBUG_RETURN(DB_SUCCESS); } @@ -3342,29 +3350,26 @@ convert_id: return(ptr); } -/*********************************************************************//** -Open a table from its database and table name, this is currently used by -foreign constraint parser to get the referenced table. -@return complete table name with database and table name, allocated from -heap memory passed in */ -char* -dict_get_referenced_table( - const char* name, /*!< in: foreign key table name */ +bool +dict_table_t::build_name( const char* database_name, /*!< in: table db name */ ulint database_name_len, /*!< in: db name length */ const char* table_name, /*!< in: table name */ ulint table_name_len, /*!< in: table name length */ - dict_table_t** table, /*!< out: table object or NULL */ - mem_heap_t* heap, /*!< in/out: heap memory */ - CHARSET_INFO* from_cs) /*!< in: table name charset */ + char *&dict_name, + ulint &dict_name_len, + mem_heap_t* alloc, + CHARSET_INFO* cs_db, + CHARSET_INFO* cs_table) /*!< in: table name charset */ { - char* ref; char db_name[MAX_DATABASE_NAME_LEN]; char tbl_name[MAX_TABLE_NAME_LEN]; CHARSET_INFO* to_cs = &my_charset_filename; uint errors; - ut_ad(database_name || name); + ut_ad(database_name); + ut_ad(database_name_len); ut_ad(table_name); + ut_ad(table_name_len); if (!strncmp(table_name, srv_mysql50_table_name_prefix, sizeof(srv_mysql50_table_name_prefix) - 1)) { @@ -3377,61 +3382,109 @@ dict_get_referenced_table( to_cs = system_charset_info; } - table_name_len = strconvert(from_cs, table_name, table_name_len, to_cs, - tbl_name, MAX_TABLE_NAME_LEN, &errors); - table_name = tbl_name; + if (cs_table != to_cs) { + table_name_len = strconvert(cs_table, table_name, table_name_len, to_cs, + tbl_name, MAX_TABLE_NAME_LEN, &errors); + if (errors > 0) { + return true; + } + table_name = tbl_name; + } - if (database_name) { + if (!strncmp(database_name, srv_mysql50_table_name_prefix, + sizeof(srv_mysql50_table_name_prefix) - 1)) { + database_name + += sizeof(srv_mysql50_table_name_prefix) - 1; + database_name_len + -= sizeof(srv_mysql50_table_name_prefix) - 1; + to_cs = system_charset_info; + } else { to_cs = &my_charset_filename; - if (!strncmp(database_name, srv_mysql50_table_name_prefix, - sizeof(srv_mysql50_table_name_prefix) - 1)) { - database_name - += sizeof(srv_mysql50_table_name_prefix) - 1; - database_name_len - -= sizeof(srv_mysql50_table_name_prefix) - 1; - to_cs = system_charset_info; - } + } + if (cs_db != to_cs) { database_name_len = strconvert( - from_cs, database_name, database_name_len, to_cs, + cs_table, database_name, database_name_len, to_cs, db_name, MAX_DATABASE_NAME_LEN, &errors); + if (errors > 0) { + return true; + } database_name = db_name; - } else { + } + + dict_name_len = database_name_len + table_name_len + 1; + + /* Copy database_name, '/', table_name, '\0' */ + if (alloc) { + dict_name = static_cast<char*>(mem_heap_alloc(alloc, dict_name_len + 1)); + if (!dict_name) { + return true; + } + } + memcpy(dict_name, database_name, database_name_len); + dict_name[database_name_len] = '/'; + memcpy(dict_name + database_name_len + 1, table_name, table_name_len + 1); + + /* Values; 0 = Store and compare as given; case sensitive + 1 = Store and compare in lower; case insensitive + 2 = Store as given, compare in lower; case semi-sensitive */ + if (innobase_get_lower_case_table_names() == 1) { + innobase_casedn_str(dict_name); + } + + return false; +} + +/*********************************************************************//** +Open a table from its database and table name, this is currently used by +foreign constraint parser to get the referenced table. +@return complete table name with database and table name, allocated from +heap memory passed in */ +char* +dict_get_referenced_table( + const char* name, /*!< in: foreign key table name */ + const char* database_name, /*!< in: table db name */ + ulint database_name_len, /*!< in: db name length */ + const char* table_name, /*!< in: table name */ + ulint table_name_len, /*!< in: table name length */ + dict_table_t** table, /*!< out: table object or NULL */ + mem_heap_t* heap, /*!< in/out: heap memory */ + CHARSET_INFO* from_cs) /*!< in: table name charset */ +{ + char* dict_name; + ulint dict_name_len; + CHARSET_INFO* db_cs = from_cs; + ut_ad(database_name || name); + ut_ad(table_name); + + + if (!database_name) { /* Use the database name of the foreign key table */ database_name = name; database_name_len = dict_get_db_name_len(name); + db_cs = &my_charset_filename; } - /* Copy database_name, '/', table_name, '\0' */ - ref = static_cast<char*>(mem_heap_alloc( - heap, database_name_len + table_name_len + 2)); - memcpy(ref, database_name, database_name_len); - ref[database_name_len] = '/'; - memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); + if (dict_table_t::build_name(database_name, database_name_len, table_name, + table_name_len, dict_name, dict_name_len, heap, from_cs, db_cs)) { + return NULL; + } /* Values; 0 = Store and compare as given; case sensitive 1 = Store and compare in lower; case insensitive 2 = Store as given, compare in lower; case semi-sensitive */ if (innobase_get_lower_case_table_names() == 2) { - innobase_casedn_str(ref); - *table = dict_table_get_low(ref); - memcpy(ref, database_name, database_name_len); - ref[database_name_len] = '/'; - memcpy(ref + database_name_len + 1, table_name, table_name_len + 1); + char buf[MAX_FULL_NAME_LEN]; + memcpy(buf, dict_name, dict_name_len + 1); + innobase_casedn_str(buf); + *table = dict_table_get_low(buf); } else { -#ifndef _WIN32 - if (innobase_get_lower_case_table_names() == 1) { - innobase_casedn_str(ref); - } -#else - innobase_casedn_str(ref); -#endif /* !_WIN32 */ - *table = dict_table_get_low(ref); + *table = dict_table_get_low(dict_name); } - return(ref); + return(dict_name); } /*********************************************************************//** diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index b135e042dc7..44f46611b3c 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -44,6 +44,7 @@ Created 4/24/1996 Heikki Tuuri #include "srv0start.h" #include "srv0srv.h" #include "fts0opt.h" +#include "ha_innodb.h" /** Following are the InnoDB system tables. The positions in this array are referenced by enum dict_system_table_id. */ @@ -62,17 +63,11 @@ static const char* SYSTEM_TABLE_NAME[] = { /** Loads a table definition and also all its index definitions. Loads those foreign key constraints whose referenced table is already in -dictionary cache. If a foreign key constraint is not loaded, then the -referenced table is pushed into the output stack (fk_tables), if it is not -NULL. These tables must be subsequently loaded so that all the foreign -key constraints are loaded into memory. +dictionary cache. @param[in] name Table name in the db/tablename format @param[in] ignore_err Error to be ignored when loading table and its index definition -@param[out] fk_tables Related table names that must also be - loaded to ensure that all foreign key - constraints are loaded. @return table, NULL if does not exist; if the table is stored in an .ibd file, but the file does not exist, then we set the file_unreadable flag in the table object we return */ @@ -80,8 +75,7 @@ static dict_table_t* dict_load_table_one( const table_name_t& name, - dict_err_ignore_t ignore_err, - dict_names_t& fk_tables); + dict_err_ignore_t ignore_err); /** Load a table definition from a SYS_TABLES record to dict_table_t. Do not load any columns or indexes. @@ -514,155 +508,6 @@ dict_process_sys_fields_rec( } /********************************************************************//** -This function parses a SYS_FOREIGN record and populate a dict_foreign_t -structure with the information from the record. For detail information -about SYS_FOREIGN fields, please refer to dict_load_foreign() function. -@return error message, or NULL on success */ -const char* -dict_process_sys_foreign_rec( -/*=========================*/ - mem_heap_t* heap, /*!< in/out: heap memory */ - const rec_t* rec, /*!< in: current SYS_FOREIGN rec */ - dict_foreign_t* foreign) /*!< out: dict_foreign_t struct - to be filled */ -{ - ulint len; - const byte* field; - - if (rec_get_deleted_flag(rec, 0)) { - return("delete-marked record in SYS_FOREIGN"); - } - - if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_FOREIGN) { - return("wrong number of columns in SYS_FOREIGN record"); - } - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN__ID, &len); - if (len == 0 || len == UNIV_SQL_NULL) { -err_len: - return("incorrect column length in SYS_FOREIGN"); - } - - /* This receives a dict_foreign_t* that points to a stack variable. - So dict_foreign_free(foreign) is not used as elsewhere. - Since the heap used here is freed elsewhere, foreign->heap - is not assigned. */ - foreign->id = mem_heap_strdupl(heap, (const char*) field, len); - - rec_get_nth_field_offs_old( - rec, DICT_FLD__SYS_FOREIGN__DB_TRX_ID, &len); - if (len != DATA_TRX_ID_LEN && len != UNIV_SQL_NULL) { - goto err_len; - } - rec_get_nth_field_offs_old( - rec, DICT_FLD__SYS_FOREIGN__DB_ROLL_PTR, &len); - if (len != DATA_ROLL_PTR_LEN && len != UNIV_SQL_NULL) { - goto err_len; - } - - /* The _lookup versions of the referenced and foreign table names - are not assigned since they are not used in this dict_foreign_t */ - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN__FOR_NAME, &len); - if (len == 0 || len == UNIV_SQL_NULL) { - goto err_len; - } - foreign->foreign_table_name = mem_heap_strdupl( - heap, (const char*) field, len); - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN__REF_NAME, &len); - if (len == 0 || len == UNIV_SQL_NULL) { - goto err_len; - } - foreign->referenced_table_name = mem_heap_strdupl( - heap, (const char*) field, len); - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN__N_COLS, &len); - if (len != 4) { - goto err_len; - } - uint32_t n_fields_and_type = mach_read_from_4(field); - - foreign->type = n_fields_and_type >> 24 & ((1U << 6) - 1); - foreign->n_fields = n_fields_and_type & dict_index_t::MAX_N_FIELDS; - - return(NULL); -} - -/********************************************************************//** -This function parses a SYS_FOREIGN_COLS record and extract necessary -information from the record and return to caller. -@return error message, or NULL on success */ -const char* -dict_process_sys_foreign_col_rec( -/*=============================*/ - mem_heap_t* heap, /*!< in/out: heap memory */ - const rec_t* rec, /*!< in: current SYS_FOREIGN_COLS rec */ - const char** name, /*!< out: foreign key constraint name */ - const char** for_col_name, /*!< out: referencing column name */ - const char** ref_col_name, /*!< out: referenced column name - in referenced table */ - ulint* pos) /*!< out: column position */ -{ - ulint len; - const byte* field; - - if (rec_get_deleted_flag(rec, 0)) { - return("delete-marked record in SYS_FOREIGN_COLS"); - } - - if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_FOREIGN_COLS) { - return("wrong number of columns in SYS_FOREIGN_COLS record"); - } - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__ID, &len); - if (len == 0 || len == UNIV_SQL_NULL) { -err_len: - return("incorrect column length in SYS_FOREIGN_COLS"); - } - *name = mem_heap_strdupl(heap, (char*) field, len); - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__POS, &len); - if (len != 4) { - goto err_len; - } - *pos = mach_read_from_4(field); - - rec_get_nth_field_offs_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__DB_TRX_ID, &len); - if (len != DATA_TRX_ID_LEN && len != UNIV_SQL_NULL) { - goto err_len; - } - rec_get_nth_field_offs_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__DB_ROLL_PTR, &len); - if (len != DATA_ROLL_PTR_LEN && len != UNIV_SQL_NULL) { - goto err_len; - } - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__FOR_COL_NAME, &len); - if (len == 0 || len == UNIV_SQL_NULL) { - goto err_len; - } - *for_col_name = mem_heap_strdupl(heap, (char*) field, len); - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__REF_COL_NAME, &len); - if (len == 0 || len == UNIV_SQL_NULL) { - goto err_len; - } - *ref_col_name = mem_heap_strdupl(heap, (char*) field, len); - - return(NULL); -} - -/********************************************************************//** This function parses a SYS_TABLESPACES record, extracts necessary information from the record and returns to caller. @return error message, or NULL on success */ @@ -2730,9 +2575,7 @@ a foreign key references columns in this table. flag in the table object we return. */ dict_table_t* dict_load_table(const char* name, dict_err_ignore_t ignore_err) { - dict_names_t fk_list; dict_table_t* result; - dict_names_t::iterator i; DBUG_ENTER("dict_load_table"); DBUG_PRINT("dict_load_table", ("loading table: '%s'", name)); @@ -2743,14 +2586,7 @@ dict_table_t* dict_load_table(const char* name, dict_err_ignore_t ignore_err) if (!result) { result = dict_load_table_one(const_cast<char*>(name), - ignore_err, fk_list); - while (!fk_list.empty()) { - if (!dict_table_check_if_in_cache_low(fk_list.front())) - dict_load_table_one( - const_cast<char*>(fk_list.front()), - ignore_err, fk_list); - fk_list.pop_front(); - } + ignore_err); } DBUG_RETURN(result); @@ -2835,17 +2671,11 @@ dict_load_tablespace( /** Loads a table definition and also all its index definitions. Loads those foreign key constraints whose referenced table is already in -dictionary cache. If a foreign key constraint is not loaded, then the -referenced table is pushed into the output stack (fk_tables), if it is not -NULL. These tables must be subsequently loaded so that all the foreign -key constraints are loaded into memory. +dictionary cache. @param[in] name Table name in the db/tablename format @param[in] ignore_err Error to be ignored when loading table and its index definition -@param[out] fk_tables Related table names that must also be - loaded to ensure that all foreign key - constraints are loaded. @return table, NULL if does not exist; if the table is stored in an .ibd file, but the file does not exist, then we set the file_unreadable flag in the table object we return */ @@ -2853,8 +2683,7 @@ static dict_table_t* dict_load_table_one( const table_name_t& name, - dict_err_ignore_t ignore_err, - dict_names_t& fk_tables) + dict_err_ignore_t ignore_err) { dberr_t err; dict_table_t* sys_tables; @@ -3026,24 +2855,7 @@ corrupted: all indexes were loaded. */ if (!table->is_readable()) { /* Don't attempt to load the indexes from disk. */ - } else if (err == DB_SUCCESS) { - err = dict_load_foreigns(table->name.m_name, NULL, - true, true, - ignore_err, fk_tables); - - if (err != DB_SUCCESS) { - ib::warn() << "Load table " << table->name - << " failed, the table has missing" - " foreign key indexes. Turn off" - " 'foreign_key_checks' and try again."; - - dict_sys.remove(table); - table = NULL; - } else { - dict_mem_table_fill_foreign_vcol_set(table); - table->fk_max_recusive_level = 0; - } - } else { + } else if (err != DB_SUCCESS) { dict_index_t* index; /* Make sure that at least the clustered index was loaded. @@ -3211,487 +3023,6 @@ dict_load_sys_table( mem_heap_free(heap); } -/********************************************************************//** -Loads foreign key constraint col names (also for the referenced table). -Members that must be set (and valid) in foreign: -foreign->heap -foreign->n_fields -foreign->id ('\0'-terminated) -Members that will be created and set by this function: -foreign->foreign_col_names[i] -foreign->referenced_col_names[i] -(for i=0..foreign->n_fields-1) */ -static -void -dict_load_foreign_cols( -/*===================*/ - dict_foreign_t* foreign)/*!< in/out: foreign constraint object */ -{ - dict_table_t* sys_foreign_cols; - dict_index_t* sys_index; - btr_pcur_t pcur; - dtuple_t* tuple; - dfield_t* dfield; - const rec_t* rec; - const byte* field; - ulint len; - ulint i; - mtr_t mtr; - size_t id_len; - - ut_ad(mutex_own(&dict_sys.mutex)); - - id_len = strlen(foreign->id); - - foreign->foreign_col_names = static_cast<const char**>( - mem_heap_alloc(foreign->heap, - foreign->n_fields * sizeof(void*))); - - foreign->referenced_col_names = static_cast<const char**>( - mem_heap_alloc(foreign->heap, - foreign->n_fields * sizeof(void*))); - - mtr_start(&mtr); - - sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS"); - - sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes); - ut_ad(!dict_table_is_comp(sys_foreign_cols)); - - tuple = dtuple_create(foreign->heap, 1); - dfield = dtuple_get_nth_field(tuple, 0); - - dfield_set_data(dfield, foreign->id, id_len); - dict_index_copy_types(tuple, sys_index, 1); - - btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur, &mtr); - for (i = 0; i < foreign->n_fields; i++) { - - rec = btr_pcur_get_rec(&pcur); - - ut_a(btr_pcur_is_on_user_rec(&pcur)); - ut_a(!rec_get_deleted_flag(rec, 0)); - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__ID, &len); - - if (len != id_len || memcmp(foreign->id, field, len)) { - const rec_t* pos; - ulint pos_len; - const rec_t* for_col_name; - ulint for_col_name_len; - const rec_t* ref_col_name; - ulint ref_col_name_len; - - pos = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__POS, - &pos_len); - - for_col_name = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__FOR_COL_NAME, - &for_col_name_len); - - ref_col_name = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__REF_COL_NAME, - &ref_col_name_len); - - ib::fatal sout; - - sout << "Unable to load column names for foreign" - " key '" << foreign->id - << "' because it was not found in" - " InnoDB internal table SYS_FOREIGN_COLS. The" - " closest entry we found is:" - " (ID='"; - sout.write(field, len); - sout << "', POS=" << mach_read_from_4(pos) - << ", FOR_COL_NAME='"; - sout.write(for_col_name, for_col_name_len); - sout << "', REF_COL_NAME='"; - sout.write(ref_col_name, ref_col_name_len); - sout << "')"; - } - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__POS, &len); - ut_a(len == 4); - ut_a(i == mach_read_from_4(field)); - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__FOR_COL_NAME, &len); - foreign->foreign_col_names[i] = mem_heap_strdupl( - foreign->heap, (char*) field, len); - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_COLS__REF_COL_NAME, &len); - foreign->referenced_col_names[i] = mem_heap_strdupl( - foreign->heap, (char*) field, len); - - btr_pcur_move_to_next_user_rec(&pcur, &mtr); - } - - btr_pcur_close(&pcur); - mtr_commit(&mtr); -} - -/***********************************************************************//** -Loads a foreign key constraint to the dictionary cache. If the referenced -table is not yet loaded, it is added in the output parameter (fk_tables). -@return DB_SUCCESS or error code */ -static MY_ATTRIBUTE((nonnull(1), warn_unused_result)) -dberr_t -dict_load_foreign( -/*==============*/ - const char* id, - /*!< in: foreign constraint id, must be - '\0'-terminated */ - const char** col_names, - /*!< in: column names, or NULL - to use foreign->foreign_table->col_names */ - bool check_recursive, - /*!< in: whether to record the foreign table - parent count to avoid unlimited recursive - load of chained foreign tables */ - bool check_charsets, - /*!< in: whether to check charset - compatibility */ - dict_err_ignore_t ignore_err, - /*!< in: error to be ignored */ - dict_names_t& fk_tables) - /*!< out: the foreign key constraint is added - to the dictionary cache only if the referenced - table is already in cache. Otherwise, the - foreign key constraint is not added to cache, - and the referenced table is added to this - stack. */ -{ - dict_foreign_t* foreign; - dict_table_t* sys_foreign; - btr_pcur_t pcur; - dict_index_t* sys_index; - dtuple_t* tuple; - mem_heap_t* heap2; - dfield_t* dfield; - const rec_t* rec; - const byte* field; - ulint len; - mtr_t mtr; - dict_table_t* for_table; - dict_table_t* ref_table; - size_t id_len; - - DBUG_ENTER("dict_load_foreign"); - DBUG_PRINT("dict_load_foreign", - ("id: '%s', check_recursive: %d", id, check_recursive)); - - ut_ad(mutex_own(&dict_sys.mutex)); - - id_len = strlen(id); - - heap2 = mem_heap_create(1000); - - mtr_start(&mtr); - - sys_foreign = dict_table_get_low("SYS_FOREIGN"); - - sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes); - ut_ad(!dict_table_is_comp(sys_foreign)); - - tuple = dtuple_create(heap2, 1); - dfield = dtuple_get_nth_field(tuple, 0); - - dfield_set_data(dfield, id, id_len); - dict_index_copy_types(tuple, sys_index, 1); - - btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur, &mtr); - rec = btr_pcur_get_rec(&pcur); - - if (!btr_pcur_is_on_user_rec(&pcur) - || rec_get_deleted_flag(rec, 0)) { - /* Not found */ - - ib::error() << "Cannot load foreign constraint " << id - << ": could not find the relevant record in " - << "SYS_FOREIGN"; - - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap2); - - DBUG_RETURN(DB_ERROR); - } - - field = rec_get_nth_field_old(rec, DICT_FLD__SYS_FOREIGN__ID, &len); - - /* Check if the id in record is the searched one */ - if (len != id_len || memcmp(id, field, len)) { - { - ib::error err; - err << "Cannot load foreign constraint " << id - << ": found "; - err.write(field, len); - err << " instead in SYS_FOREIGN"; - } - - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap2); - - DBUG_RETURN(DB_ERROR); - } - - /* Read the table names and the number of columns associated - with the constraint */ - - mem_heap_free(heap2); - - foreign = dict_mem_foreign_create(); - - uint32_t n_fields_and_type = mach_read_from_4( - rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN__N_COLS, &len)); - - ut_a(len == 4); - - /* We store the type in the bits 24..29 of n_fields_and_type. */ - - foreign->type = (n_fields_and_type >> 24) & ((1U << 6) - 1); - foreign->n_fields = n_fields_and_type & dict_index_t::MAX_N_FIELDS; - - foreign->id = mem_heap_strdupl(foreign->heap, id, id_len); - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN__FOR_NAME, &len); - - foreign->foreign_table_name = mem_heap_strdupl( - foreign->heap, (char*) field, len); - dict_mem_foreign_table_name_lookup_set(foreign, TRUE); - - const ulint foreign_table_name_len = len; - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN__REF_NAME, &len); - foreign->referenced_table_name = mem_heap_strdupl( - foreign->heap, (char*) field, len); - dict_mem_referenced_table_name_lookup_set(foreign, TRUE); - - btr_pcur_close(&pcur); - mtr_commit(&mtr); - - dict_load_foreign_cols(foreign); - - ref_table = dict_table_check_if_in_cache_low( - foreign->referenced_table_name_lookup); - for_table = dict_table_check_if_in_cache_low( - foreign->foreign_table_name_lookup); - - if (!for_table) { - /* To avoid recursively loading the tables related through - the foreign key constraints, the child table name is saved - here. The child table will be loaded later, along with its - foreign key constraint. */ - - ut_a(ref_table != NULL); - fk_tables.push_back( - mem_heap_strdupl(ref_table->heap, - foreign->foreign_table_name_lookup, - foreign_table_name_len)); - - dict_foreign_remove_from_cache(foreign); - DBUG_RETURN(DB_SUCCESS); - } - - ut_a(for_table || ref_table); - - /* Note that there may already be a foreign constraint object in - the dictionary cache for this constraint: then the following - call only sets the pointers in it to point to the appropriate table - and index objects and frees the newly created object foreign. - Adding to the cache should always succeed since we are not creating - a new foreign key constraint but loading one from the data - dictionary. */ - - DBUG_RETURN(dict_foreign_add_to_cache(foreign, col_names, - check_charsets, - ignore_err)); -} - -/***********************************************************************//** -Loads foreign key constraints where the table is either the foreign key -holder or where the table is referenced by a foreign key. Adds these -constraints to the data dictionary. - -The foreign key constraint is loaded only if the referenced table is also -in the dictionary cache. If the referenced table is not in dictionary -cache, then it is added to the output parameter (fk_tables). - -@return DB_SUCCESS or error code */ -dberr_t -dict_load_foreigns( - const char* table_name, /*!< in: table name */ - const char** col_names, /*!< in: column names, or NULL - to use table->col_names */ - bool check_recursive,/*!< in: Whether to check - recursive load of tables - chained by FK */ - bool check_charsets, /*!< in: whether to check - charset compatibility */ - dict_err_ignore_t ignore_err, /*!< in: error to be ignored */ - dict_names_t& fk_tables) - /*!< out: stack of table - names which must be loaded - subsequently to load all the - foreign key constraints. */ -{ - ulint tuple_buf[(DTUPLE_EST_ALLOC(1) + sizeof(ulint) - 1) - / sizeof(ulint)]; - btr_pcur_t pcur; - dtuple_t* tuple; - dfield_t* dfield; - dict_index_t* sec_index; - dict_table_t* sys_foreign; - const rec_t* rec; - const byte* field; - ulint len; - dberr_t err; - mtr_t mtr; - - DBUG_ENTER("dict_load_foreigns"); - - ut_ad(mutex_own(&dict_sys.mutex)); - - sys_foreign = dict_table_get_low("SYS_FOREIGN"); - - if (sys_foreign == NULL) { - /* No foreign keys defined yet in this database */ - - ib::info() << "No foreign key system tables in the database"; - DBUG_RETURN(DB_ERROR); - } - - ut_ad(!dict_table_is_comp(sys_foreign)); - mtr_start(&mtr); - - /* Get the secondary index based on FOR_NAME from table - SYS_FOREIGN */ - - sec_index = dict_table_get_next_index( - dict_table_get_first_index(sys_foreign)); - ut_ad(!dict_index_is_clust(sec_index)); -start_load: - - tuple = dtuple_create_from_mem(tuple_buf, sizeof(tuple_buf), 1, 0); - dfield = dtuple_get_nth_field(tuple, 0); - - dfield_set_data(dfield, table_name, strlen(table_name)); - dict_index_copy_types(tuple, sec_index, 1); - - btr_pcur_open_on_user_rec(sec_index, tuple, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur, &mtr); -loop: - rec = btr_pcur_get_rec(&pcur); - - if (!btr_pcur_is_on_user_rec(&pcur)) { - /* End of index */ - - goto load_next_index; - } - - /* Now we have the record in the secondary index containing a table - name and a foreign constraint ID */ - - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_FOR_NAME__NAME, &len); - - /* Check if the table name in the record is the one searched for; the - following call does the comparison in the latin1_swedish_ci - charset-collation, in a case-insensitive way. */ - - if (0 != cmp_data_data(dfield_get_type(dfield)->mtype, - dfield_get_type(dfield)->prtype, - static_cast<const byte*>( - dfield_get_data(dfield)), - dfield_get_len(dfield), - field, len)) { - - goto load_next_index; - } - - /* Since table names in SYS_FOREIGN are stored in a case-insensitive - order, we have to check that the table name matches also in a binary - string comparison. On Unix, MySQL allows table names that only differ - in character case. If lower_case_table_names=2 then what is stored - may not be the same case, but the previous comparison showed that they - match with no-case. */ - - if (rec_get_deleted_flag(rec, 0)) { - goto next_rec; - } - - if (innobase_get_lower_case_table_names() != 2 - && memcmp(field, table_name, len)) { - goto next_rec; - } - - /* Now we get a foreign key constraint id */ - field = rec_get_nth_field_old( - rec, DICT_FLD__SYS_FOREIGN_FOR_NAME__ID, &len); - - /* Copy the string because the page may be modified or evicted - after mtr_commit() below. */ - char fk_id[MAX_TABLE_NAME_LEN + 1]; - - ut_a(len <= MAX_TABLE_NAME_LEN); - memcpy(fk_id, field, len); - fk_id[len] = '\0'; - - btr_pcur_store_position(&pcur, &mtr); - - mtr_commit(&mtr); - - /* Load the foreign constraint definition to the dictionary cache */ - - err = dict_load_foreign(fk_id, col_names, - check_recursive, check_charsets, ignore_err, - fk_tables); - - if (err != DB_SUCCESS) { - btr_pcur_close(&pcur); - - DBUG_RETURN(err); - } - - mtr_start(&mtr); - - btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr); -next_rec: - btr_pcur_move_to_next_user_rec(&pcur, &mtr); - - goto loop; - -load_next_index: - btr_pcur_close(&pcur); - mtr_commit(&mtr); - - sec_index = dict_table_get_next_index(sec_index); - - if (sec_index != NULL) { - - mtr_start(&mtr); - - /* Switch to scan index on REF_NAME, fk_max_recusive_level - already been updated when scanning FOR_NAME index, no need to - update again */ - check_recursive = FALSE; - - goto start_load; - } - - DBUG_RETURN(DB_SUCCESS); -} - /***********************************************************************//** Loads a table id based on the index id. @return true if found */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 429e841425f..d6c486ca8f1 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5723,6 +5723,14 @@ ha_innobase::open(const char* name, int, uint) } } + mutex_enter(&dict_sys.mutex); + dberr_t err = dict_load_foreigns(ib_table, table->s, NULL, false, DICT_ERR_IGNORE_FK_NOKEY); + mutex_exit(&dict_sys.mutex); + if (err != DB_SUCCESS) { + DBUG_RETURN(convert_error_code_to_mysql( + err, ib_table->flags, NULL)); + } + m_prebuilt = row_create_prebuilt(ib_table, table->s->reclength); m_prebuilt->default_rec = table->s->default_values; @@ -11939,11 +11947,9 @@ create_table_info_t::create_foreign_keys() { dict_foreign_set local_fk_set; dict_foreign_set_free local_fk_set_free(local_fk_set); - dberr_t error; ulint number = 1; - static const unsigned MAX_COLS_PER_FK = 500; - const char* column_names[MAX_COLS_PER_FK]; - const char* ref_column_names[MAX_COLS_PER_FK]; + const char* column_names[MAX_NUM_FK_COLUMNS]; + const char* ref_column_names[MAX_NUM_FK_COLUMNS]; char create_name[MAX_DATABASE_NAME_LEN + 1 + MAX_TABLE_NAME_LEN + 1]; dict_index_t* index = NULL; @@ -12062,7 +12068,8 @@ create_table_info_t::create_foreign_keys() } if (foreign->id == NULL) { - error = dict_create_add_foreign_id( + // TODO: is it needed? + dberr_t error = dict_create_add_foreign_id( &number, table->name.m_name, foreign); if (error != DB_SUCCESS) { dict_foreign_free(foreign); @@ -12098,7 +12105,7 @@ create_table_info_t::create_foreign_keys() return (DB_CANNOT_ADD_CONSTRAINT); } ++i; - if (i >= MAX_COLS_PER_FK) { + if (i >= MAX_NUM_FK_COLUMNS) { key_text k(fk); ib_foreign_warn( m_trx, DB_CANNOT_ADD_CONSTRAINT, @@ -12107,7 +12114,7 @@ create_table_info_t::create_foreign_keys() " failed. Too many columns: %u (%u " "allowed).", operation, create_name, k.str(), i, - MAX_COLS_PER_FK); + MAX_NUM_FK_COLUMNS); return (DB_CANNOT_ADD_CONSTRAINT); } } @@ -12335,28 +12342,26 @@ create_table_info_t::create_foreign_keys() return (DB_NO_FK_ON_S_BASE_COL); } - /**********************************************************/ - /* The following call adds the foreign key constraints - to the data dictionary system tables on disk */ - m_trx->op_info = "adding foreign keys"; + table->foreign_set.insert(local_fk_set.begin(), + local_fk_set.end()); - trx_start_if_not_started_xa(m_trx, true); - - trx_set_dict_operation(m_trx, TRX_DICT_OP_TABLE); - - error = dict_create_add_foreigns_to_dictionary(local_fk_set, table, m_trx); + for (dict_foreign_t *foreign: local_fk_set) { + if (!foreign->referenced_table) { + continue; + } + auto ret = foreign->referenced_table->referenced_set.insert(foreign); + // Duplicate constraint id in referenced table + if (!ret.second) { + ut_ad(0); + return DB_CANNOT_ADD_CONSTRAINT; + } + } - if (error == DB_SUCCESS) { + local_fk_set.clear(); - table->foreign_set.insert(local_fk_set.begin(), - local_fk_set.end()); - std::for_each(local_fk_set.begin(), local_fk_set.end(), - dict_foreign_add_to_referenced_table()); - local_fk_set.clear(); + dict_mem_table_fill_foreign_vcol_set(table); - dict_mem_table_fill_foreign_vcol_set(table); - } - return (error); + return (DB_SUCCESS); } /** Create the internal innodb table. @@ -12482,17 +12487,13 @@ int create_table_info_t::create_table(bool create_fk) ? create_foreign_keys() : DB_SUCCESS; if (err == DB_SUCCESS) { + bool check_foreigns = !thd_test_options(m_thd, OPTION_NO_FOREIGN_KEY_CHECKS); /* Check that also referencing constraints are ok */ - dict_names_t fk_tables; - err = dict_load_foreigns(m_table_name, NULL, - false, true, - DICT_ERR_IGNORE_NONE, - fk_tables); - while (err == DB_SUCCESS && !fk_tables.empty()) { - dict_load_table(fk_tables.front(), - DICT_ERR_IGNORE_NONE); - fk_tables.pop_front(); - } + // TODO: is it needed here? + err = dict_load_foreigns(m_table, m_form->s, NULL, true, + check_foreigns + ? DICT_ERR_IGNORE_NONE + : DICT_ERR_IGNORE_FK_NOKEY); } switch (err) { @@ -12979,7 +12980,7 @@ ha_innobase::create( /*****************************************************************//** Discards or imports an InnoDB tablespace. -@return 0 == success, -1 == error */ +@return 0 == success, HA_ERR_... == error */ int ha_innobase::discard_or_import_tablespace( @@ -13086,15 +13087,26 @@ ha_innobase::discard_or_import_tablespace( dict_sys.remove(m_prebuilt->table); m_prebuilt->table = dict_table_open_on_id(id, TRUE, DICT_TABLE_OP_NORMAL); - mutex_exit(&dict_sys.mutex); if (!m_prebuilt->table) { err = DB_TABLE_NOT_FOUND; } else { - if (const Field* ai = table->found_next_number_field) { - initialize_auto_increment(m_prebuilt->table, ai); + err = dict_load_foreigns(m_prebuilt->table, NULL, NULL, false, DICT_ERR_IGNORE_FK_NOKEY); + if (err != DB_SUCCESS) { + dict_table_close(m_prebuilt->table, true, false); + m_prebuilt->table = NULL; } - dict_stats_init(m_prebuilt->table); } + mutex_exit(&dict_sys.mutex); + + if (err != DB_SUCCESS) { + DBUG_RETURN(convert_error_code_to_mysql( + err, m_prebuilt->table->flags, NULL)); + } + + if (const Field* ai = table->found_next_number_field) { + initialize_auto_increment(m_prebuilt->table, ai); + } + dict_stats_init(m_prebuilt->table); if (dict_stats_is_persistent_enabled(m_prebuilt->table)) { dberr_t ret; @@ -20030,8 +20042,6 @@ i_s_innodb_sys_tablestats, i_s_innodb_sys_indexes, i_s_innodb_sys_columns, i_s_innodb_sys_fields, -i_s_innodb_sys_foreign, -i_s_innodb_sys_foreign_cols, i_s_innodb_sys_tablespaces, i_s_innodb_sys_datafiles, i_s_innodb_sys_virtual, @@ -21448,3 +21458,193 @@ void ins_node_t::vers_update_end(row_prebuilt_t *prebuilt, bool history_row) mem_heap_free(local_heap); } } + +dberr_t +dict_load_foreigns( + dict_table_t* table, + TABLE_SHARE* share, + const char** col_names, /*!< in: column names, or NULL + to use table->col_names */ + bool check_charsets, /*!< in: whether to check + charset compatibility */ + dict_err_ignore_t ignore_err) /*!< in: error to be ignored */ +{ + Share_acquire sa; + TABLE_LIST tl; + dict_foreign_t* foreign; + char buf[MAX_FULL_NAME_LEN + 1]; + char *bufptr= buf; + size_t len; + dberr_t err; + const char* column_names[MAX_NUM_FK_COLUMNS]; + const char* ref_column_names[MAX_NUM_FK_COLUMNS]; + ut_ad(table); + if (table->is_system_db) + return DB_SUCCESS; + if (!share) { + LEX_CSTRING db; + LEX_CSTRING table_name; + char db_buf[NAME_LEN + 1]; + char tbl_buf[NAME_LEN + 1]; + + if (!current_thd) + return DB_CANNOT_ADD_CONSTRAINT; + + if (!table->parse_name<true>(db_buf, tbl_buf, &db.length, &table_name.length)) { + return DB_CANNOT_ADD_CONSTRAINT; + } + + db.str= db_buf; + table_name.str= tbl_buf; + + tl.init_one_table(&db, &table_name, &table_name, TL_IGNORE); + sa.acquire(current_thd, tl); + if (!sa.share) { + return DB_CANNOT_ADD_CONSTRAINT; + } + share= sa.share; + } + + for (FK_info &fk: share->foreign_keys) + { + foreign = dict_mem_foreign_create(); + if (!innobase_set_foreign_key_option(foreign, &fk)) { + return DB_CANNOT_ADD_CONSTRAINT; + } + + // NB: see innobase_get_foreign_key_info() for index checks + ut_ad(fk.foreign_fields.elements == fk.referenced_fields.elements); + ut_ad(fk.foreign_fields.elements <= MAX_NUM_FK_COLUMNS); + DBUG_ASSERT(fk.foreign_fields.elements <= 0x3ff); + foreign->n_fields = fk.foreign_fields.elements & 0x3ff; + + List_iterator_fast<Lex_cstring> ref_it(fk.referenced_fields); + uint i= 0; + for (Lex_cstring &fcol: fk.foreign_fields) + { + Lex_cstring &ref_col = *(ref_it++); + column_names[i] = mem_heap_strdupl(foreign->heap, LEX_STRING_WITH_LEN(fcol)); + if (!column_names[i]) + return DB_OUT_OF_MEMORY; + ref_column_names[i] = mem_heap_strdupl(foreign->heap, LEX_STRING_WITH_LEN(ref_col)); + if (!ref_column_names[i]) + return DB_OUT_OF_MEMORY; + ++i; + } + + size_t dblen = table->name.dblen() + 1; + foreign->id = static_cast<char*>(mem_heap_alloc( + foreign->heap, dblen + fk.foreign_id.length + 1)); + if (!foreign->id) + return DB_OUT_OF_MEMORY; + memcpy(foreign->id, table->name.m_name, dblen); + strcpy(foreign->id + dblen, fk.foreign_id.str); + + foreign->foreign_table_name = mem_heap_strdup(foreign->heap, table->name.m_name); + if (!foreign->foreign_table_name) + return DB_OUT_OF_MEMORY; + + if (dict_table_t::build_name(LEX_STRING_WITH_LEN(fk.referenced_db), + LEX_STRING_WITH_LEN(fk.referenced_table), bufptr, len)) { + return DB_CANNOT_ADD_CONSTRAINT; + } + + foreign->referenced_table_name = mem_heap_strdupl(foreign->heap, buf, len); + if (!foreign->referenced_table_name) + return DB_OUT_OF_MEMORY; + dict_mem_foreign_table_name_lookup_set(foreign, true); + dict_mem_referenced_table_name_lookup_set(foreign, true); + foreign->foreign_col_names = static_cast<const char**>( + mem_heap_alloc(foreign->heap, + foreign->n_fields * sizeof(void*))); + if (!foreign->foreign_col_names) { + return (DB_OUT_OF_MEMORY); + } + + foreign->referenced_col_names = static_cast<const char**>( + mem_heap_alloc(foreign->heap, + foreign->n_fields * sizeof(void*))); + if (!foreign->referenced_col_names) { + return (DB_OUT_OF_MEMORY); + } + + memcpy(foreign->foreign_col_names, column_names, + foreign->n_fields * sizeof(void*)); + + memcpy(foreign->referenced_col_names, ref_column_names, + foreign->n_fields * sizeof(void*)); + + /* Note that there may already be a foreign constraint object in + the dictionary cache for this constraint: then the following + call only sets the pointers in it to point to the appropriate table + and index objects and frees the newly created object foreign. + Adding to the cache should always succeed since we are not creating + a new foreign key constraint but loading one from the data + dictionary. */ + + err = dict_foreign_add_to_cache(foreign, col_names, check_charsets, ignore_err); + if (err != DB_SUCCESS) + return err; + } + + if (share->referenced_keys.elements > table->referenced_set.size()) + { + /* We don't have some foreign table because it was created earlier that this table. */ + mbd::set<Table_name> tables_missing; + for (FK_info &rk: share->referenced_keys) + { + if (0 == cmp_table(rk.foreign_db, share->db) && + 0 == cmp_table(rk.foreign_table, share->table_name)) + continue; + if (!tables_missing.insert({rk.foreign_db, rk.foreign_table})) { + return DB_OUT_OF_MEMORY; + } + } + /* In this case we assume that there is no referenced keys of that table in referenced_set. + If there are any we just skip that table from reloading. */ + for (dict_foreign_t *rk: table->referenced_set) + { + char db_buf[NAME_LEN + 1]; + char tbl_buf[NAME_LEN + 1]; + LEX_CSTRING db = { db_buf, 0 }; + LEX_CSTRING table_name = { tbl_buf, 0 }; + + if (!rk->foreign_table->parse_name<true>(db_buf, tbl_buf, &db.length, &table_name.length)) { + return DB_CANNOT_ADD_CONSTRAINT; + } + + auto it = tables_missing.find({db, table_name}); + if (it == tables_missing.end()) { + /* We don't know this foreign table. Reloading its foreign set will update this referenced set. */ + continue; + } + tables_missing.erase(it); + } + + for (const Table_name &t: tables_missing) + { + if (dict_table_t::build_name(LEX_STRING_WITH_LEN(t.db), + LEX_STRING_WITH_LEN(t.name), bufptr, len)) { + return DB_CANNOT_ADD_CONSTRAINT; + } + dict_table_t *for_table = dict_table_check_if_in_cache_low(buf); + if (!for_table) + { + // not possible for DML (foreign table is written) + continue; + } + err = dict_load_foreigns(for_table, NULL, NULL, check_charsets, ignore_err); + if (err != DB_SUCCESS) { + return err; + } + for (dict_foreign_t *fk: for_table->foreign_set) + { + // Actually we have to exclude keys not matching current table + err = dict_foreign_add_to_cache(fk, NULL, false, ignore_err); + if (err != DB_SUCCESS) + return err; + } + } + } + return DB_SUCCESS; +} diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 0a52d936835..80cac0887a2 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -972,3 +972,26 @@ int innobase_rollback_by_xid(handlerton* hton, XID* xid); /** Free tablespace resources allocated. */ void innobase_space_shutdown(); + +/*************************************************************//** +Set foreign key options +@return true if successfully set */ +MY_ATTRIBUTE((nonnull, warn_unused_result)) +bool +innobase_set_foreign_key_option( +/*============================*/ + dict_foreign_t* foreign, /*!< in:InnoDB Foreign key */ + FK_info* fk_key); /*!< in: Foreign key info from + MySQL */ + +dberr_t +dict_load_foreigns( +/*===============*/ + dict_table_t* table, + TABLE_SHARE* share, + const char** col_names, /*!< in: column names, or NULL + to use table->col_names */ + bool check_charsets, /*!< in: whether to check + charset compatibility */ + dict_err_ignore_t ignore_err) /*!< in: error to be ignored */ + MY_ATTRIBUTE((warn_unused_result)); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 4238d339c32..7cd6d96881b 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2688,7 +2688,7 @@ innobase_check_fk_option( /*************************************************************//** Set foreign key options @return true if successfully set */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) +MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_set_foreign_key_option( /*============================*/ @@ -8798,56 +8798,6 @@ func_exit: DBUG_RETURN(fail); } -/** Drop a FOREIGN KEY constraint from the data dictionary tables. -@param trx data dictionary transaction -@param table_name Table name in MySQL -@param foreign_id Foreign key constraint identifier -@retval true Failure -@retval false Success */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) -bool -innobase_drop_foreign_try( -/*======================*/ - trx_t* trx, - const char* table_name, - const char* foreign_id) -{ - DBUG_ENTER("innobase_drop_foreign_try"); - - DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_d(dict_sys.assert_locked()); - - /* Drop the constraint from the data dictionary. */ - static const char sql[] = - "PROCEDURE DROP_FOREIGN_PROC () IS\n" - "BEGIN\n" - "DELETE FROM SYS_FOREIGN WHERE ID=:id;\n" - "DELETE FROM SYS_FOREIGN_COLS WHERE ID=:id;\n" - "END;\n"; - - dberr_t error; - pars_info_t* info; - - info = pars_info_create(); - pars_info_add_str_literal(info, "id", foreign_id); - - trx->op_info = "dropping foreign key constraint from dictionary"; - error = que_eval_sql(info, sql, FALSE, trx); - trx->op_info = ""; - - DBUG_EXECUTE_IF("ib_drop_foreign_error", - error = DB_OUT_OF_FILE_SPACE;); - - if (error != DB_SUCCESS) { - my_error_innodb(error, table_name, 0); - trx->error_state = DB_SUCCESS; - DBUG_RETURN(true); - } - - DBUG_RETURN(false); -} - /** Rename a column in the data dictionary tables. @param[in] ctx ALTER TABLE context @param[in,out] trx Data dictionary transaction @@ -8964,29 +8914,11 @@ rename_foreign: continue; } - pars_info_t* info = pars_info_create(); - - pars_info_add_str_literal(info, "id", foreign->id); - pars_info_add_int4_literal(info, "nth", i); - pars_info_add_str_literal(info, "new", to); - - error = que_eval_sql( - info, - "PROCEDURE RENAME_SYS_FOREIGN_F_PROC () IS\n" - "BEGIN\n" - "UPDATE SYS_FOREIGN_COLS\n" - "SET FOR_COL_NAME=:new\n" - "WHERE ID=:id AND POS=:nth;\n" - "END;\n", - FALSE, trx); - - if (error != DB_SUCCESS) { - goto err_exit; - } foreign_modified = true; } if (foreign_modified) { + // TODO: do we need dict_foreign_remove_from_cache() here? fk_evict.insert(foreign); } } @@ -9006,25 +8938,6 @@ rename_foreign: continue; } - pars_info_t* info = pars_info_create(); - - pars_info_add_str_literal(info, "id", foreign->id); - pars_info_add_int4_literal(info, "nth", i); - pars_info_add_str_literal(info, "new", to); - - error = que_eval_sql( - info, - "PROCEDURE RENAME_SYS_FOREIGN_R_PROC () IS\n" - "BEGIN\n" - "UPDATE SYS_FOREIGN_COLS\n" - "SET REF_COL_NAME=:new\n" - "WHERE ID=:id AND POS=:nth;\n" - "END;\n", - FALSE, trx); - - if (error != DB_SUCCESS) { - goto err_exit; - } foreign_modified = true; } @@ -9478,93 +9391,6 @@ commit_set_autoinc( DBUG_RETURN(false); } -/** Add or drop foreign key constraints to the data dictionary tables, -but do not touch the data dictionary cache. -@param ha_alter_info Data used during in-place alter -@param ctx In-place ALTER TABLE context -@param trx Data dictionary transaction -@param table_name Table name in MySQL -@retval true Failure -@retval false Success -*/ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) -bool -innobase_update_foreign_try( -/*========================*/ - ha_innobase_inplace_ctx*ctx, - trx_t* trx, - const char* table_name) -{ - ulint foreign_id; - ulint i; - - DBUG_ENTER("innobase_update_foreign_try"); - - foreign_id = dict_table_get_highest_foreign_id(ctx->new_table); - - foreign_id++; - - for (i = 0; i < ctx->num_to_add_fk; i++) { - dict_foreign_t* fk = ctx->add_fk[i]; - - ut_ad(fk->foreign_table == ctx->new_table - || fk->foreign_table == ctx->old_table); - - dberr_t error = dict_create_add_foreign_id( - &foreign_id, ctx->old_table->name.m_name, fk); - - if (error != DB_SUCCESS) { - my_error(ER_TOO_LONG_IDENT, MYF(0), - fk->id); - DBUG_RETURN(true); - } - - if (!fk->foreign_index) { - fk->foreign_index = dict_foreign_find_index( - ctx->new_table, ctx->col_names, - fk->foreign_col_names, - fk->n_fields, fk->referenced_index, TRUE, - fk->type - & (DICT_FOREIGN_ON_DELETE_SET_NULL - | DICT_FOREIGN_ON_UPDATE_SET_NULL), - NULL, NULL, NULL); - if (!fk->foreign_index) { - my_error(ER_FK_INCORRECT_OPTION, - MYF(0), table_name, fk->id); - DBUG_RETURN(true); - } - } - - /* The fk->foreign_col_names[] uses renamed column - names, while the columns in ctx->old_table have not - been renamed yet. */ - error = dict_create_add_foreign_to_dictionary( - ctx->old_table->name.m_name, fk, trx); - - DBUG_EXECUTE_IF( - "innodb_test_cannot_add_fk_system", - error = DB_ERROR;); - - if (error != DB_SUCCESS) { - my_error(ER_FK_FAIL_ADD_SYSTEM, MYF(0), - fk->id); - DBUG_RETURN(true); - } - } - - for (i = 0; i < ctx->num_to_drop_fk; i++) { - dict_foreign_t* fk = ctx->drop_fk[i]; - - DBUG_ASSERT(fk->foreign_table == ctx->old_table); - - if (innobase_drop_foreign_try(trx, table_name, fk->id)) { - DBUG_RETURN(true); - } - } - - DBUG_RETURN(false); -} - /** Update the foreign key constraint definitions in the data dictionary cache after the changes to data dictionary tables were committed. @param ctx In-place ALTER TABLE context @@ -9575,7 +9401,8 @@ dberr_t innobase_update_foreign_cache( /*==========================*/ ha_innobase_inplace_ctx* ctx, - THD* user_thd) + THD* user_thd, + TABLE* altered_table) { dict_table_t* user_table; dberr_t err = DB_SUCCESS; @@ -9615,23 +9442,19 @@ innobase_update_foreign_cache( /* Load the old or added foreign keys from the data dictionary and prevent the table from being evicted from the data dictionary cache (work around the lack of WL#6049). */ - dict_names_t fk_tables; - err = dict_load_foreigns(user_table->name.m_name, - ctx->col_names, false, true, - DICT_ERR_IGNORE_NONE, - fk_tables); + err = dict_load_foreigns(user_table, altered_table->s, + ctx->col_names, true, + DICT_ERR_IGNORE_NONE); if (err == DB_CANNOT_ADD_CONSTRAINT) { - fk_tables.clear(); /* It is possible there are existing foreign key are loaded with "foreign_key checks" off, so let's retry the loading with charset_check is off */ - err = dict_load_foreigns(user_table->name.m_name, - ctx->col_names, false, false, - DICT_ERR_IGNORE_NONE, - fk_tables); + err = dict_load_foreigns(user_table, altered_table->s, + ctx->col_names, false, + DICT_ERR_IGNORE_NONE); /* The load with "charset_check" off is successful, warn the user that the foreign key has loaded with mis-matched @@ -9647,27 +9470,68 @@ innobase_update_foreign_cache( } } - /* For complete loading of foreign keys, all associated tables must - also be loaded. */ - while (err == DB_SUCCESS && !fk_tables.empty()) { - dict_table_t* table = dict_load_table( - fk_tables.front(), DICT_ERR_IGNORE_NONE); + DBUG_RETURN(err); +} - if (table == NULL) { - err = DB_TABLE_NOT_FOUND; - ib::error() - << "Failed to load table '" - << table_name_t(const_cast<char*> - (fk_tables.front())) - << "' which has a foreign key constraint with" - << " table '" << user_table->name << "'."; - break; +/** Add or drop foreign key constraints to the data dictionary tables, +but do not touch the data dictionary cache. +@param ha_alter_info Data used during in-place alter +@param ctx In-place ALTER TABLE context +@param trx Data dictionary transaction +@param table_name Table name in MySQL +@retval true Failure +@retval false Success +*/ +static MY_ATTRIBUTE((nonnull, warn_unused_result)) +bool +innobase_update_foreign_try( +/*========================*/ + ha_innobase_inplace_ctx*ctx, + trx_t* trx, + const char* table_name) +{ + ulint foreign_id; + ulint i; + + DBUG_ENTER("innobase_update_foreign_try"); + + foreign_id = dict_table_get_highest_foreign_id(ctx->new_table); + + foreign_id++; + + for (i = 0; i < ctx->num_to_add_fk; i++) { + dict_foreign_t* fk = ctx->add_fk[i]; + + ut_ad(fk->foreign_table == ctx->new_table + || fk->foreign_table == ctx->old_table); + + dberr_t error = dict_create_add_foreign_id( + &foreign_id, ctx->old_table->name.m_name, fk); + + if (error != DB_SUCCESS) { + my_error(ER_TOO_LONG_IDENT, MYF(0), + fk->id); + DBUG_RETURN(true); } - fk_tables.pop_front(); + if (!fk->foreign_index) { + fk->foreign_index = dict_foreign_find_index( + ctx->new_table, ctx->col_names, + fk->foreign_col_names, + fk->n_fields, fk->referenced_index, TRUE, + fk->type + & (DICT_FOREIGN_ON_DELETE_SET_NULL + | DICT_FOREIGN_ON_UPDATE_SET_NULL), + NULL, NULL, NULL); + if (!fk->foreign_index) { + my_error(ER_FK_INCORRECT_OPTION, + MYF(0), table_name, fk->id); + DBUG_RETURN(true); + } + } } - DBUG_RETURN(err); + DBUG_RETURN(false); } /** Changes SYS_COLUMNS.PRTYPE for one column. @@ -11045,7 +10909,7 @@ ha_innobase::commit_inplace_alter_table( DBUG_PRINT("to_be_dropped", ("table: %s", ctx->old_table->name.m_name)); - if (innobase_update_foreign_cache(ctx, m_user_thd) + if (innobase_update_foreign_cache(ctx, m_user_thd, altered_table) != DB_SUCCESS && m_prebuilt->trx->check_foreigns) { foreign_fail: @@ -11058,7 +10922,7 @@ foreign_fail: } } else { bool fk_fail = innobase_update_foreign_cache( - ctx, m_user_thd) != DB_SUCCESS; + ctx, m_user_thd, altered_table) != DB_SUCCESS; if (!commit_cache_norebuild(ha_alter_info, ctx, altered_table, table, diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 125456c1ad4..78235df58ba 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -6058,398 +6058,6 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_fields = }; namespace Show { -/** SYS_FOREIGN ********************************************/ -/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FOREIGN */ -static ST_FIELD_INFO innodb_sys_foreign_fields_info[] = -{ -#define SYS_FOREIGN_ID 0 - Column("ID", Varchar(NAME_LEN + 1), NOT_NULL), - -#define SYS_FOREIGN_FOR_NAME 1 - Column("FOR_NAME", Varchar(NAME_LEN + 1), NOT_NULL), - -#define SYS_FOREIGN_REF_NAME 2 - Column("REF_NAME", Varchar(NAME_LEN + 1), NOT_NULL), - -#define SYS_FOREIGN_NUM_COL 3 - Column("N_COLS", ULong(), NOT_NULL), - -#define SYS_FOREIGN_TYPE 4 - Column("TYPE", ULong(), NOT_NULL), - - CEnd() -}; -} // namespace Show - -/**********************************************************************//** -Function to fill information_schema.innodb_sys_foreign with information -collected by scanning SYS_FOREIGN table. -@return 0 on success */ -static -int -i_s_dict_fill_sys_foreign( -/*======================*/ - THD* thd, /*!< in: thread */ - dict_foreign_t* foreign, /*!< in: table */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_foreign"); - - fields = table_to_fill->field; - - OK(field_store_string(fields[SYS_FOREIGN_ID], foreign->id)); - - OK(field_store_string(fields[SYS_FOREIGN_FOR_NAME], - foreign->foreign_table_name)); - - OK(field_store_string(fields[SYS_FOREIGN_REF_NAME], - foreign->referenced_table_name)); - - OK(fields[SYS_FOREIGN_NUM_COL]->store(foreign->n_fields)); - - OK(fields[SYS_FOREIGN_TYPE]->store(foreign->type)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} - -/*******************************************************************//** -Function to populate INFORMATION_SCHEMA.innodb_sys_foreign table. Loop -through each record in SYS_FOREIGN, and extract the foreign key -information. -@return 0 on success */ -static -int -i_s_sys_foreign_fill_table( -/*=======================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - Item* ) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - mem_heap_t* heap; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_foreign_fill_table"); - RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); - - /* deny access to user without PROCESS_ACL privilege */ - if (check_global_access(thd, PROCESS_ACL)) { - - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&dict_sys.mutex); - mtr_start(&mtr); - - rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN); - - while (rec) { - const char* err_msg; - dict_foreign_t foreign_rec; - - /* Populate a dict_foreign_t structure with information from - a SYS_FOREIGN row */ - err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec); - - mtr_commit(&mtr); - mutex_exit(&dict_sys.mutex); - - if (!err_msg) { - i_s_dict_fill_sys_foreign(thd, &foreign_rec, - tables->table); - } else { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, "%s", - err_msg); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mtr_start(&mtr); - mutex_enter(&dict_sys.mutex); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys.mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} - -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign -@return 0 on success */ -static -int -innodb_sys_foreign_init( -/*====================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_foreign_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = Show::innodb_sys_foreign_fields_info; - schema->fill_table = i_s_sys_foreign_fill_table; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_FOREIGN"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_FOREIGN"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_foreign_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* Maria extension */ - STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), -}; - -namespace Show { -/** SYS_FOREIGN_COLS ********************************************/ -/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS */ -static ST_FIELD_INFO innodb_sys_foreign_cols_fields_info[] = -{ -#define SYS_FOREIGN_COL_ID 0 - Column("ID", Varchar(NAME_LEN + 1), NOT_NULL), - -#define SYS_FOREIGN_COL_FOR_NAME 1 - Column("FOR_COL_NAME", Varchar(NAME_CHAR_LEN), NOT_NULL), - -#define SYS_FOREIGN_COL_REF_NAME 2 - Column("REF_COL_NAME", Varchar(NAME_CHAR_LEN), NOT_NULL), - -#define SYS_FOREIGN_COL_POS 3 - Column("POS", ULong(), NOT_NULL), - - CEnd() -}; -} // namespace Show - -/**********************************************************************//** -Function to fill information_schema.innodb_sys_foreign_cols with information -collected by scanning SYS_FOREIGN_COLS table. -@return 0 on success */ -static -int -i_s_dict_fill_sys_foreign_cols( -/*==========================*/ - THD* thd, /*!< in: thread */ - const char* name, /*!< in: foreign key constraint name */ - const char* for_col_name, /*!< in: referencing column name*/ - const char* ref_col_name, /*!< in: referenced column - name */ - ulint pos, /*!< in: column position */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_foreign_cols"); - - fields = table_to_fill->field; - - OK(field_store_string(fields[SYS_FOREIGN_COL_ID], name)); - - OK(field_store_string(fields[SYS_FOREIGN_COL_FOR_NAME], for_col_name)); - - OK(field_store_string(fields[SYS_FOREIGN_COL_REF_NAME], ref_col_name)); - - OK(fields[SYS_FOREIGN_COL_POS]->store(pos, true)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Function to populate INFORMATION_SCHEMA.innodb_sys_foreign_cols table. Loop -through each record in SYS_FOREIGN_COLS, and extract the foreign key column -information and fill the INFORMATION_SCHEMA.innodb_sys_foreign_cols table. -@return 0 on success */ -static -int -i_s_sys_foreign_cols_fill_table( -/*============================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - Item* ) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - mem_heap_t* heap; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_foreign_cols_fill_table"); - RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); - - /* deny access to user without PROCESS_ACL privilege */ - if (check_global_access(thd, PROCESS_ACL)) { - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&dict_sys.mutex); - mtr_start(&mtr); - - rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS); - - while (rec) { - const char* err_msg; - const char* name; - const char* for_col_name; - const char* ref_col_name; - ulint pos; - - /* Extract necessary information from a SYS_FOREIGN_COLS row */ - err_msg = dict_process_sys_foreign_col_rec( - heap, rec, &name, &for_col_name, &ref_col_name, &pos); - - mtr_commit(&mtr); - mutex_exit(&dict_sys.mutex); - - if (!err_msg) { - i_s_dict_fill_sys_foreign_cols( - thd, name, for_col_name, ref_col_name, pos, - tables->table); - } else { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, "%s", - err_msg); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mutex_enter(&dict_sys.mutex); - mtr_start(&mtr); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys.mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols -@return 0 on success */ -static -int -innodb_sys_foreign_cols_init( -/*========================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_foreign_cols_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = Show::innodb_sys_foreign_cols_fields_info; - schema->fill_table = i_s_sys_foreign_cols_fill_table; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign_cols = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_FOREIGN_COLS"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_FOREIGN_COLS"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_foreign_cols_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* Maria extension */ - STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), -}; - -namespace Show { /** SYS_TABLESPACES ********************************************/ /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES */ static ST_FIELD_INFO innodb_sys_tablespaces_fields_info[] = diff --git a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h index 385c249d9d5..8779760e393 100644 --- a/storage/innobase/handler/i_s.h +++ b/storage/innobase/handler/i_s.h @@ -56,8 +56,6 @@ extern struct st_maria_plugin i_s_innodb_sys_tablestats; extern struct st_maria_plugin i_s_innodb_sys_indexes; extern struct st_maria_plugin i_s_innodb_sys_columns; extern struct st_maria_plugin i_s_innodb_sys_fields; -extern struct st_maria_plugin i_s_innodb_sys_foreign; -extern struct st_maria_plugin i_s_innodb_sys_foreign_cols; extern struct st_maria_plugin i_s_innodb_sys_tablespaces; extern struct st_maria_plugin i_s_innodb_sys_datafiles; extern struct st_maria_plugin i_s_innodb_mutexes; diff --git a/storage/innobase/include/dict0crea.h b/storage/innobase/include/dict0crea.h index 13706d6bfad..e2b793a0610 100644 --- a/storage/innobase/include/dict0crea.h +++ b/storage/innobase/include/dict0crea.h @@ -113,15 +113,6 @@ dict_create_index_tree_in_mem( dict_index_t* index, /*!< in/out: index */ const trx_t* trx); /*!< in: InnoDB transaction handle */ -/****************************************************************//** -Creates the foreign key constraints system tables inside InnoDB -at server bootstrap or server start if they are not found or are -not of the right form. -@return DB_SUCCESS or error code */ -dberr_t -dict_create_or_check_foreign_constraint_tables(void); -/*================================================*/ - /********************************************************************//** Generate a foreign key constraint name when it was not named by the user. A generated constraint has a name of the format dbname/tablename_ibfk_NUMBER, @@ -136,24 +127,6 @@ dict_create_add_foreign_id( const char* name, /*!< in: table name */ dict_foreign_t* foreign); /*!< in/out: foreign key */ -/** Adds the given set of foreign key objects to the dictionary tables -in the database. This function does not modify the dictionary cache. The -caller must ensure that all foreign key objects contain a valid constraint -name in foreign->id. -@param[in] local_fk_set set of foreign key objects, to be added to -the dictionary tables -@param[in] table table to which the foreign key objects in -local_fk_set belong to -@param[in,out] trx transaction -@return error code or DB_SUCCESS */ -dberr_t -dict_create_add_foreigns_to_dictionary( -/*===================================*/ - const dict_foreign_set& local_fk_set, - const dict_table_t* table, - trx_t* trx) - MY_ATTRIBUTE((nonnull, warn_unused_result)); - /** Check if a foreign constraint is on columns server as base columns of any stored column. This is to prevent creating SET NULL or CASCADE constraint on such columns @@ -199,17 +172,6 @@ dict_replace_tablespace_in_dictionary( trx_t* trx); /********************************************************************//** -Add a foreign key definition to the data dictionary tables. -@return error code or DB_SUCCESS */ -dberr_t -dict_create_add_foreign_to_dictionary( -/*==================================*/ - const char* name, /*!< in: table name */ - const dict_foreign_t* foreign,/*!< in: foreign key */ - trx_t* trx) /*!< in/out: dictionary transaction */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); - -/********************************************************************//** Construct foreign key constraint defintion from data dictionary information. */ UNIV_INTERN diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index f067571ca5b..63661f062b7 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -34,11 +34,6 @@ Created 4/24/1996 Heikki Tuuri #include "mem0mem.h" #include "btr0types.h" -#include <deque> - -/** A stack of table names related through foreign key constraints */ -typedef std::deque<const char*, ut_allocator<const char*> > dict_names_t; - /** enum that defines all system table IDs. @see SYSTEM_TABLE_NAME[] */ enum dict_system_id_t { SYS_TABLES = 0, @@ -117,33 +112,6 @@ void dict_load_sys_table( /*================*/ dict_table_t* table); /*!< in: system table */ -/***********************************************************************//** -Loads foreign key constraints where the table is either the foreign key -holder or where the table is referenced by a foreign key. Adds these -constraints to the data dictionary. - -The foreign key constraint is loaded only if the referenced table is also -in the dictionary cache. If the referenced table is not in dictionary -cache, then it is added to the output parameter (fk_tables). - -@return DB_SUCCESS or error code */ -dberr_t -dict_load_foreigns( -/*===============*/ - const char* table_name, /*!< in: table name */ - const char** col_names, /*!< in: column names, or NULL - to use table->col_names */ - bool check_recursive,/*!< in: Whether to check - recursive load of tables - chained by FK */ - bool check_charsets, /*!< in: whether to check - charset compatibility */ - dict_err_ignore_t ignore_err, /*!< in: error to be ignored */ - dict_names_t& fk_tables) /*!< out: stack of table names - which must be loaded - subsequently to load all the - foreign key constraints. */ - MY_ATTRIBUTE((nonnull(1), warn_unused_result)); /********************************************************************//** This function opens a system table, and return the first record. @@ -234,32 +202,6 @@ dict_process_sys_fields_rec( index_id_t* index_id, /*!< out: current index id */ index_id_t last_id); /*!< in: previous index id */ /********************************************************************//** -This function parses a SYS_FOREIGN record and populate a dict_foreign_t -structure with the information from the record. For detail information -about SYS_FOREIGN fields, please refer to dict_load_foreign() function -@return error message, or NULL on success */ -const char* -dict_process_sys_foreign_rec( -/*=========================*/ - mem_heap_t* heap, /*!< in/out: heap memory */ - const rec_t* rec, /*!< in: current SYS_FOREIGN rec */ - dict_foreign_t* foreign); /*!< out: dict_foreign_t to be - filled */ -/********************************************************************//** -This function parses a SYS_FOREIGN_COLS record and extract necessary -information from the record and return to caller. -@return error message, or NULL on success */ -const char* -dict_process_sys_foreign_col_rec( -/*=============================*/ - mem_heap_t* heap, /*!< in/out: heap memory */ - const rec_t* rec, /*!< in: current SYS_FOREIGN_COLS rec */ - const char** name, /*!< out: foreign key constraint name */ - const char** for_col_name, /*!< out: referencing column name */ - const char** ref_col_name, /*!< out: referenced column name - in referenced table */ - ulint* pos); /*!< out: column position */ -/********************************************************************//** This function parses a SYS_TABLESPACES record, extracts necessary information from the record and returns to caller. @return error message, or NULL on success */ diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 0c42c5ffe6f..d1ec2ef4060 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1769,6 +1769,8 @@ typedef enum { DICT_FRM_INCONSISTENT_KEYS = 3 /*!< Key count mismatch */ } dict_frm_t; +extern "C" MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info; + /** Data structure for a database table. Most fields will be initialized to 0, NULL or FALSE in dict_mem_table_create(). */ struct dict_table_t { @@ -1948,6 +1950,19 @@ struct dict_table_t { char (&tbl_name)[NAME_LEN + 1], size_t *db_name_len, size_t *tbl_name_len) const; + + static bool + build_name( + const char* database_name, /*!< in: table db name */ + ulint database_name_len, /*!< in: db name length */ + const char* table_name, /*!< in: table name */ + ulint table_name_len, /*!< in: table name length */ + char *&dict_name, + ulint &dict_name_len, + mem_heap_t* alloc = NULL, + CHARSET_INFO* cs_db = system_charset_info, + CHARSET_INFO* cs_table = system_charset_info); /*!< in: table name charset */ + private: /** Initialize instant->field_map. @param[in] table table definition to copy from */ @@ -2449,19 +2464,6 @@ lock_table_lock_list_init( /*======================*/ table_lock_list_t* locks); /*!< List to initialise */ -/** A function object to add the foreign key constraint to the referenced set -of the referenced table, if it exists in the dictionary cache. */ -struct dict_foreign_add_to_referenced_table { - void operator()(dict_foreign_t* foreign) const - { - if (dict_table_t* table = foreign->referenced_table) { - std::pair<dict_foreign_set::iterator, bool> ret - = table->referenced_set.insert(foreign); - ut_a(ret.second); - } - } -}; - /** Check whether the col is used in spatial index or regular index. @param[in] col column to check @return spatial status */ diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h index b7fd9c098a6..50da82b0b37 100644 --- a/storage/innobase/include/mem0mem.h +++ b/storage/innobase/include/mem0mem.h @@ -262,6 +262,8 @@ char* mem_heap_strdupl(mem_heap_t* heap, const char* str, size_t len) { char* s = static_cast<char*>(mem_heap_alloc(heap, len + 1)); + if (!s) + return NULL; s[len] = 0; return(static_cast<char*>(memcpy(s, str, len))); } diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 2294025a1aa..1bb3a347171 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -817,6 +817,7 @@ public: current operation, or an empty string */ uint isolation_level;/*!< TRX_ISO_REPEATABLE_READ, ... */ + // TODO: remove check_foreigns? bool check_foreigns; /*!< normally TRUE, but if the user wants to suppress foreign key checks, (in table imports, for example) we diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 42ed2aaf415..7251be09c5b 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -64,6 +64,7 @@ Created 9/17/2000 Heikki Tuuri #include "srv0start.h" #include "row0ext.h" #include "srv0start.h" +#include "ha_innodb.h" #include <algorithm> #include <deque> @@ -3817,66 +3818,6 @@ dberr_t row_drop_table_after_create_fail(const char* name, trx_t* trx) return row_drop_table_for_mysql(name, trx, SQLCOM_DROP_DB, true); } -/*******************************************************************//** -Drop all foreign keys in a database, see Bug#18942. -Called at the end of row_drop_database_for_mysql(). -@return error code or DB_SUCCESS */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) -dberr_t -drop_all_foreign_keys_in_db( -/*========================*/ - const char* name, /*!< in: database name which ends to '/' */ - trx_t* trx) /*!< in: transaction handle */ -{ - pars_info_t* pinfo; - dberr_t err; - - ut_a(name[strlen(name) - 1] == '/'); - - pinfo = pars_info_create(); - - pars_info_add_str_literal(pinfo, "dbname", name); - -/** true if for_name is not prefixed with dbname */ -#define TABLE_NOT_IN_THIS_DB \ -"SUBSTR(for_name, 0, LENGTH(:dbname)) <> :dbname" - - err = que_eval_sql(pinfo, - "PROCEDURE DROP_ALL_FOREIGN_KEYS_PROC () IS\n" - "foreign_id CHAR;\n" - "for_name CHAR;\n" - "found INT;\n" - "DECLARE CURSOR cur IS\n" - "SELECT ID, FOR_NAME FROM SYS_FOREIGN\n" - "WHERE FOR_NAME >= :dbname\n" - "LOCK IN SHARE MODE\n" - "ORDER BY FOR_NAME;\n" - "BEGIN\n" - "found := 1;\n" - "OPEN cur;\n" - "WHILE found = 1 LOOP\n" - " FETCH cur INTO foreign_id, for_name;\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSIF (" TABLE_NOT_IN_THIS_DB ") THEN\n" - " found := 0;\n" - " ELSIF (1=1) THEN\n" - " DELETE FROM SYS_FOREIGN_COLS\n" - " WHERE ID = foreign_id;\n" - " DELETE FROM SYS_FOREIGN\n" - " WHERE ID = foreign_id;\n" - " END IF;\n" - "END LOOP;\n" - "CLOSE cur;\n" - "COMMIT WORK;\n" - "END;\n", - FALSE, /* do not reserve dict mutex, - we are already holding it */ - trx); - - return(err); -} - /** Drop a database for MySQL. @param[in] name database name which ends at '/' @param[in] trx transaction handle @@ -3892,7 +3833,6 @@ row_drop_database_for_mysql( char* table_name; dberr_t err = DB_SUCCESS; ulint namelen = strlen(name); - bool is_partition = false; ut_ad(found != NULL); @@ -3904,7 +3844,6 @@ row_drop_database_for_mysql( /* Assert DB name or partition name. */ if (name[namelen - 1] == '#') { ut_ad(name[namelen - 2] != '/'); - is_partition = true; trx->op_info = "dropping partitions"; } else { ut_a(name[namelen - 1] == '/'); @@ -4021,20 +3960,6 @@ loop: (*found)++; } - /* Partitioning does not yet support foreign keys. */ - if (err == DB_SUCCESS && !is_partition) { - /* after dropping all tables try to drop all leftover - foreign keys in case orphaned ones exist */ - err = drop_all_foreign_keys_in_db(name, trx); - - if (err != DB_SUCCESS) { - const std::string& db = ut_get_name(trx, name); - ib::error() << "DROP DATABASE " << db << " failed with" - " error " << err << " while dropping all" - " foreign keys"; - } - } - trx_commit_for_mysql(trx); row_mysql_unlock_data_dictionary(trx); @@ -4044,62 +3969,6 @@ loop: DBUG_RETURN(err); } -/****************************************************************//** -Delete a single constraint. -@return error code or DB_SUCCESS */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) -dberr_t -row_delete_constraint_low( -/*======================*/ - const char* id, /*!< in: constraint id */ - trx_t* trx) /*!< in: transaction handle */ -{ - pars_info_t* info = pars_info_create(); - - pars_info_add_str_literal(info, "id", id); - - return(que_eval_sql(info, - "PROCEDURE DELETE_CONSTRAINT () IS\n" - "BEGIN\n" - "DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;\n" - "DELETE FROM SYS_FOREIGN WHERE ID = :id;\n" - "END;\n" - , FALSE, trx)); -} - -/****************************************************************//** -Delete a single constraint. -@return error code or DB_SUCCESS */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) -dberr_t -row_delete_constraint( -/*==================*/ - const char* id, /*!< in: constraint id */ - const char* database_name, /*!< in: database name, with the - trailing '/' */ - mem_heap_t* heap, /*!< in: memory heap */ - trx_t* trx) /*!< in: transaction handle */ -{ - dberr_t err; - - /* New format constraints have ids <databasename>/<constraintname>. */ - err = row_delete_constraint_low( - mem_heap_strcat(heap, database_name, id), trx); - - if ((err == DB_SUCCESS) && !strchr(id, '/')) { - /* Old format < 4.0.18 constraints have constraint ids - NUMBER_NUMBER. We only try deleting them if the - constraint name does not contain a '/' character, otherwise - deleting a new format constraint named 'foo/bar' from - database 'baz' would remove constraint 'bar' from database - 'foo', if it existed. */ - - err = row_delete_constraint_low(id, trx); - } - - return(err); -} - /*********************************************************************//** Renames a table for MySQL. @return error code or DB_SUCCESS */ @@ -4311,139 +4180,7 @@ row_rename_table_for_mysql( goto end; } - if (!new_is_tmp) { - /* Rename all constraints. */ - char new_table_name[MAX_TABLE_NAME_LEN + 1]; - char old_table_utf8[MAX_TABLE_NAME_LEN + 1]; - uint errors = 0; - - strncpy(old_table_utf8, old_name, MAX_TABLE_NAME_LEN); - old_table_utf8[MAX_TABLE_NAME_LEN] = '\0'; - innobase_convert_to_system_charset( - strchr(old_table_utf8, '/') + 1, - strchr(old_name, '/') +1, - MAX_TABLE_NAME_LEN, &errors); - - if (errors) { - /* Table name could not be converted from charset - my_charset_filename to UTF-8. This means that the - table name is already in UTF-8 (#mysql#50). */ - strncpy(old_table_utf8, old_name, MAX_TABLE_NAME_LEN); - old_table_utf8[MAX_TABLE_NAME_LEN] = '\0'; - } - - info = pars_info_create(); - - pars_info_add_str_literal(info, "new_table_name", new_name); - pars_info_add_str_literal(info, "old_table_name", old_name); - pars_info_add_str_literal(info, "old_table_name_utf8", - old_table_utf8); - - strncpy(new_table_name, new_name, MAX_TABLE_NAME_LEN); - new_table_name[MAX_TABLE_NAME_LEN] = '\0'; - innobase_convert_to_system_charset( - strchr(new_table_name, '/') + 1, - strchr(new_name, '/') +1, - MAX_TABLE_NAME_LEN, &errors); - - if (errors) { - /* Table name could not be converted from charset - my_charset_filename to UTF-8. This means that the - table name is already in UTF-8 (#mysql#50). */ - strncpy(new_table_name, new_name, MAX_TABLE_NAME_LEN); - new_table_name[MAX_TABLE_NAME_LEN] = '\0'; - } - - pars_info_add_str_literal(info, "new_table_utf8", new_table_name); - - err = que_eval_sql( - info, - "PROCEDURE RENAME_CONSTRAINT_IDS () IS\n" - "gen_constr_prefix CHAR;\n" - "new_db_name CHAR;\n" - "foreign_id CHAR;\n" - "new_foreign_id CHAR;\n" - "old_db_name_len INT;\n" - "old_t_name_len INT;\n" - "new_db_name_len INT;\n" - "id_len INT;\n" - "offset INT;\n" - "found INT;\n" - "BEGIN\n" - "found := 1;\n" - "old_db_name_len := INSTR(:old_table_name, '/')-1;\n" - "new_db_name_len := INSTR(:new_table_name, '/')-1;\n" - "new_db_name := SUBSTR(:new_table_name, 0,\n" - " new_db_name_len);\n" - "old_t_name_len := LENGTH(:old_table_name);\n" - "gen_constr_prefix := CONCAT(:old_table_name_utf8,\n" - " '_ibfk_');\n" - "WHILE found = 1 LOOP\n" - " SELECT ID INTO foreign_id\n" - " FROM SYS_FOREIGN\n" - " WHERE FOR_NAME = :old_table_name\n" - " AND TO_BINARY(FOR_NAME)\n" - " = TO_BINARY(:old_table_name)\n" - " LOCK IN SHARE MODE;\n" - " IF (SQL % NOTFOUND) THEN\n" - " found := 0;\n" - " ELSE\n" - " UPDATE SYS_FOREIGN\n" - " SET FOR_NAME = :new_table_name\n" - " WHERE ID = foreign_id;\n" - " id_len := LENGTH(foreign_id);\n" - " IF (INSTR(foreign_id, '/') > 0) THEN\n" - " IF (INSTR(foreign_id,\n" - " gen_constr_prefix) > 0)\n" - " THEN\n" - " offset := INSTR(foreign_id, '_ibfk_') - 1;\n" - " new_foreign_id :=\n" - " CONCAT(:new_table_utf8,\n" - " SUBSTR(foreign_id, offset,\n" - " id_len - offset));\n" - " ELSE\n" - " new_foreign_id :=\n" - " CONCAT(new_db_name,\n" - " SUBSTR(foreign_id,\n" - " old_db_name_len,\n" - " id_len - old_db_name_len));\n" - " END IF;\n" - " UPDATE SYS_FOREIGN\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " UPDATE SYS_FOREIGN_COLS\n" - " SET ID = new_foreign_id\n" - " WHERE ID = foreign_id;\n" - " END IF;\n" - " END IF;\n" - "END LOOP;\n" - "UPDATE SYS_FOREIGN SET REF_NAME = :new_table_name\n" - "WHERE REF_NAME = :old_table_name\n" - " AND TO_BINARY(REF_NAME)\n" - " = TO_BINARY(:old_table_name);\n" - "END;\n" - , FALSE, trx); - - } else if (n_constraints_to_drop > 0) { - /* Drop some constraints of tmp tables. */ - - ulint db_name_len = dict_get_db_name_len(old_name) + 1; - char* db_name = mem_heap_strdupl(heap, old_name, - db_name_len); - ulint i; - - for (i = 0; i < n_constraints_to_drop; i++) { - err = row_delete_constraint(constraints_to_drop[i], - db_name, heap, trx); - - if (err != DB_SUCCESS) { - break; - } - } - } - - if (err == DB_SUCCESS - && (dict_table_has_fts_index(table) + if ((dict_table_has_fts_index(table) || DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) && !dict_tables_have_same_db(old_name, new_name)) { err = fts_rename_aux_tables(table, new_name, trx); @@ -4454,33 +4191,6 @@ row_rename_table_for_mysql( end: if (err != DB_SUCCESS) { - if (err == DB_DUPLICATE_KEY) { - ib::error() << "Possible reasons:"; - ib::error() << "(1) Table rename would cause two" - " FOREIGN KEY constraints to have the same" - " internal name in case-insensitive" - " comparison."; - ib::error() << "(2) Table " - << ut_get_name(trx, new_name) - << " exists in the InnoDB internal data" - " dictionary though MySQL is trying to rename" - " table " << ut_get_name(trx, old_name) - << " to it. Have you deleted the .frm file and" - " not used DROP TABLE?"; - ib::info() << TROUBLESHOOTING_MSG; - ib::error() << "If table " - << ut_get_name(trx, new_name) - << " is a temporary table #sql..., then" - " it can be that there are still queries" - " running on the table, and it will be dropped" - " automatically when the queries end. You can" - " drop the orphaned table inside InnoDB by" - " creating an InnoDB table with the same name" - " in another database and copying the .frm file" - " to the current database. Then MySQL thinks" - " the table exists, and DROP TABLE will" - " succeed."; - } trx->error_state = DB_SUCCESS; trx->rollback(); trx->error_state = DB_SUCCESS; @@ -4504,48 +4214,6 @@ end: innobase_rename_vc_templ(table); } - /* We only want to switch off some of the type checking in - an ALTER TABLE, not in a RENAME. */ - dict_names_t fk_tables; - - err = dict_load_foreigns( - new_name, NULL, false, - !old_is_tmp || trx->check_foreigns, - use_fk - ? 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) - << "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; - goto funct_exit; - } - } 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."; - } - - trx->error_state = DB_SUCCESS; - trx->rollback(); - trx->error_state = DB_SUCCESS; - } - /* Check whether virtual column or stored column affects the foreign key constraint of the table. */ if (dict_foreigns_has_s_base_col( @@ -4564,12 +4232,6 @@ end: dict_mem_table_free_foreign_vcol_set(table); dict_mem_table_fill_foreign_vcol_set(table); - while (!fk_tables.empty()) { - dict_load_table(fk_tables.front(), - DICT_ERR_IGNORE_NONE); - fk_tables.pop_front(); - } - table->data_dir_path= NULL; } diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 85fc90a8e0c..32b087b5d67 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1929,13 +1929,9 @@ skip_monitors: } } - /* Create the SYS_FOREIGN and SYS_FOREIGN_COLS system tables */ - err = dict_create_or_check_foreign_constraint_tables(); + err = dict_create_or_check_sys_tablespace(); if (err == DB_SUCCESS) { - err = dict_create_or_check_sys_tablespace(); - if (err == DB_SUCCESS) { - err = dict_create_or_check_sys_virtual(); - } + err = dict_create_or_check_sys_virtual(); } switch (err) { case DB_SUCCESS: diff --git a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result index 2139b1bfe05..850af257255 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result @@ -329,10 +329,6 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS; TABLE_ID NAME POS MTYPE PRTYPE LEN SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS; INDEX_ID NAME POS -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES; SPACE NAME FLAG ROW_FORMAT PAGE_SIZE ZIP_PAGE_SIZE FS_BLOCK_SIZE FILE_SIZE ALLOCATED_SIZE SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES; diff --git a/storage/rocksdb/mysql-test/rocksdb/t/innodb_i_s_tables_disabled-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/innodb_i_s_tables_disabled-master.opt index b3565b5fa82..c07821692f1 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/innodb_i_s_tables_disabled-master.opt +++ b/storage/rocksdb/mysql-test/rocksdb/t/innodb_i_s_tables_disabled-master.opt @@ -23,8 +23,6 @@ --loose-enable-innodb_sys_indexes --loose-enable-innodb_sys_columns --loose-enable-innodb_sys_fields ---loose-enable-innodb_sys_foreign ---loose-enable-innodb_sys_foreign_cols --loose-enable-innodb_sys_tablespaces --loose-enable-innodb_sys_datafiles --loose-enable-innodb_sys_docstore_fields diff --git a/storage/rocksdb/mysql-test/rocksdb/t/innodb_i_s_tables_disabled.test b/storage/rocksdb/mysql-test/rocksdb/t/innodb_i_s_tables_disabled.test index 4ff48e13089..b218fb7a769 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/innodb_i_s_tables_disabled.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/innodb_i_s_tables_disabled.test @@ -34,8 +34,6 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES; #Not in MariaDB: SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_DOCSTORE_FIELDS; |