Skip to content

Commit

Permalink
test: add more foreign key test (#40650)
Browse files Browse the repository at this point in the history
close #40649
  • Loading branch information
crazycs520 committed Jan 17, 2023
1 parent 45e85d9 commit faffcd9
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
25 changes: 25 additions & 0 deletions ddl/fktest/foreign_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1810,3 +1810,28 @@ func TestForeignKeyAndConcurrentDDL(t *testing.T) {
}
}
}

func TestForeignKeyAndRenameIndex(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, b int, index idx1(b));")
tk.MustExec("create table t2 (id int key, b int, 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("delete from t1 where id=1", plannercore.ErrRowIsReferenced2)
tk.MustExec("alter table t1 rename index idx1 to idx2")
tk.MustExec("alter table t2 rename index fk to idx")
tk.MustGetDBError("insert into t2 values (3,3)", plannercore.ErrNoReferencedRow2)
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 cascade on update cascade")
tk.MustExec("alter table t1 rename index idx2 to idx3")
tk.MustExec("alter table t2 rename index idx to idx0")
tk.MustExec("delete from t1 where id=1")
tk.MustQuery("select * from t1").Check(testkit.Rows("2 2"))
tk.MustQuery("select * from t2").Check(testkit.Rows("2 2"))
tk.MustExec("admin check table t1,t2")
}
94 changes: 94 additions & 0 deletions executor/fktest/foreign_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2745,3 +2745,97 @@ func TestForeignKeyMetaInKeyColumnUsage(t *testing.T) {
"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 <nil>"))
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 <nil>"))
tk.MustExec("admin check table t1")
tk.MustExec("admin check table t2")
}

0 comments on commit faffcd9

Please sign in to comment.