Skip to content

Commit a6a126b

Browse files
committed
add test for foreign key related to prepare and Non-Transactional DML
Signed-off-by: Yang Keao <[email protected]>
1 parent 73f1cfe commit a6a126b

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed

pkg/executor/prepared_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,3 +1115,29 @@ func TestMaxPreparedStmtCount(t *testing.T) {
11151115
err := tk.ExecToErr("prepare stmt3 from 'select ? as num from dual'")
11161116
require.True(t, terror.ErrorEqual(err, variable.ErrMaxPreparedStmtCountReached))
11171117
}
1118+
1119+
func TestPrepareWorkWithForeignKey(t *testing.T) {
1120+
store := testkit.CreateMockStore(t)
1121+
tk := testkit.NewTestKit(t, store)
1122+
1123+
tk.MustExec(`set tidb_enable_prepared_plan_cache=1`)
1124+
tk.MustExec("use test")
1125+
tk.MustExec("drop table if exists t1, t2")
1126+
tk.MustExec("create table t1(a int, key(a))")
1127+
tk.MustExec("create table t2(a int, key(a))")
1128+
tk.MustExec("prepare stmt from 'insert into t2 values (0)'")
1129+
tk.MustExec("execute stmt")
1130+
1131+
tk.MustQuery("select * from t2").Check(testkit.Rows("0"))
1132+
tk.MustExec("delete from t2")
1133+
tk.MustExec("execute stmt")
1134+
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
1135+
tk.MustQuery("select * from t2").Check(testkit.Rows("0"))
1136+
tk.MustExec("delete from t2")
1137+
1138+
// Then we create a foreign key constraint.
1139+
tk.MustExec("alter table t2 add constraint fk foreign key (a) references t1(a)")
1140+
tk.MustContainErrMsg("execute stmt", "Cannot add or update a child row: a foreign key constraint fails")
1141+
// As schema version increased, the plan cache should be invalidated.
1142+
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
1143+
}

pkg/session/nontransactionaltest/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ go_test(
88
"nontransactional_test.go",
99
],
1010
flaky = True,
11-
shard_count = 3,
11+
shard_count = 4,
1212
deps = [
1313
"//pkg/config",
1414
"//pkg/testkit",

pkg/session/nontransactionaltest/nontransactional_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,59 @@ func TestNonTransactionalWithCheckConstraint(t *testing.T) {
366366
err = tk.ExecToErr("batch limit 1 insert into t select * from (select 1, 2) tmp")
367367
require.EqualError(t, err, "Non-transactional DML, table name not found in join")
368368
}
369+
370+
func TestNonTransactionalDMLWorkWithForeignKey(t *testing.T) {
371+
store := testkit.CreateMockStore(t)
372+
tk := testkit.NewTestKit(t, store)
373+
374+
// t1 is the parent table, t2 is the child table, t3 is a helper table.
375+
tk.MustExec("use test")
376+
tk.MustExec("drop table if exists t1, t2, t3")
377+
tk.MustExec("create table t1(a int, b int, key(a), key(b))")
378+
tk.MustExec("create table t2(a int, b int, foreign key (a) references t1(a), key(b))")
379+
tk.MustExec("create table t3(a int, b int, key(a))")
380+
381+
cleanFn := func() {
382+
tk.MustExec("truncate t3")
383+
tk.MustExec("truncate t2")
384+
// Cannot truncate t1 because it is the parent table
385+
tk.MustExec("delete from t1")
386+
}
387+
388+
// The check should work for INSERT
389+
for i := 0; i < 100; i++ {
390+
tk.MustExec(fmt.Sprintf("insert into t1 values (%d, %d)", i, i))
391+
tk.MustExec(fmt.Sprintf("insert into t3 values (%d, %d)", i, i))
392+
}
393+
tk.MustExec("DELETE FROM t1 WHERE a = 55")
394+
tk.MustContainErrMsg("BATCH ON a LIMIT 10 INSERT INTO t2 SELECT * FROM t3", "Cannot add or update a child row: a foreign key constraint fails")
395+
// Though it failed, some data is still inserted
396+
tk.MustQuery("select count(*) from t2").Check(testkit.Rows("50"))
397+
cleanFn()
398+
399+
// The check should work for UPDATE
400+
for i := 0; i < 100; i++ {
401+
tk.MustExec(fmt.Sprintf("insert into t1 values (%d, %d)", i, i))
402+
}
403+
tk.MustExec("DELETE FROM t1 WHERE a = 55")
404+
for i := 0; i < 100; i++ {
405+
if i != 55 {
406+
tk.MustExec(fmt.Sprintf("insert into t2 values (%d, %d)", i, i))
407+
}
408+
}
409+
tk.MustContainErrMsg("BATCH ON b LIMIT 10 UPDATE t2 SET a = a + 1", "Cannot add or update a child row: a foreign key constraint fails")
410+
tk.MustQuery("select min(a) from t2").Check(testkit.Rows("1"))
411+
cleanFn()
412+
413+
// The check should work for DELETE
414+
for i := 0; i < 100; i++ {
415+
tk.MustExec(fmt.Sprintf("insert into t1 values (%d, %d)", i, i))
416+
}
417+
tk.MustExec("DELETE FROM t1 WHERE a = 55")
418+
for i := 56; i < 100; i++ {
419+
tk.MustExec(fmt.Sprintf("insert into t2 values (%d, %d)", i, i))
420+
}
421+
tk.MustContainErrMsg("BATCH ON b LIMIT 10 DELETE FROM t1", "Cannot delete or update a parent row: a foreign key constraint fails")
422+
tk.MustQuery("select count(*) from t1").Check(testkit.Rows("49"))
423+
cleanFn()
424+
}

0 commit comments

Comments
 (0)