diff --git a/ddl/db_test.go b/ddl/db_test.go index 7ef7d23a82196..0bfc654941727 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -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") diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 4684d5d4cc7ef..640823b23305a 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -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 { diff --git a/ddl/serial_test.go b/ddl/serial_test.go index 62610e3279cf6..30c81bf2f2e7b 100644 --- a/ddl/serial_test.go +++ b/ddl/serial_test.go @@ -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. diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index 4df8572b19447..b743204a1db91 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -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,