Skip to content

Commit

Permalink
ddl: add foreign key compatibility for temporary table (#24961)
Browse files Browse the repository at this point in the history
  • Loading branch information
Howie59 authored Jun 2, 2021
1 parent debf8c7 commit da8dbe6
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 10 deletions.
20 changes: 19 additions & 1 deletion ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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")
Expand Down
3 changes: 3 additions & 0 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 0 additions & 7 deletions ddl/serial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 6 additions & 2 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit da8dbe6

Please sign in to comment.