diff --git a/executor/test/admintest/BUILD.bazel b/executor/test/admintest/BUILD.bazel index 722658bd08e13..d79b63ce09e31 100644 --- a/executor/test/admintest/BUILD.bazel +++ b/executor/test/admintest/BUILD.bazel @@ -8,7 +8,7 @@ go_test( "main_test.go", ], flaky = True, - shard_count = 26, + shard_count = 21, deps = [ "//config", "//domain", @@ -17,7 +17,6 @@ go_test( "//kv", "//meta/autoid", "//parser/model", - "//planner/core", "//session", "//sessionctx/stmtctx", "//sessionctx/variable", diff --git a/executor/test/admintest/admin_test.go b/executor/test/admintest/admin_test.go index b02eac46f2ed6..686c9297d869b 100644 --- a/executor/test/admintest/admin_test.go +++ b/executor/test/admintest/admin_test.go @@ -29,7 +29,6 @@ import ( "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" - "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" @@ -93,100 +92,6 @@ func TestAdminCheckIndex(t *testing.T) { check() } -func TestAdminCheckIndexInTemporaryMode(t *testing.T) { - store := testkit.CreateMockStore(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("drop table if exists temporary_admin_test;") - tk.MustExec("create global temporary table temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2)) ON COMMIT DELETE ROWS;") - tk.MustExec("insert temporary_admin_test (c1, c2) values (1, 1), (2, 2), (3, 3);") - err := tk.ExecToErr("admin check table temporary_admin_test;") - require.EqualError(t, err, core.ErrOptOnTemporaryTable.GenWithStackByArgs("admin check table").Error()) - err = tk.ExecToErr("admin check index temporary_admin_test c1;") - require.EqualError(t, err, core.ErrOptOnTemporaryTable.GenWithStackByArgs("admin check index").Error()) - tk.MustExec("drop table if exists temporary_admin_test;") - - tk.MustExec("drop table if exists non_temporary_admin_test;") - tk.MustExec("create table non_temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2));") - tk.MustExec("insert non_temporary_admin_test (c1, c2) values (1, 1), (2, 2), (3, 3);") - tk.MustExec("admin check table non_temporary_admin_test;") - tk.MustExec("drop table if exists non_temporary_admin_test;") - - tk.MustExec("drop table if exists temporary_admin_checksum_table_with_index_test;") - tk.MustExec("drop table if exists temporary_admin_checksum_table_without_index_test;") - tk.MustExec("create global temporary table temporary_admin_checksum_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count)) ON COMMIT DELETE ROWS;") - tk.MustExec("create global temporary table temporary_admin_checksum_table_without_index_test (id int, count int, PRIMARY KEY(id)) ON COMMIT DELETE ROWS;") - err = tk.ExecToErr("admin checksum table temporary_admin_checksum_table_with_index_test;") - require.EqualError(t, err, core.ErrOptOnTemporaryTable.GenWithStackByArgs("admin checksum table").Error()) - err = tk.ExecToErr("admin checksum table temporary_admin_checksum_table_without_index_test;") - require.EqualError(t, err, core.ErrOptOnTemporaryTable.GenWithStackByArgs("admin checksum table").Error()) - tk.MustExec("drop table if exists temporary_admin_checksum_table_with_index_test,temporary_admin_checksum_table_without_index_test;") -} - -func TestAdminCheckIndexInLocalTemporaryMode(t *testing.T) { - store := testkit.CreateMockStore(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("drop table if exists local_temporary_admin_test;") - tk.MustExec("create temporary table local_temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2))") - tk.MustExec("insert local_temporary_admin_test (c1, c2) values (1,1), (2,2), (3,3);") - err := tk.ExecToErr("admin check table local_temporary_admin_test;") - require.EqualError(t, err, core.ErrOptOnTemporaryTable.GenWithStackByArgs("admin check table").Error()) - tk.MustExec("drop table if exists temporary_admin_test;") - - tk.MustExec("drop table if exists local_temporary_admin_checksum_table_with_index_test;") - tk.MustExec("drop table if exists local_temporary_admin_checksum_table_without_index_test;") - tk.MustExec("create temporary table local_temporary_admin_checksum_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count))") - tk.MustExec("create temporary table local_temporary_admin_checksum_table_without_index_test (id int, count int, PRIMARY KEY(id))") - err = tk.ExecToErr("admin checksum table local_temporary_admin_checksum_table_with_index_test;") - require.EqualError(t, err, core.ErrOptOnTemporaryTable.GenWithStackByArgs("admin checksum table").Error()) - err = tk.ExecToErr("admin checksum table local_temporary_admin_checksum_table_without_index_test;") - require.EqualError(t, err, core.ErrOptOnTemporaryTable.GenWithStackByArgs("admin checksum table").Error()) - tk.MustExec("drop table if exists local_temporary_admin_checksum_table_with_index_test,local_temporary_admin_checksum_table_without_index_test;") -} - -func TestAdminCheckIndexInCacheTable(t *testing.T) { - store := testkit.CreateMockStore(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("drop table if exists cache_admin_test;") - tk.MustExec("create table cache_admin_test (c1 int, c2 int, c3 int default 1, index (c1), unique key(c2))") - tk.MustExec("insert cache_admin_test (c1, c2) values (1, 1), (2, 2), (5, 5), (10, 10), (11, 11)") - tk.MustExec("alter table cache_admin_test cache") - tk.MustExec("admin check table cache_admin_test;") - tk.MustExec("admin check index cache_admin_test c1;") - tk.MustExec("admin check index cache_admin_test c2;") - tk.MustExec("alter table cache_admin_test nocache;") - tk.MustExec("drop table if exists cache_admin_test;") - - tk.MustExec(`drop table if exists check_index_test;`) - tk.MustExec(`create table check_index_test (a int, b varchar(10), index a_b (a, b), index b (b))`) - tk.MustExec(`insert check_index_test values (3, "ab"),(2, "cd"),(1, "ef"),(-1, "hi")`) - tk.MustExec("alter table check_index_test cache") - result := tk.MustQuery("admin check index check_index_test a_b (2, 4);") - result.Check(testkit.Rows("1 ef 3", "2 cd 2")) - result = tk.MustQuery("admin check index check_index_test a_b (3, 5);") - result.Check(testkit.Rows("-1 hi 4", "1 ef 3")) - tk.MustExec("alter table check_index_test nocache;") - tk.MustExec("drop table if exists check_index_test;") - - tk.MustExec("drop table if exists cache_admin_table_with_index_test;") - tk.MustExec("drop table if exists cache_admin_table_without_index_test;") - tk.MustExec("create table cache_admin_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count))") - tk.MustExec("create table cache_admin_table_without_index_test (id int, count int, PRIMARY KEY(id))") - tk.MustExec("alter table cache_admin_table_with_index_test cache") - tk.MustExec("alter table cache_admin_table_without_index_test cache") - tk.MustExec("admin checksum table cache_admin_table_with_index_test;") - tk.MustExec("admin checksum table cache_admin_table_without_index_test;") - - tk.MustExec("alter table cache_admin_table_with_index_test nocache;") - tk.MustExec("alter table cache_admin_table_without_index_test nocache;") - tk.MustExec("drop table if exists cache_admin_table_with_index_test,cache_admin_table_without_index_test;") -} - func TestAdminRecoverIndex(t *testing.T) { store, domain := testkit.CreateMockStoreAndDomain(t) @@ -599,17 +504,6 @@ func TestAdminRecoverIndex1(t *testing.T) { tk.MustExec("admin check index admin_test `primary`") } -// https://github.com/pingcap/tidb/issues/32915. -func TestAdminRecoverIndexEdge(t *testing.T) { - store := testkit.CreateMockStore(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("create table t(id bigint(20) primary key, col varchar(255) unique key);") - tk.MustExec("insert into t values(9223372036854775807, 'test');") - tk.MustQuery("admin recover index t col;").Check(testkit.Rows("0 1")) -} - func TestAdminCleanupIndex(t *testing.T) { store, domain := testkit.CreateMockStoreAndDomain(t) @@ -1407,16 +1301,6 @@ func TestCheckFailReport(t *testing.T) { }() } -func TestAdminCheckPrimaryIndex(t *testing.T) { - store := testkit.CreateMockStore(t) - - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("create table t(a bigint unsigned primary key, b int, c int, index idx(a, b));") - tk.MustExec("insert into t values(1, 1, 1), (9223372036854775807, 2, 2);") - tk.MustExec("admin check index t idx;") -} - func TestAdminCheckWithSnapshot(t *testing.T) { store, domain := testkit.CreateMockStoreAndDomain(t) diff --git a/executor/test/fktest/BUILD.bazel b/executor/test/fktest/BUILD.bazel index cbf2536c7a4d3..6af0ab32d2c65 100644 --- a/executor/test/fktest/BUILD.bazel +++ b/executor/test/fktest/BUILD.bazel @@ -8,7 +8,7 @@ go_test( "main_test.go", ], flaky = True, - shard_count = 39, + shard_count = 26, deps = [ "//config", "//executor", diff --git a/executor/test/fktest/foreign_key_test.go b/executor/test/fktest/foreign_key_test.go index def9344c1c833..852a6d895ecc7 100644 --- a/executor/test/fktest/foreign_key_test.go +++ b/executor/test/fktest/foreign_key_test.go @@ -500,30 +500,6 @@ func TestForeignKeyCheckAndLock(t *testing.T) { } } -func TestForeignKeyOnInsertIgnore(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - // Test for foreign key index is primary key. - tk.MustExec("CREATE TABLE t1 (i INT PRIMARY KEY);") - tk.MustExec("CREATE TABLE t2 (i INT, FOREIGN KEY (i) REFERENCES t1 (i));") - tk.MustExec("INSERT INTO t1 VALUES (1),(3);") - tk.MustExec("INSERT IGNORE INTO t2 VALUES (1), (null), (1), (2),(3),(4);") - warning := "Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`))" - tk.MustQuery("show warnings;").Check(testkit.Rows(warning, warning)) - tk.MustQuery("select * from t2 order by i").Check(testkit.Rows("", "1", "1", "3")) - // Test for foreign key index is non-unique key. - tk.MustExec("drop table t1,t2") - tk.MustExec("CREATE TABLE t1 (i INT, index(i));") - tk.MustExec("CREATE TABLE t2 (i INT, FOREIGN KEY (i) REFERENCES t1 (i));") - tk.MustExec("INSERT INTO t1 VALUES (1),(3);") - tk.MustExec("INSERT IGNORE INTO t2 VALUES (1), (null), (1), (2), (3), (2);") - tk.MustQuery("show warnings;").Check(testkit.Rows(warning, warning)) - tk.MustQuery("select * from t2 order by i").Check(testkit.Rows("", "1", "1", "3")) -} - func TestForeignKeyOnInsertOnDuplicateParentTableCheck(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -593,53 +569,6 @@ func TestForeignKeyOnInsertOnDuplicateParentTableCheck(t *testing.T) { tk.MustExec("insert into t1 values (1) on duplicate key update id=2") } -func TestForeignKey(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - - // Test table has more than 1 foreign keys. - tk.MustExec("create table t1 (id int, a int, b int, primary key (id));") - tk.MustExec("create table t2 (id int, a int, b int, primary key (id));") - tk.MustExec("create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id), foreign key (b) references t2(id));") - tk.MustExec("insert into t1 (id, a, b) values (1, 11, 111), (2, 22, 222);") - tk.MustExec("insert into t2 (id, a, b) values (2, 22, 222);") - tk.MustGetDBError("insert into t3 (id, a, b) values (1, 1, 1)", plannercore.ErrNoReferencedRow2) - tk.MustGetDBError("insert into t3 (id, a, b) values (2, 3, 2)", plannercore.ErrNoReferencedRow2) - tk.MustExec("insert into t3 (id, a, b) values (0, 1, 2);") - tk.MustExec("insert into t3 (id, a, b) values (1, 2, 2);") - tk.MustGetDBError("update t3 set a=3 where a=1", plannercore.ErrNoReferencedRow2) - tk.MustGetDBError("update t3 set b=4 where id=1", plannercore.ErrNoReferencedRow2) - - // Test table has been referenced by more than tables. - tk.MustExec("drop table if exists t3,t2,t1;") - tk.MustExec("create table t1 (id int, a int, b int, primary key (id));") - tk.MustExec("create table t2 (b int, a int, id int, primary key (a), foreign key (a) references t1(id));") - tk.MustExec("create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id));") - tk.MustExec("insert into t1 (id, a, b) values (1, 1, 1);") - tk.MustExec("insert into t2 (id, a, b) values (1, 1, 1);") - tk.MustExec("insert into t3 (id, a, b) values (1, 1, 1);") - tk.MustGetDBError(" update t1 set id=2 where id = 1", plannercore.ErrRowIsReferenced2) - tk.MustExec(" update t1 set a=2 where id = 1") - tk.MustExec(" update t1 set b=2 where id = 1") - - // Test table has been referenced by more than tables. - tk.MustExec("drop table if exists t3,t2,t1;") - tk.MustExec("create table t1 (id int, a int, b int, primary key (id));") - tk.MustExec("create table t2 (b int, a int, id int, primary key (a), foreign key (a) references t1(id));") - tk.MustExec("create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id));") - tk.MustExec("insert into t1 (id, a, b) values (1, 1, 1);") - tk.MustExec("insert into t2 (id, a, b) values (1, 1, 1);") - tk.MustExec("insert into t3 (id, a, b) values (1, 1, 1);") - tk.MustGetDBError("delete from t1 where a=1", plannercore.ErrRowIsReferenced2) - tk.MustExec("delete from t2 where id=1") - tk.MustGetDBError("delete from t1 where a=1", plannercore.ErrRowIsReferenced2) - tk.MustExec("delete from t3 where id=1") - tk.MustExec("delete from t1 where id=1") -} - func TestForeignKeyConcurrentInsertChildTable(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -1956,56 +1885,6 @@ func TestForeignKeyOnUpdateCascade2(t *testing.T) { tk.MustQuery("select count(*) from t1 join t2 where t1.id=t2.id and t1.b=t2.b").Check(testkit.Rows("32768")) } -func TestForeignKeyOnUpdateSetNull(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - - // Test handle many foreign key value in one cascade. - tk.MustExec("create table t1 (id int auto_increment key, b int, index(b));") - tk.MustExec("create table t2 (id int, b int, foreign key fk(b) references t1(b) on update set null)") - tk.MustExec("insert into t1 (b) values (1),(2),(3),(4),(5),(6),(7),(8);") - for i := 0; i < 12; i++ { - tk.MustExec("insert into t1 (b) select id from t1") - } - tk.MustQuery("select count(*) from t1").Check(testkit.Rows("32768")) - tk.MustExec("insert into t2 select * from t1") - tk.MustExec("update t1 set b=b+100000000") - tk.MustQuery("select count(*) from t2 where b is null").Check(testkit.Rows("32768")) -} - -func TestShowCreateTableWithForeignKey(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - - tk.MustExec("set @@global.tidb_enable_foreign_key=0") - tk.MustExec("create table t1 (id int key, leader int, leader2 int, index(leader), index(leader2), constraint fk foreign key (leader) references t1(id) ON DELETE CASCADE ON UPDATE SET NULL);") - tk.MustQuery("show create table t1").Check(testkit.Rows("t1 CREATE TABLE `t1` (\n" + - " `id` int(11) NOT NULL,\n" + - " `leader` int(11) DEFAULT NULL,\n" + - " `leader2` int(11) DEFAULT NULL,\n" + - " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + - " KEY `leader` (`leader`),\n KEY `leader2` (`leader2`),\n" + - " CONSTRAINT `fk` FOREIGN KEY (`leader`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE SET NULL /* FOREIGN KEY INVALID */\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("alter table t1 add constraint fk2 foreign key (leader2) references t1 (id)") - tk.MustQuery("show create table t1").Check(testkit.Rows("t1 CREATE TABLE `t1` (\n" + - " `id` int(11) NOT NULL,\n" + - " `leader` int(11) DEFAULT NULL,\n" + - " `leader2` int(11) DEFAULT NULL,\n" + - " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n" + - " KEY `leader` (`leader`),\n KEY `leader2` (`leader2`),\n" + - " CONSTRAINT `fk` FOREIGN KEY (`leader`) REFERENCES `test`.`t1` (`id`) ON DELETE CASCADE ON UPDATE SET NULL /* FOREIGN KEY INVALID */,\n" + - " CONSTRAINT `fk2` FOREIGN KEY (`leader2`) REFERENCES `test`.`t1` (`id`)\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - tk.MustExec("drop table t1") - tk.MustExec("create table t1 (id int key, leader int, leader2 int, index(leader), index(leader2), constraint fk foreign key (leader) references t1(id) /* FOREIGN KEY INVALID */);") -} - func TestDMLExplainAnalyzeFKInfo(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2037,23 +1916,6 @@ func getExplainResult(res *testkit.Result) string { return resBuff.String() } -func TestForeignKeyCascadeOnDiffColumnType(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - - tk.MustExec("create table t1 (id bit(10), index(id));") - tk.MustExec("create table t2 (id int key, b bit(10), constraint fk foreign key (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE);") - tk.MustExec("insert into t1 values (b'01'), (b'10');") - tk.MustExec("insert into t2 values (1, b'01'), (2, b'10');") - tk.MustExec("delete from t1 where id = b'01';") - tk.MustExec("update t1 set id = b'110' where id = b'10';") - tk.MustQuery("select cast(id as unsigned) from t1;").Check(testkit.Rows("6")) - tk.MustQuery("select id, cast(b as unsigned) from t2;").Check(testkit.Rows("2 6")) -} - func TestForeignKeyOnInsertOnDuplicateUpdate(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2099,32 +1961,6 @@ func TestForeignKeyOnInsertOnDuplicateUpdate(t *testing.T) { tk.MustQuery("select * from t3").Check(testkit.Rows("1")) } -func TestForeignKeyIssue39419(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@global.tidb_enable_foreign_key=1") - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key);") - tk.MustExec("create table t2 (id int key, a int, b int, " + - "foreign key fk_1 (a) references t1(id) ON DELETE SET NULL ON UPDATE SET NULL, " + - "foreign key fk_2 (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE);") - tk.MustExec("insert into t1 values (1), (2), (3);") - tk.MustExec("insert into t2 values (1, 1, 1), (2, 2, 2), (3, 3, 3);") - tk.MustExec("update t1 set id=id+10 where id in (1, 3);") - tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("2", "11", "13")) - tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 11", "2 2 2", "3 13")) - tk.MustExec("delete from t1 where id = 2;") - tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("11", "13")) - tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 11", "3 13")) - - tk.MustExec("drop table t1,t2") - tk.MustExec("create table t1 (id int, b int, index(id), foreign key fk_2 (b) references t1(id) ON UPDATE CASCADE);") - tk.MustExec("insert into t1 values (1, 1), (2, 2), (3, 3);") - tk.MustExec("update t1 set id=id+10 where id > 1") - tk.MustQuery("select * from t1 order by id").Check(testkit.Rows("1 1", "12 12", "13 13")) -} - func TestExplainAnalyzeDMLWithFKInfo(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2614,48 +2450,6 @@ func TestForeignKeyOnReplaceIntoChildTable(t *testing.T) { tk.MustGetDBError("replace into t2 values (3, 2);", plannercore.ErrNoReferencedRow2) } -func TestForeignKeyOnReplaceInto(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int key, a int, index (a));") - tk.MustExec("create table t2 (id int key, a int, index (a), constraint fk_1 foreign key (a) references t1(a));") - tk.MustExec("replace into t1 values (1, 1);") - tk.MustExec("replace into t2 values (1, 1);") - tk.MustExec("replace into t2 (id) values (2);") - tk.MustGetDBError("replace into t2 values (1, 2);", plannercore.ErrNoReferencedRow2) - // Test fk check on replace into parent table. - tk.MustGetDBError("replace into t1 values (1, 2);", plannercore.ErrRowIsReferenced2) - // Test fk cascade delete on replace into parent table. - tk.MustExec("alter table t2 drop foreign key fk_1") - tk.MustExec("alter table t2 add constraint fk_1 foreign key (a) references t1(a) on delete cascade") - tk.MustExec("replace into t1 values (1, 2);") - tk.MustQuery("select id, a from t1").Check(testkit.Rows("1 2")) - tk.MustQuery("select * from t2").Check(testkit.Rows("2 ")) - // Test fk cascade delete on replace into parent table. - tk.MustExec("alter table t2 drop foreign key fk_1") - tk.MustExec("alter table t2 add constraint fk_1 foreign key (a) references t1(a) on delete set null") - tk.MustExec("delete from t2") - tk.MustExec("delete from t1") - tk.MustExec("replace into t1 values (1, 1);") - tk.MustExec("replace into t2 values (1, 1);") - tk.MustExec("replace into t1 values (1, 2);") - tk.MustQuery("select id, a from t1").Check(testkit.Rows("1 2")) - tk.MustQuery("select id, a from t2").Check(testkit.Rows("1 ")) - - // Test cascade delete in self table by replace into statement. - tk.MustExec("drop table t1,t2") - tk.MustExec("create table t1 (id int key, name varchar(10), leader int, index(leader), foreign key (leader) references t1(id) ON DELETE CASCADE);") - tk.MustExec("replace into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1)") - tk.MustExec("replace into t1 values (100, 'l2_a1', 10), (101, 'l2_a2', 10), (102, 'l2_a3', 10)") - tk.MustExec("replace into t1 values (110, 'l2_b1', 11), (111, 'l2_b2', 11), (112, 'l2_b3', 11)") - tk.MustExec("replace into t1 values (120, 'l2_c1', 12), (121, 'l2_c2', 12), (122, 'l2_c3', 12)") - tk.MustExec("replace into t1 values (1000,'l3_a1', 100)") - tk.MustExec("replace into t1 values (1, 'new-boss', null)") - tk.MustQuery("select id from t1 order by id").Check(testkit.Rows("1")) -} - func TestForeignKeyLargeTxnErr(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2743,137 +2537,3 @@ func TestForeignKeyAndMemoryTracker(t *testing.T) { tk.MustExec("update t1 set id=id+100000 where id=1") tk.MustQuery("select id,pid from t1 where id<3 or pid is null order by id").Check(testkit.Rows("2 1", "100001 ")) } - -func TestForeignKeyMetaInKeyColumnUsage(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (a int, b int, index(a, b));") - tk.MustExec("create table t2 (a int, b int, index(a, b), constraint fk foreign key(a, b) references t1(a, b));") - tk.MustQuery("select CONSTRAINT_NAME, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from " + - "INFORMATION_SCHEMA.KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA='test' and TABLE_NAME='t2' and REFERENCED_TABLE_SCHEMA is not null and REFERENCED_COLUMN_NAME is not null;"). - Check(testkit.Rows("fk test t2 a test t1 a", "fk test t2 b test t1 b")) -} - -func TestForeignKeyAndGeneratedColumn(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - // Test foreign key with parent column is virtual generated column. - tk.MustExec("create table t1 (a int, b int as (a+1) virtual, index(b));") - tk.MustGetErrMsg("create table t2 (a int, b int, constraint fk foreign key(b) references t1(b));", "[schema:3733]Foreign key 'fk' uses virtual column 'b' which is not supported.") - // Test foreign key with child column is virtual generated column. - tk.MustExec("drop table t1") - tk.MustExec("create table t1 (a int key);") - tk.MustGetErrMsg("create table t2 (a int, c int as (a+1) virtual, constraint fk foreign key(c) references t1(a));", "[schema:3733]Foreign key 'fk' uses virtual column 'c' which is not supported.") - // Test foreign key with parent column is stored generated column. - tk.MustExec("drop table if exists t1,t2") - tk.MustExec("create table t1 (a int, b int as (a) stored, index(b));") - tk.MustExec("create table t2 (a int, b int, constraint fk foreign key(b) references t1(b) on delete cascade on update cascade);") - tk.MustExec("insert into t1 (a) values (1),(2)") - tk.MustExec("insert into t2 (a) values (1),(2)") - tk.MustExec("update t2 set b=a") - tk.MustExec("insert into t2 values (1,1),(2,2)") - tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2) - tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 1", "1 1", "2 2", "2 2")) - tk.MustExec("update t1 set a=a+10 where a=1") - tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("2 2", "11 11")) - tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "1 11", "2 2", "2 2")) - tk.MustExec("delete from t1 where a=2") - tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("11 11")) - tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "1 11")) - // Test foreign key with parent and child column is stored generated column. - tk.MustExec("drop table if exists t1,t2") - tk.MustExec("create table t1 (a int, b int as (a) stored, index(b));") - tk.MustGetErrMsg("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on update cascade);", "[ddl:3104]Cannot define foreign key with ON UPDATE CASCADE clause on a generated column.") - tk.MustGetErrMsg("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on delete set null);", "[ddl:3104]Cannot define foreign key with ON DELETE SET NULL clause on a generated column.") - tk.MustExec("create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b));") - tk.MustExec("insert into t1 (a) values (1),(2)") - tk.MustExec("insert into t2 (a) values (1),(2)") - tk.MustGetDBError("insert into t2 (a) values (3)", plannercore.ErrNoReferencedRow2) - tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 1", "2 2")) - tk.MustGetDBError("delete from t1 where b=1", plannercore.ErrRowIsReferenced2) - tk.MustGetDBError("update t1 set a=a+10 where a=1", plannercore.ErrRowIsReferenced2) - tk.MustExec("alter table t2 drop foreign key fk") - tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete cascade") - tk.MustExec("delete from t1 where a=1") - tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("2 2")) - tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("2 2")) -} - -func TestForeignKeyAndExpressionIndex(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (a int, b int, index idx1 (b), index idx2 ((b*2)));") - tk.MustExec("create table t2 (a int, b int, index((b*2)), constraint fk foreign key(b) references t1(b));") - tk.MustExec("insert into t1 values (1,1),(2,2)") - tk.MustExec("insert into t2 values (1,1),(2,2)") - tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2) - tk.MustGetDBError("update t1 set b=b+10 where b=1", plannercore.ErrRowIsReferenced2) - tk.MustGetDBError("delete from t1 where b=1", plannercore.ErrRowIsReferenced2) - tk.MustGetErrMsg("alter table t1 drop index idx1", "[ddl:1553]Cannot drop index 'idx1': needed in a foreign key constraint") - tk.MustGetErrMsg("alter table t2 drop index fk", "[ddl:1553]Cannot drop index 'fk': needed in a foreign key constraint") - tk.MustExec("alter table t2 drop foreign key fk") - tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade") - tk.MustExec("update t1 set b=b+10 where b=1") - tk.MustExec("delete from t1 where b=2") - tk.MustQuery("select * from t1 order by a").Check(testkit.Rows("1 11")) - tk.MustQuery("select * from t2 order by a").Check(testkit.Rows("1 11", "2 ")) - tk.MustExec("admin check table t1") - tk.MustExec("admin check table t2") -} - -func TestForeignKeyAndMultiValuedIndex(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (id int primary key, a json, b int generated always as (a->'$.id') stored, index idx1(b), index idx2((cast(a ->'$.data' as signed array))))") - tk.MustExec("create table t2 (id int, b int, constraint fk foreign key(b) references t1(b));") - tk.MustExec(`insert into t1 (id, a) values (1, '{"id": "1", "data": [1,11,111]}')`) - tk.MustExec(`insert into t1 (id, a) values (2, '{"id": "2", "data": [2,22,222]}')`) - tk.MustExec("insert into t2 values (1,1),(2,2)") - tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2) - tk.MustGetDBError(`update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1`, plannercore.ErrRowIsReferenced2) - tk.MustGetDBError(`delete from t1 where id=1`, plannercore.ErrRowIsReferenced2) - tk.MustExec("alter table t2 drop foreign key fk") - tk.MustExec("alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade") - tk.MustExec(`update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1`) - tk.MustExec(`delete from t1 where id=2`) - tk.MustQuery("select id,b from t1 order by id").Check(testkit.Rows("1 10")) - tk.MustQuery("select id,b from t2 order by id").Check(testkit.Rows("1 10", "2 ")) - tk.MustExec("admin check table t1") - tk.MustExec("admin check table t2") -} - -func TestForeignKeyAndSessionVariable(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - tk.MustExec("create table t1 (t timestamp, index(t));") - tk.MustExec("create table t2 (t timestamp, foreign key (t) references t1(t) on delete cascade);") - tk.MustExec("set @@time_zone='+8:00';") - tk.MustExec("insert into t1 values ('2023-01-28 10:29:16');") - tk.MustExec("insert into t2 values ('2023-01-28 10:29:16');") - tk.MustExec("set @@time_zone='+6:00';") - tk.MustExec("delete from t1;") - tk.MustQuery("select * from t1").Check(testkit.Rows()) - tk.MustQuery("select * from t2").Check(testkit.Rows()) -} - -func TestForeignKeyIssue44848(t *testing.T) { - store := testkit.CreateMockStore(t) - tk := testkit.NewTestKit(t, store) - tk.MustExec("set @@foreign_key_checks=1") - tk.MustExec("use test") - tk.MustExec("create table b ( id int(11) NOT NULL AUTO_INCREMENT, f int(11) NOT NULL, PRIMARY KEY (id));") - tk.MustExec("create table a ( id int(11) NOT NULL AUTO_INCREMENT, b_id int(11) NOT NULL, PRIMARY KEY (id), CONSTRAINT fk_b_id FOREIGN KEY (b_id) REFERENCES b (id) ON DELETE CASCADE);") - tk.MustExec("insert b(id,f) values(1,1);") - tk.MustExec("insert a(id,b_id) values(1,1);") - tk.MustExec("update b set id=1,f=2 where id=1;") -} diff --git a/tests/integrationtest/r/executor/admin.result b/tests/integrationtest/r/executor/admin.result new file mode 100644 index 0000000000000..5ec10a53cd878 --- /dev/null +++ b/tests/integrationtest/r/executor/admin.result @@ -0,0 +1,90 @@ +drop table if exists temporary_admin_test; +create global temporary table temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2)) ON COMMIT DELETE ROWS; +insert temporary_admin_test (c1, c2) values (1, 1), (2, 2), (3, 3); +admin check table temporary_admin_test; +Error 8006 (HY000): `admin check table` is unsupported on temporary tables. +admin check index temporary_admin_test c1; +Error 8006 (HY000): `admin check index` is unsupported on temporary tables. +drop table if exists temporary_admin_test; +drop table if exists non_temporary_admin_test; +create table non_temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2)); +insert non_temporary_admin_test (c1, c2) values (1, 1), (2, 2), (3, 3); +admin check table non_temporary_admin_test; + +drop table if exists non_temporary_admin_test; +drop table if exists temporary_admin_checksum_table_with_index_test; +drop table if exists temporary_admin_checksum_table_without_index_test; +create global temporary table temporary_admin_checksum_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count)) ON COMMIT DELETE ROWS; +create global temporary table temporary_admin_checksum_table_without_index_test (id int, count int, PRIMARY KEY(id)) ON COMMIT DELETE ROWS; +admin checksum table temporary_admin_checksum_table_with_index_test; +Error 8006 (HY000): `admin checksum table` is unsupported on temporary tables. +admin checksum table temporary_admin_checksum_table_without_index_test; +Error 8006 (HY000): `admin checksum table` is unsupported on temporary tables. +drop table if exists temporary_admin_checksum_table_with_index_test,temporary_admin_checksum_table_without_index_test; +drop table if exists local_temporary_admin_test; +create temporary table local_temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2)); +insert local_temporary_admin_test (c1, c2) values (1,1), (2,2), (3,3); +admin check table local_temporary_admin_test; +Error 8006 (HY000): `admin check table` is unsupported on temporary tables. +drop table if exists temporary_admin_test; +drop table if exists local_temporary_admin_checksum_table_with_index_test; +drop table if exists local_temporary_admin_checksum_table_without_index_test; +create temporary table local_temporary_admin_checksum_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count)); +create temporary table local_temporary_admin_checksum_table_without_index_test (id int, count int, PRIMARY KEY(id)); +admin checksum table local_temporary_admin_checksum_table_with_index_test; +Error 8006 (HY000): `admin checksum table` is unsupported on temporary tables. +admin checksum table local_temporary_admin_checksum_table_without_index_test; +Error 8006 (HY000): `admin checksum table` is unsupported on temporary tables. +drop table if exists local_temporary_admin_checksum_table_with_index_test,local_temporary_admin_checksum_table_without_index_test; +drop table if exists cache_admin_test; +create table cache_admin_test (c1 int, c2 int, c3 int default 1, index (c1), unique key(c2)); +insert cache_admin_test (c1, c2) values (1, 1), (2, 2), (5, 5), (10, 10), (11, 11); +alter table cache_admin_test cache; +admin check table cache_admin_test; + +admin check index cache_admin_test c1; + +admin check index cache_admin_test c2; + +alter table cache_admin_test nocache; +drop table if exists cache_admin_test; +drop table if exists check_index_test; +create table check_index_test (a int, b varchar(10), index a_b (a, b), index b (b)); +insert check_index_test values (3, "ab"),(2, "cd"),(1, "ef"),(-1, "hi"); +alter table check_index_test cache; +admin check index check_index_test a_b (2, 4); +a b extra_handle +1 ef 3 +2 cd 2 +admin check index check_index_test a_b (3, 5); +a b extra_handle +-1 hi 4 +1 ef 3 +alter table check_index_test nocache; +drop table if exists check_index_test; +drop table if exists cache_admin_table_with_index_test; +drop table if exists cache_admin_table_without_index_test; +create table cache_admin_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count)); +create table cache_admin_table_without_index_test (id int, count int, PRIMARY KEY(id)); +alter table cache_admin_table_with_index_test cache; +alter table cache_admin_table_without_index_test cache; +admin checksum table cache_admin_table_with_index_test; +Db_name Table_name Checksum_crc64_xor Total_kvs Total_bytes +executor__admin cache_admin_table_with_index_test 0 2 2 +admin checksum table cache_admin_table_without_index_test; +Db_name Table_name Checksum_crc64_xor Total_kvs Total_bytes +executor__admin cache_admin_table_without_index_test 1 1 1 +alter table cache_admin_table_with_index_test nocache; +alter table cache_admin_table_without_index_test nocache; +drop table if exists cache_admin_table_with_index_test,cache_admin_table_without_index_test; +drop table if exists t; +create table t(id bigint(20) primary key, col varchar(255) unique key); +insert into t values(9223372036854775807, 'test'); +admin recover index t col; +ADDED_COUNT SCAN_COUNT +0 1 +drop table if exists t; +create table t(a bigint unsigned primary key, b int, c int, index idx(a, b)); +insert into t values(1, 1, 1), (9223372036854775807, 2, 2); +admin check index t idx; + diff --git a/tests/integrationtest/r/executor/foreign_key.result b/tests/integrationtest/r/executor/foreign_key.result new file mode 100644 index 0000000000000..c2ff3c733ff96 --- /dev/null +++ b/tests/integrationtest/r/executor/foreign_key.result @@ -0,0 +1,400 @@ +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +CREATE TABLE t1 (i INT PRIMARY KEY); +CREATE TABLE t2 (i INT, FOREIGN KEY (i) REFERENCES t1 (i)); +INSERT INTO t1 VALUES (1),(3); +INSERT IGNORE INTO t2 VALUES (1), (null), (1), (2),(3),(4); +Level Code Message +Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`)) +Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`)) +select * from t2 order by i; +i +NULL +1 +1 +3 +drop table t1,t2; +CREATE TABLE t1 (i INT, index(i)); +CREATE TABLE t2 (i INT, FOREIGN KEY (i) REFERENCES t1 (i)); +INSERT INTO t1 VALUES (1),(3); +INSERT IGNORE INTO t2 VALUES (1), (null), (1), (2), (3), (2); +Level Code Message +Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`)) +Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`)) +select * from t2 order by i; +i +NULL +1 +1 +3 +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int, a int, b int, primary key (id)); +create table t2 (id int, a int, b int, primary key (id)); +create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id), foreign key (b) references t2(id)); +insert into t1 (id, a, b) values (1, 11, 111), (2, 22, 222); +insert into t2 (id, a, b) values (2, 22, 222); +insert into t3 (id, a, b) values (1, 1, 1); +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t3`, CONSTRAINT `fk_2` FOREIGN KEY (`b`) REFERENCES `t2` (`id`)) +insert into t3 (id, a, b) values (2, 3, 2); +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t3`, CONSTRAINT `fk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`id`)) +insert into t3 (id, a, b) values (0, 1, 2); +insert into t3 (id, a, b) values (1, 2, 2); +update t3 set a=3 where a=1; +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t3`, CONSTRAINT `fk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`id`)) +update t3 set b=4 where id=1; +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t3`, CONSTRAINT `fk_2` FOREIGN KEY (`b`) REFERENCES `t2` (`id`)) +drop table if exists t3,t2,t1; +create table t1 (id int, a int, b int, primary key (id)); +create table t2 (b int, a int, id int, primary key (a), foreign key (a) references t1(id)); +create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id)); +insert into t1 (id, a, b) values (1, 1, 1); +insert into t2 (id, a, b) values (1, 1, 1); +insert into t3 (id, a, b) values (1, 1, 1); +update t1 set id=2 where id = 1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`id`)) +update t1 set a=2 where id = 1; +update t1 set b=2 where id = 1; +drop table if exists t3,t2,t1; +create table t1 (id int, a int, b int, primary key (id)); +create table t2 (b int, a int, id int, primary key (a), foreign key (a) references t1(id)); +create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id)); +insert into t1 (id, a, b) values (1, 1, 1); +insert into t2 (id, a, b) values (1, 1, 1); +insert into t3 (id, a, b) values (1, 1, 1); +delete from t1 where a=1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`id`)) +delete from t2 where id=1; +delete from t1 where a=1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t3`, CONSTRAINT `fk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`id`)) +delete from t3 where id=1; +delete from t1 where id=1; +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int auto_increment key, b int, index(b)); +create table t2 (id int, b int, foreign key fk(b) references t1(b) on update set null); +insert into t1 (b) values (1),(2),(3),(4),(5),(6),(7),(8); +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +select count(*) from t1; +count(*) +32768 +insert into t2 select * from t1; +update t1 set b=b+100000000; +select count(*) from t2 where b is null; +count(*) +32768 +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; +set @@global.tidb_enable_foreign_key=0; +drop table if exists t1, t2, t3; +create table t1 (id int key, leader int, leader2 int, index(leader), index(leader2), constraint fk foreign key (leader) references t1(id) ON DELETE CASCADE ON UPDATE SET NULL); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `leader` int(11) DEFAULT NULL, + `leader2` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */, + KEY `leader` (`leader`), + KEY `leader2` (`leader2`), + CONSTRAINT `fk` FOREIGN KEY (`leader`) REFERENCES `executor__foreign_key`.`t1` (`id`) ON DELETE CASCADE ON UPDATE SET NULL /* FOREIGN KEY INVALID */ +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin +set @@global.tidb_enable_foreign_key=1; +alter table t1 add constraint fk2 foreign key (leader2) references t1 (id); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `leader` int(11) DEFAULT NULL, + `leader2` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */, + KEY `leader` (`leader`), + KEY `leader2` (`leader2`), + CONSTRAINT `fk` FOREIGN KEY (`leader`) REFERENCES `executor__foreign_key`.`t1` (`id`) ON DELETE CASCADE ON UPDATE SET NULL /* FOREIGN KEY INVALID */, + CONSTRAINT `fk2` FOREIGN KEY (`leader2`) REFERENCES `executor__foreign_key`.`t1` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin +drop table t1; +create table t1 (id int key, leader int, leader2 int, index(leader), index(leader2), constraint fk foreign key (leader) references t1(id) /* FOREIGN KEY INVALID */); +set @@foreign_key_checks=default; +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id bit(10), index(id)); +create table t2 (id int key, b bit(10), constraint fk foreign key (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE); +insert into t1 values (b'01'), (b'10'); +insert into t2 values (1, b'01'), (2, b'10'); +delete from t1 where id = b'01'; +update t1 set id = b'110' where id = b'10'; +select cast(id as unsigned) from t1; +cast(id as unsigned) +6 +select id, cast(b as unsigned) from t2; +id cast(b as unsigned) +2 6 +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int key); +create table t2 (id int key, a int, b int, foreign key fk_1 (a) references t1(id) ON DELETE SET NULL ON UPDATE SET NULL, foreign key fk_2 (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE); +insert into t1 values (1), (2), (3); +insert into t2 values (1, 1, 1), (2, 2, 2), (3, 3, 3); +update t1 set id=id+10 where id in (1, 3); +select * from t1 order by id; +id +2 +11 +13 +select * from t2 order by id; +id a b +1 NULL 11 +2 2 2 +3 NULL 13 +delete from t1 where id = 2; +select * from t1 order by id; +id +11 +13 +select * from t2 order by id; +id a b +1 NULL 11 +3 NULL 13 +drop table t1,t2; +create table t1 (id int, b int, index(id), foreign key fk_2 (b) references t1(id) ON UPDATE CASCADE); +insert into t1 values (1, 1), (2, 2), (3, 3); +update t1 set id=id+10 where id > 1; +select * from t1 order by id; +id b +1 1 +12 12 +13 13 +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int key, a int, index (a)); +create table t2 (id int key, a int, index (a), constraint fk_1 foreign key (a) references t1(a)); +replace into t1 values (1, 1); +replace into t2 values (1, 1); +replace into t2 (id) values (2); +replace into t2 values (1, 2); +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) +replace into t1 values (1, 2); +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) +alter table t2 drop foreign key fk_1; +alter table t2 add constraint fk_1 foreign key (a) references t1(a) on delete cascade; +replace into t1 values (1, 2); +select id, a from t1; +id a +1 2 +select * from t2; +id a +2 NULL +alter table t2 drop foreign key fk_1; +alter table t2 add constraint fk_1 foreign key (a) references t1(a) on delete set null; +delete from t2; +delete from t1; +replace into t1 values (1, 1); +replace into t2 values (1, 1); +replace into t1 values (1, 2); +select id, a from t1; +id a +1 2 +select id, a from t2; +id a +1 NULL +drop table t1,t2; +create table t1 (id int key, name varchar(10), leader int, index(leader), foreign key (leader) references t1(id) ON DELETE CASCADE); +replace into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1); +replace into t1 values (100, 'l2_a1', 10), (101, 'l2_a2', 10), (102, 'l2_a3', 10); +replace into t1 values (110, 'l2_b1', 11), (111, 'l2_b2', 11), (112, 'l2_b3', 11); +replace into t1 values (120, 'l2_c1', 12), (121, 'l2_c2', 12), (122, 'l2_c3', 12); +replace into t1 values (1000,'l3_a1', 100); +replace into t1 values (1, 'new-boss', null); +select id from t1 order by id; +id +1 +set @@foreign_key_checks=default; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (a int, b int, index(a, b)); +create table t2 (a int, b int, index(a, b), constraint fk foreign key(a, b) references t1(a, b)); +select CONSTRAINT_NAME, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA='test' and TABLE_NAME='t2' and REFERENCED_TABLE_SCHEMA is not null and REFERENCED_COLUMN_NAME is not null; +CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME COLUMN_NAME REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +set @@foreign_key_checks=default; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (a int, b int as (a+1) virtual, index(b)); +create table t2 (a int, b int, constraint fk foreign key(b) references t1(b)); +Error 3733 (HY000): Foreign key 'fk' uses virtual column 'b' which is not supported. +drop table t1; +create table t1 (a int key); +create table t2 (a int, c int as (a+1) virtual, constraint fk foreign key(c) references t1(a)); +Error 3733 (HY000): Foreign key 'fk' uses virtual column 'c' which is not supported. +drop table if exists t1,t2,t3; +create table t1 (a int, b int as (a) stored, index(b)); +create table t2 (a int, b int, constraint fk foreign key(b) references t1(b) on delete cascade on update cascade); +insert into t1 (a) values (1),(2); +insert into t2 (a) values (1),(2); +update t2 set b=a; +insert into t2 values (1,1),(2,2); +insert into t2 values (3,3); +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`) ON DELETE CASCADE ON UPDATE CASCADE) +select * from t2 order by a; +a b +1 1 +1 1 +2 2 +2 2 +update t1 set a=a+10 where a=1; +select * from t1 order by a; +a b +2 2 +11 11 +select * from t2 order by a; +a b +1 11 +1 11 +2 2 +2 2 +delete from t1 where a=2; +select * from t1 order by a; +a b +11 11 +select * from t2 order by a; +a b +1 11 +1 11 +drop table if exists t1,t2,t3; +create table t1 (a int, b int as (a) stored, index(b)); +create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on update cascade); +Error 3104 (HY000): Cannot define foreign key with ON UPDATE CASCADE clause on a generated column. +create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on delete set null); +Error 3104 (HY000): Cannot define foreign key with ON DELETE SET NULL clause on a generated column. +create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b)); +insert into t1 (a) values (1),(2); +insert into t2 (a) values (1),(2); +insert into t2 (a) values (3); +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +select * from t2 order by a; +a b +1 1 +2 2 +delete from t1 where b=1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +update t1 set a=a+10 where a=1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +alter table t2 drop foreign key fk; +alter table t2 add foreign key fk (b) references t1(b) on delete cascade; +delete from t1 where a=1; +select * from t1 order by a; +a b +2 2 +select * from t2 order by a; +a b +2 2 +set @@foreign_key_checks=default; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (a int, b int, index idx1 (b), index idx2 ((b*2))); +create table t2 (a int, b int, index((b*2)), constraint fk foreign key(b) references t1(b)); +insert into t1 values (1,1),(2,2); +insert into t2 values (1,1),(2,2); +insert into t2 values (3,3); +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +update t1 set b=b+10 where b=1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +delete from t1 where b=1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +alter table t1 drop index idx1; +Error 1553 (HY000): Cannot drop index 'idx1': needed in a foreign key constraint +alter table t2 drop index fk; +Error 1553 (HY000): Cannot drop index 'fk': needed in a foreign key constraint +alter table t2 drop foreign key fk; +alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade; +update t1 set b=b+10 where b=1; +delete from t1 where b=2; +select * from t1 order by a; +a b +1 11 +select * from t2 order by a; +a b +1 11 +2 NULL +admin check table t1; + +admin check table t2; + +set @@foreign_key_checks=default; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int primary key, a json, b int generated always as (a->'$.id') stored, index idx1(b), index idx2((cast(a ->'$.data' as signed array)))); +create table t2 (id int, b int, constraint fk foreign key(b) references t1(b)); +insert into t1 (id, a) values (1, '{"id": "1", "data": [1,11,111]}'); +insert into t1 (id, a) values (2, '{"id": "2", "data": [2,22,222]}'); +insert into t2 values (1,1),(2,2); +insert into t2 values (3,3); +Error 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +delete from t1 where id=1; +Error 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`executor__foreign_key`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`b`) REFERENCES `t1` (`b`)) +alter table t2 drop foreign key fk; +alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade; +update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1; +delete from t1 where id=2; +select id,b from t1 order by id; +id b +1 10 +select id,b from t2 order by id; +id b +1 10 +2 NULL +admin check table t1; + +admin check table t2; + +set @@foreign_key_checks=default; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (t timestamp, index(t)); +create table t2 (t timestamp, foreign key (t) references t1(t) on delete cascade); +set @@time_zone='+8:00'; +insert into t1 values ('2023-01-28 10:29:16'); +insert into t2 values ('2023-01-28 10:29:16'); +set @@time_zone='+6:00'; +delete from t1; +select * from t1; +t +select * from t2; +t +set @@time_zone=default; +set @@foreign_key_checks=default; +set @@foreign_key_checks=1; +drop table if exists a, b; +create table b ( id int(11) NOT NULL AUTO_INCREMENT, f int(11) NOT NULL, PRIMARY KEY (id)); +create table a ( id int(11) NOT NULL AUTO_INCREMENT, b_id int(11) NOT NULL, PRIMARY KEY (id), CONSTRAINT fk_b_id FOREIGN KEY (b_id) REFERENCES b (id) ON DELETE CASCADE); +insert b(id,f) values(1,1); +insert a(id,b_id) values(1,1); +update b set id=1,f=2 where id=1; +set @@foreign_key_checks=default; +drop table if exists a, b; diff --git a/tests/integrationtest/t/executor/admin.test b/tests/integrationtest/t/executor/admin.test new file mode 100644 index 0000000000000..1202d251efb82 --- /dev/null +++ b/tests/integrationtest/t/executor/admin.test @@ -0,0 +1,82 @@ +# TestAdminCheckIndexInTemporaryMode +drop table if exists temporary_admin_test; +create global temporary table temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2)) ON COMMIT DELETE ROWS; +insert temporary_admin_test (c1, c2) values (1, 1), (2, 2), (3, 3); +--error 8006 +admin check table temporary_admin_test; +--error 8006 +admin check index temporary_admin_test c1; +drop table if exists temporary_admin_test; +drop table if exists non_temporary_admin_test; +create table non_temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2)); +insert non_temporary_admin_test (c1, c2) values (1, 1), (2, 2), (3, 3); +admin check table non_temporary_admin_test; +drop table if exists non_temporary_admin_test; +drop table if exists temporary_admin_checksum_table_with_index_test; +drop table if exists temporary_admin_checksum_table_without_index_test; +create global temporary table temporary_admin_checksum_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count)) ON COMMIT DELETE ROWS; +create global temporary table temporary_admin_checksum_table_without_index_test (id int, count int, PRIMARY KEY(id)) ON COMMIT DELETE ROWS; +--error 8006 +admin checksum table temporary_admin_checksum_table_with_index_test; +--error 8006 +admin checksum table temporary_admin_checksum_table_without_index_test; +drop table if exists temporary_admin_checksum_table_with_index_test,temporary_admin_checksum_table_without_index_test; + +# TestAdminCheckIndexInLocalTemporaryMode +drop table if exists local_temporary_admin_test; +create temporary table local_temporary_admin_test (c1 int, c2 int, c3 int default 1, primary key (c1), index (c1), unique key(c2)); +insert local_temporary_admin_test (c1, c2) values (1,1), (2,2), (3,3); +--error 8006 +admin check table local_temporary_admin_test; +drop table if exists temporary_admin_test; +drop table if exists local_temporary_admin_checksum_table_with_index_test; +drop table if exists local_temporary_admin_checksum_table_without_index_test; +create temporary table local_temporary_admin_checksum_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count)); +create temporary table local_temporary_admin_checksum_table_without_index_test (id int, count int, PRIMARY KEY(id)); +--error 8006 +admin checksum table local_temporary_admin_checksum_table_with_index_test; +--error 8006 +admin checksum table local_temporary_admin_checksum_table_without_index_test; +drop table if exists local_temporary_admin_checksum_table_with_index_test,local_temporary_admin_checksum_table_without_index_test; + +# TestAdminCheckIndexInCacheTable +drop table if exists cache_admin_test; +create table cache_admin_test (c1 int, c2 int, c3 int default 1, index (c1), unique key(c2)); +insert cache_admin_test (c1, c2) values (1, 1), (2, 2), (5, 5), (10, 10), (11, 11); +alter table cache_admin_test cache; +admin check table cache_admin_test; +admin check index cache_admin_test c1; +admin check index cache_admin_test c2; +alter table cache_admin_test nocache; +drop table if exists cache_admin_test; +drop table if exists check_index_test; +create table check_index_test (a int, b varchar(10), index a_b (a, b), index b (b)); +insert check_index_test values (3, "ab"),(2, "cd"),(1, "ef"),(-1, "hi"); +alter table check_index_test cache; +admin check index check_index_test a_b (2, 4); +admin check index check_index_test a_b (3, 5); +alter table check_index_test nocache; +drop table if exists check_index_test; +drop table if exists cache_admin_table_with_index_test; +drop table if exists cache_admin_table_without_index_test; +create table cache_admin_table_with_index_test (id int, count int, PRIMARY KEY(id), KEY(count)); +create table cache_admin_table_without_index_test (id int, count int, PRIMARY KEY(id)); +alter table cache_admin_table_with_index_test cache; +alter table cache_admin_table_without_index_test cache; +admin checksum table cache_admin_table_with_index_test; +admin checksum table cache_admin_table_without_index_test; +alter table cache_admin_table_with_index_test nocache; +alter table cache_admin_table_without_index_test nocache; +drop table if exists cache_admin_table_with_index_test,cache_admin_table_without_index_test; + +# TestAdminRecoverIndexEdge +drop table if exists t; +create table t(id bigint(20) primary key, col varchar(255) unique key); +insert into t values(9223372036854775807, 'test'); +admin recover index t col; + +# TestAdminCheckPrimaryIndex +drop table if exists t; +create table t(a bigint unsigned primary key, b int, c int, index idx(a, b)); +insert into t values(1, 1, 1), (9223372036854775807, 2, 2); +admin check index t idx; diff --git a/tests/integrationtest/t/executor/foreign_key.test b/tests/integrationtest/t/executor/foreign_key.test new file mode 100644 index 0000000000000..704de1620b5a8 --- /dev/null +++ b/tests/integrationtest/t/executor/foreign_key.test @@ -0,0 +1,314 @@ +# TestForeignKeyOnInsertIgnore +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +CREATE TABLE t1 (i INT PRIMARY KEY); +CREATE TABLE t2 (i INT, FOREIGN KEY (i) REFERENCES t1 (i)); +INSERT INTO t1 VALUES (1),(3); +--enable_warnings; +INSERT IGNORE INTO t2 VALUES (1), (null), (1), (2),(3),(4); +--disable_warnings; +select * from t2 order by i; +drop table t1,t2; +CREATE TABLE t1 (i INT, index(i)); +CREATE TABLE t2 (i INT, FOREIGN KEY (i) REFERENCES t1 (i)); +INSERT INTO t1 VALUES (1),(3); +--enable_warnings; +INSERT IGNORE INTO t2 VALUES (1), (null), (1), (2), (3), (2); +--disable_warnings; +select * from t2 order by i; +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; + +# TestForeignKey +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int, a int, b int, primary key (id)); +create table t2 (id int, a int, b int, primary key (id)); +create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id), foreign key (b) references t2(id)); +insert into t1 (id, a, b) values (1, 11, 111), (2, 22, 222); +insert into t2 (id, a, b) values (2, 22, 222); +--error 1452 +insert into t3 (id, a, b) values (1, 1, 1); +--error 1452 +insert into t3 (id, a, b) values (2, 3, 2); +insert into t3 (id, a, b) values (0, 1, 2); +insert into t3 (id, a, b) values (1, 2, 2); +--error 1452 +update t3 set a=3 where a=1; +--error 1452 +update t3 set b=4 where id=1; +drop table if exists t3,t2,t1; +create table t1 (id int, a int, b int, primary key (id)); +create table t2 (b int, a int, id int, primary key (a), foreign key (a) references t1(id)); +create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id)); +insert into t1 (id, a, b) values (1, 1, 1); +insert into t2 (id, a, b) values (1, 1, 1); +insert into t3 (id, a, b) values (1, 1, 1); +--error 1452 +update t1 set id=2 where id = 1; +update t1 set a=2 where id = 1; +update t1 set b=2 where id = 1; +drop table if exists t3,t2,t1; +create table t1 (id int, a int, b int, primary key (id)); +create table t2 (b int, a int, id int, primary key (a), foreign key (a) references t1(id)); +create table t3 (b int, a int, id int, primary key (a), foreign key (a) references t1(id)); +insert into t1 (id, a, b) values (1, 1, 1); +insert into t2 (id, a, b) values (1, 1, 1); +insert into t3 (id, a, b) values (1, 1, 1); +--error 1452 +delete from t1 where a=1; +delete from t2 where id=1; +--error 1452 +delete from t1 where a=1; +delete from t3 where id=1; +delete from t1 where id=1; +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; + +# TestForeignKeyOnUpdateSetNull +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int auto_increment key, b int, index(b)); +create table t2 (id int, b int, foreign key fk(b) references t1(b) on update set null); +insert into t1 (b) values (1),(2),(3),(4),(5),(6),(7),(8); +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +insert into t1 (b) select id from t1; +select count(*) from t1; +insert into t2 select * from t1; +update t1 set b=b+100000000; +select count(*) from t2 where b is null; +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; + +# TestShowCreateTableWithForeignKey +set @@global.tidb_enable_foreign_key=0; +drop table if exists t1, t2, t3; +create table t1 (id int key, leader int, leader2 int, index(leader), index(leader2), constraint fk foreign key (leader) references t1(id) ON DELETE CASCADE ON UPDATE SET NULL); +show create table t1; +set @@global.tidb_enable_foreign_key=1; +alter table t1 add constraint fk2 foreign key (leader2) references t1 (id); +show create table t1; +drop table t1; +create table t1 (id int key, leader int, leader2 int, index(leader), index(leader2), constraint fk foreign key (leader) references t1(id) /* FOREIGN KEY INVALID */); +set @@foreign_key_checks=default; + +# TestForeignKeyCascadeOnDiffColumnType +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id bit(10), index(id)); +create table t2 (id int key, b bit(10), constraint fk foreign key (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE); +insert into t1 values (b'01'), (b'10'); +insert into t2 values (1, b'01'), (2, b'10'); +delete from t1 where id = b'01'; +update t1 set id = b'110' where id = b'10'; +select cast(id as unsigned) from t1; +select id, cast(b as unsigned) from t2; +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; + +# TestForeignKeyIssue39419 +set @@global.tidb_enable_foreign_key=1; +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int key); +create table t2 (id int key, a int, b int, foreign key fk_1 (a) references t1(id) ON DELETE SET NULL ON UPDATE SET NULL, foreign key fk_2 (b) references t1(id) ON DELETE CASCADE ON UPDATE CASCADE); +insert into t1 values (1), (2), (3); +insert into t2 values (1, 1, 1), (2, 2, 2), (3, 3, 3); +update t1 set id=id+10 where id in (1, 3); +select * from t1 order by id; +select * from t2 order by id; +delete from t1 where id = 2; +select * from t1 order by id; +select * from t2 order by id; +drop table t1,t2; +create table t1 (id int, b int, index(id), foreign key fk_2 (b) references t1(id) ON UPDATE CASCADE); +insert into t1 values (1, 1), (2, 2), (3, 3); +update t1 set id=id+10 where id > 1; +select * from t1 order by id; +set @@global.tidb_enable_foreign_key=default; +set @@foreign_key_checks=default; + +# TestForeignKeyOnReplaceInto +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int key, a int, index (a)); +create table t2 (id int key, a int, index (a), constraint fk_1 foreign key (a) references t1(a)); +replace into t1 values (1, 1); +replace into t2 values (1, 1); +replace into t2 (id) values (2); +--error 1452 +replace into t2 values (1, 2); +--error 1452 +replace into t1 values (1, 2); +alter table t2 drop foreign key fk_1; +alter table t2 add constraint fk_1 foreign key (a) references t1(a) on delete cascade; +replace into t1 values (1, 2); +select id, a from t1; +select * from t2; +alter table t2 drop foreign key fk_1; +alter table t2 add constraint fk_1 foreign key (a) references t1(a) on delete set null; +delete from t2; +delete from t1; +replace into t1 values (1, 1); +replace into t2 values (1, 1); +replace into t1 values (1, 2); +select id, a from t1; +select id, a from t2; +drop table t1,t2; +create table t1 (id int key, name varchar(10), leader int, index(leader), foreign key (leader) references t1(id) ON DELETE CASCADE); +replace into t1 values (1, 'boss', null), (10, 'l1_a', 1), (11, 'l1_b', 1), (12, 'l1_c', 1); +replace into t1 values (100, 'l2_a1', 10), (101, 'l2_a2', 10), (102, 'l2_a3', 10); +replace into t1 values (110, 'l2_b1', 11), (111, 'l2_b2', 11), (112, 'l2_b3', 11); +replace into t1 values (120, 'l2_c1', 12), (121, 'l2_c2', 12), (122, 'l2_c3', 12); +replace into t1 values (1000,'l3_a1', 100); +replace into t1 values (1, 'new-boss', null); +select id from t1 order by id; +set @@foreign_key_checks=default; + +# TestForeignKeyMetaInKeyColumnUsage +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (a int, b int, index(a, b)); +create table t2 (a int, b int, index(a, b), constraint fk foreign key(a, b) references t1(a, b)); +select CONSTRAINT_NAME, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA='test' and TABLE_NAME='t2' and REFERENCED_TABLE_SCHEMA is not null and REFERENCED_COLUMN_NAME is not null; +set @@foreign_key_checks=default; + +# TestForeignKeyAndGeneratedColumn +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (a int, b int as (a+1) virtual, index(b)); +-- error 3733 +create table t2 (a int, b int, constraint fk foreign key(b) references t1(b)); +drop table t1; +create table t1 (a int key); +-- error 3733 +create table t2 (a int, c int as (a+1) virtual, constraint fk foreign key(c) references t1(a)); +drop table if exists t1,t2,t3; +create table t1 (a int, b int as (a) stored, index(b)); +create table t2 (a int, b int, constraint fk foreign key(b) references t1(b) on delete cascade on update cascade); +insert into t1 (a) values (1),(2); +insert into t2 (a) values (1),(2); +update t2 set b=a; +insert into t2 values (1,1),(2,2); +--error 1452 +insert into t2 values (3,3); +select * from t2 order by a; +update t1 set a=a+10 where a=1; +select * from t1 order by a; +select * from t2 order by a; +delete from t1 where a=2; +select * from t1 order by a; +select * from t2 order by a; +drop table if exists t1,t2,t3; +create table t1 (a int, b int as (a) stored, index(b)); +-- error 3104 +create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on update cascade); +-- error 3104 +create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b) on delete set null); +create table t2 (a int, b int as (a) stored, constraint fk foreign key(b) references t1(b)); +insert into t1 (a) values (1),(2); +insert into t2 (a) values (1),(2); +--error 1452 +insert into t2 (a) values (3); +select * from t2 order by a; +--error 1452 +delete from t1 where b=1; +--error 1452 +update t1 set a=a+10 where a=1; +alter table t2 drop foreign key fk; +alter table t2 add foreign key fk (b) references t1(b) on delete cascade; +delete from t1 where a=1; +select * from t1 order by a; +select * from t2 order by a; +set @@foreign_key_checks=default; + +# TestForeignKeyAndExpressionIndex +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (a int, b int, index idx1 (b), index idx2 ((b*2))); +create table t2 (a int, b int, index((b*2)), constraint fk foreign key(b) references t1(b)); +insert into t1 values (1,1),(2,2); +insert into t2 values (1,1),(2,2); +--error 1452 +insert into t2 values (3,3); +--error 1452 +update t1 set b=b+10 where b=1; +--error 1452 +delete from t1 where b=1; +-- error 1553 +alter table t1 drop index idx1; +-- error 1553 +alter table t2 drop index fk; +alter table t2 drop foreign key fk; +alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade; +update t1 set b=b+10 where b=1; +delete from t1 where b=2; +select * from t1 order by a; +select * from t2 order by a; +admin check table t1; +admin check table t2; +set @@foreign_key_checks=default; + +# TestForeignKeyAndMultiValuedIndex +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (id int primary key, a json, b int generated always as (a->'$.id') stored, index idx1(b), index idx2((cast(a ->'$.data' as signed array)))); +create table t2 (id int, b int, constraint fk foreign key(b) references t1(b)); +insert into t1 (id, a) values (1, '{"id": "1", "data": [1,11,111]}'); +insert into t1 (id, a) values (2, '{"id": "2", "data": [2,22,222]}'); +insert into t2 values (1,1),(2,2); +--error 1452 +insert into t2 values (3,3); +--error 1452 +update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1; +--error 1452 +delete from t1 where id=1; +alter table t2 drop foreign key fk; +alter table t2 add foreign key fk (b) references t1(b) on delete set null on update cascade; +update t1 set a='{"id": "10", "data": [1,11,111]}' where id=1; +delete from t1 where id=2; +select id,b from t1 order by id; +select id,b from t2 order by id; +admin check table t1; +admin check table t2; +set @@foreign_key_checks=default; + +# TestForeignKeyAndSessionVariable +set @@foreign_key_checks=1; +drop table if exists t1, t2, t3; +create table t1 (t timestamp, index(t)); +create table t2 (t timestamp, foreign key (t) references t1(t) on delete cascade); +set @@time_zone='+8:00'; +insert into t1 values ('2023-01-28 10:29:16'); +insert into t2 values ('2023-01-28 10:29:16'); +set @@time_zone='+6:00'; +delete from t1; +select * from t1; +select * from t2; +set @@time_zone=default; +set @@foreign_key_checks=default; + +# TestForeignKeyIssue44848 +set @@foreign_key_checks=1; +drop table if exists a, b; +create table b ( id int(11) NOT NULL AUTO_INCREMENT, f int(11) NOT NULL, PRIMARY KEY (id)); +create table a ( id int(11) NOT NULL AUTO_INCREMENT, b_id int(11) NOT NULL, PRIMARY KEY (id), CONSTRAINT fk_b_id FOREIGN KEY (b_id) REFERENCES b (id) ON DELETE CASCADE); +insert b(id,f) values(1,1); +insert a(id,b_id) values(1,1); +update b set id=1,f=2 where id=1; +set @@foreign_key_checks=default; +drop table if exists a, b;