Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add more foreign key test #40650

Merged
merged 6 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
}