ddl: add foreign key compatibility for temporary table (#24961)

This commit is contained in:
Howie
2021-06-02 19:34:25 +08:00
committed by GitHub
parent debf8c76a3
commit da8dbe6085
4 changed files with 28 additions and 10 deletions

View File

@ -3012,7 +3012,7 @@ func (s *testDBSuite2) TestTableForeignKey(c *C) {
tk.MustExec("create table t3 (a int, b int);")
failSQL = "alter table t1 add foreign key (c) REFERENCES t3(a);"
tk.MustGetErrCode(failSQL, errno.ErrKeyColumnDoesNotExits)
// test oreign key not match error
// test origin key not match error
failSQL = "alter table t1 add foreign key (a) REFERENCES t3(a, b);"
tk.MustGetErrCode(failSQL, errno.ErrWrongFkDef)
// Test drop column with foreign key.
@ -3031,6 +3031,24 @@ func (s *testDBSuite2) TestTableForeignKey(c *C) {
tk.MustExec("drop table if exists t1,t2,t3,t4;")
}
func (s *testDBSuite2) TestTemporaryTableForeignKey(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t1 (a int, b int);")
tk.MustExec("drop table if exists t1_tmp;")
tk.MustExec("create global temporary table t1_tmp (a int, b int) on commit delete rows;")
// test add foreign key.
tk.MustExec("drop table if exists t2;")
tk.MustExec("create table t2 (a int, b int);")
failSQL := "alter table t1_tmp add foreign key (c) REFERENCES t2(a);"
tk.MustGetErrCode(failSQL, mysql.ErrCannotAddForeign)
// Test drop column with foreign key.
failSQL = "create global temporary table t3 (c int,d int,foreign key (d) references t1 (b)) on commit delete rows;"
tk.MustGetErrCode(failSQL, mysql.ErrCannotAddForeign)
tk.MustExec("drop table if exists t1,t2,t3,t1_tmp;")
}
func (s *testDBSuite8) TestFKOnGeneratedColumns(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")

View File

@ -5267,6 +5267,9 @@ func (d *ddl) CreateForeignKey(ctx sessionctx.Context, ti ast.Ident, fkName mode
if err != nil {
return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ti.Schema, ti.Name))
}
if t.Meta().TempTableType != model.TempTableNone {
return infoschema.ErrCannotAddForeign
}
fkInfo, err := buildFKInfo(fkName, keys, refer, t.Cols(), t.Meta())
if err != nil {

View File

@ -534,13 +534,6 @@ func (s *testSerialSuite) TestCreateTableWithLike(c *C) {
_, err = tk.Exec("create table temporary_table_t1 like temporary_table")
c.Assert(err.Error(), Equals, core.ErrOptOnTemporaryTable.GenWithStackByArgs("create table like").Error())
tk.MustExec("drop table if exists temporary_table;")
tk.MustExec("drop table if exists temporary_table_like;")
tk.MustExec("create table temporary_table (a int, b int,index(a))")
tk.MustExec("drop table if exists temporary_table_like_t1;")
_, err = tk.Exec("create global temporary table temporary_table_like_t1 like temporary_table on commit delete rows;")
c.Assert(err.Error(), Equals, core.ErrOptOnTemporaryTable.GenWithStackByArgs("create table like").Error())
tk.MustExec("drop table if exists temporary_table_like;")
}
// TestCancelAddIndex1 tests canceling ddl job when the add index worker is not started.

View File

@ -3481,8 +3481,12 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.IndexPriv, v.Table.Schema.L,
v.Table.Name.L, "", authErr)
case *ast.CreateTableStmt:
if v.TemporaryKeyword != ast.TemporaryNone && v.ReferTable != nil {
return nil, ErrOptOnTemporaryTable.GenWithStackByArgs("create table like")
if v.TemporaryKeyword != ast.TemporaryNone {
for _, cons := range v.Constraints {
if cons.Tp == ast.ConstraintForeignKey {
return nil, infoschema.ErrCannotAddForeign
}
}
}
if b.ctx.GetSessionVars().User != nil {
authErr = ErrTableaccessDenied.GenWithStackByArgs("CREATE", b.ctx.GetSessionVars().User.AuthUsername,