153 lines
5.1 KiB
Plaintext
153 lines
5.1 KiB
Plaintext
# Tests of foreign keys that need a debug build or debug_sync feature.
|
|
#
|
|
|
|
--source include/have_debug.inc
|
|
--source include/have_debug_sync.inc
|
|
|
|
# Some parts of the test require enabled binary log.
|
|
--source include/have_log_bin.inc
|
|
|
|
--source include/have_myisam.inc
|
|
|
|
SET SESSION debug= '+d,skip_dd_table_access_check';
|
|
|
|
--echo #
|
|
--echo # RENAME will update FK information in both children and parents, also
|
|
--echo # when there are tables in the statement that belong in SEs without
|
|
--echo # support for atomic DDL. Basically the same test case as above with
|
|
--echo # an additional MyISAM table.
|
|
--echo #
|
|
|
|
CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER,
|
|
UNIQUE KEY parent_key(j));
|
|
|
|
CREATE TABLE child(pk INTEGER PRIMARY KEY, k INTEGER, fk INTEGER,
|
|
FOREIGN KEY (fk) REFERENCES parent(j), UNIQUE KEY child_key(k));
|
|
|
|
CREATE TABLE grandchild(pk INTEGER PRIMARY KEY, fk INTEGER,
|
|
FOREIGN KEY (fk) REFERENCES child(k));
|
|
|
|
SET @@foreign_key_checks= 0;
|
|
CREATE TABLE orphan_grandchild(pk INTEGER PRIMARY KEY, fk INTEGER,
|
|
FOREIGN KEY (fk) REFERENCES siebling(k));
|
|
SET @@foreign_key_checks= 1;
|
|
|
|
CREATE TABLE non_atomic_t1(pk INTEGER) ENGINE= MyISAM;
|
|
|
|
--echo # FK definitions before rename:
|
|
SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name
|
|
FROM mysql.foreign_keys
|
|
WHERE referenced_table_schema LIKE 'test';
|
|
|
|
RENAME TABLE non_atomic_t1 TO non_atomic_t2, child TO siebling;
|
|
|
|
--echo # After the rename, we see that:
|
|
--echo # 1. The name of the constraint is changed to 'siebling_ibfk...'.
|
|
--echo # 2. The referenced table name of the grandchild is changed to 'siebling'.
|
|
--echo # 3. The unique constraint name of the orphan_grandchild is corrected.
|
|
SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name
|
|
FROM mysql.foreign_keys
|
|
WHERE referenced_table_schema LIKE 'test';
|
|
|
|
DROP TABLE grandchild;
|
|
DROP TABLE orphan_grandchild;
|
|
DROP TABLE siebling;
|
|
DROP TABLE parent;
|
|
DROP TABLE non_atomic_t2;
|
|
|
|
--echo #
|
|
--echo # RENAME will rollback FK information in both children and parents, also
|
|
--echo # when there are tables in the statement that belong in SEs without
|
|
--echo # support for atomic DDL. Basically the same test case as above with
|
|
--echo # an additional MyISAM table, where renaming fails due to an existing table.
|
|
--echo #
|
|
|
|
CREATE TABLE parent(pk INTEGER PRIMARY KEY, j INTEGER,
|
|
UNIQUE KEY parent_key(j));
|
|
|
|
CREATE TABLE child(pk INTEGER PRIMARY KEY, k INTEGER, fk INTEGER,
|
|
FOREIGN KEY (fk) REFERENCES parent(j), UNIQUE KEY child_key(k));
|
|
|
|
CREATE TABLE grandchild(pk INTEGER PRIMARY KEY, fk INTEGER,
|
|
FOREIGN KEY (fk) REFERENCES child(k));
|
|
|
|
SET @@foreign_key_checks= 0;
|
|
CREATE TABLE orphan_grandchild(pk INTEGER PRIMARY KEY, fk INTEGER,
|
|
FOREIGN KEY (fk) REFERENCES siebling(k));
|
|
SET @@foreign_key_checks= 1;
|
|
|
|
CREATE TABLE non_atomic_t1(pk INTEGER) ENGINE= InnoDB;
|
|
CREATE TABLE non_atomic_t2(pk INTEGER) ENGINE= InnoDB;
|
|
|
|
--echo # FK definitions before rename:
|
|
SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name
|
|
FROM mysql.foreign_keys
|
|
WHERE referenced_table_schema LIKE 'test';
|
|
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
RENAME TABLE child TO siebling,
|
|
non_atomic_t1 TO non_atomic_t3,
|
|
non_atomic_t3 TO non_atomic_t2;
|
|
|
|
--echo # After the rename, we see that the FK information remain unchanged.
|
|
--echo # TODO: Note that the unique constraint name of orphan_grandchild is not reverted.
|
|
SELECT name, unique_constraint_name, referenced_table_schema, referenced_table_name
|
|
FROM mysql.foreign_keys
|
|
WHERE referenced_table_schema LIKE 'test';
|
|
|
|
DROP TABLE grandchild;
|
|
DROP TABLE orphan_grandchild;
|
|
DROP TABLE child;
|
|
DROP TABLE parent;
|
|
DROP TABLE non_atomic_t1;
|
|
DROP TABLE non_atomic_t2;
|
|
|
|
# Restore defaults.
|
|
SET @@foreign_key_checks= DEFAULT;
|
|
SET SESSION debug= '-d,skip_dd_table_access_check';
|
|
|
|
|
|
--echo #
|
|
--echo # Additional test coverage for case when ALTER TABLE is non-atomic but
|
|
--echo # still adds foreign keys and fails at the late stage (after foreign
|
|
--echo # keys are added to the data-dictionary).
|
|
--echo #
|
|
|
|
--enable_connect_log
|
|
connect (con1, localhost, root,,);
|
|
SET @old_lock_wait_timeout= @@lock_wait_timeout;
|
|
connection default;
|
|
|
|
CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB;
|
|
CREATE TABLE t2 (fk INT) ENGINE=MyISAM;
|
|
SET @@debug='+d,injecting_fault_writing';
|
|
--replace_regex /(errno: .*)/(errno: #)/
|
|
--error ER_ERROR_ON_WRITE
|
|
ALTER TABLE t2 ADD FOREIGN KEY (fk) REFERENCES t1(pk), ENGINE=InnoDB;
|
|
SET @@debug='-d,injecting_fault_writing';
|
|
--echo # Even though the above ALTER TABLE has failed it has updated
|
|
--echo # data-dictionary. So cached object for parent table should
|
|
--echo # be updated to reflect this new foreign key.
|
|
--echo # The below LOCK TABLES should implicitly lock t2 too.
|
|
LOCK TABLES t1 WRITE;
|
|
|
|
connection con1;
|
|
--echo # So concurrent inserts into child are blocked.
|
|
SET @@lock_wait_timeout= 1;
|
|
--error ER_LOCK_WAIT_TIMEOUT
|
|
INSERT INTO t1 VALUES (NULL);
|
|
SET @@lock_wait_timeout= @old_lock_wait_timeout;
|
|
|
|
connection default;
|
|
--echo # And delete from parent table is possible and doesn't cause asserts.
|
|
DELETE FROM t1;
|
|
UNLOCK TABLES;
|
|
DROP TABLES t2, t1;
|
|
|
|
connection con1;
|
|
disconnect con1;
|
|
--source include/wait_until_disconnected.inc
|
|
connection default;
|
|
|
|
--disable_connect_log
|