From fa2a4df8388f150dd311a285f9b16eb525725e06 Mon Sep 17 00:00:00 2001 From: lihaowei Date: Fri, 28 May 2021 20:42:59 +0800 Subject: [PATCH 1/4] forbid foreign key Signed-off-by: lihaowei --- ddl/db_test.go | 21 ++++++++++++++++++++- ddl/ddl_api.go | 6 ++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index 80a821a40e387..74e3c6b2c2493 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -3011,7 +3011,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. @@ -3030,6 +3030,25 @@ 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);") + _, err := tk.Exec("alter table t1_tmp add foreign key (c) REFERENCES t2(a);") + c.Assert(err.Error(), Equals, ddl.ErrOptOnTemporaryTable.GenWithStackByArgs("foreign key").Error()) + // Test drop column with foreign key. + tk.MustExec("create global temporary table t3 (c int,d int,foreign key (d) references t1 (b)) on commit delete rows;") + _, err = tk.Exec("alter table t3 drop foreign key d") + c.Assert(err.Error(), Equals, ddl.ErrOptOnTemporaryTable.GenWithStackByArgs("foreign key").Error()) + 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 9c3eca13c7fee..189b1ad53d2ed 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -5264,6 +5264,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 ErrOptOnTemporaryTable.GenWithStackByArgs("foreign key") + } fkInfo, err := buildFKInfo(fkName, keys, refer, t.Cols(), t.Meta()) if err != nil { @@ -5296,6 +5299,9 @@ func (d *ddl) DropForeignKey(ctx sessionctx.Context, ti ast.Ident, fkName model. if err != nil { return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ti.Schema, ti.Name)) } + if t.Meta().TempTableType != model.TempTableNone { + return ErrOptOnTemporaryTable.GenWithStackByArgs("foreign key") + } job := &model.Job{ SchemaID: schema.ID, From 9fcfdebe92ebdfdcc95243fa6f7001ade44dd34a Mon Sep 17 00:00:00 2001 From: lihaowei Date: Mon, 31 May 2021 21:06:05 +0800 Subject: [PATCH 2/4] change err code Signed-off-by: lihaowei --- ddl/db_test.go | 8 ++++---- ddl/ddl_api.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index 74e3c6b2c2493..0aaf342ff6d09 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -3040,12 +3040,12 @@ func (s *testDBSuite2) TestTemporaryTableForeignKey(c *C) { // test add foreign key. tk.MustExec("drop table if exists t2;") tk.MustExec("create table t2 (a int, b int);") - _, err := tk.Exec("alter table t1_tmp add foreign key (c) REFERENCES t2(a);") - c.Assert(err.Error(), Equals, ddl.ErrOptOnTemporaryTable.GenWithStackByArgs("foreign key").Error()) + failSQL := "alter table t1_tmp add foreign key (c) REFERENCES t2(a);" + tk.MustGetErrCode(failSQL, mysql.ErrCannotAddForeign) // Test drop column with foreign key. tk.MustExec("create global temporary table t3 (c int,d int,foreign key (d) references t1 (b)) on commit delete rows;") - _, err = tk.Exec("alter table t3 drop foreign key d") - c.Assert(err.Error(), Equals, ddl.ErrOptOnTemporaryTable.GenWithStackByArgs("foreign key").Error()) + failSQL = "alter table t3 drop foreign key d" + tk.MustGetErrCode(failSQL, mysql.ErrCannotAddForeign) tk.MustExec("drop table if exists t1,t2,t3,t1_tmp;") } diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 189b1ad53d2ed..23f0febf44080 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -5265,7 +5265,7 @@ func (d *ddl) CreateForeignKey(ctx sessionctx.Context, ti ast.Ident, fkName mode return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ti.Schema, ti.Name)) } if t.Meta().TempTableType != model.TempTableNone { - return ErrOptOnTemporaryTable.GenWithStackByArgs("foreign key") + return infoschema.ErrCannotAddForeign } fkInfo, err := buildFKInfo(fkName, keys, refer, t.Cols(), t.Meta()) @@ -5300,7 +5300,7 @@ func (d *ddl) DropForeignKey(ctx sessionctx.Context, ti ast.Ident, fkName model. return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ti.Schema, ti.Name)) } if t.Meta().TempTableType != model.TempTableNone { - return ErrOptOnTemporaryTable.GenWithStackByArgs("foreign key") + return infoschema.ErrCannotAddForeign } job := &model.Job{ From 01848070fb028e2f51fc092f6c91efe36cc0e291 Mon Sep 17 00:00:00 2001 From: lihaowei Date: Wed, 2 Jun 2021 13:13:48 +0800 Subject: [PATCH 3/4] add check Signed-off-by: lihaowei --- ddl/db_test.go | 3 +-- ddl/ddl_api.go | 3 --- planner/core/planbuilder.go | 7 +++++++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index 0aaf342ff6d09..3f1c859b503ad 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -3043,8 +3043,7 @@ func (s *testDBSuite2) TestTemporaryTableForeignKey(c *C) { failSQL := "alter table t1_tmp add foreign key (c) REFERENCES t2(a);" tk.MustGetErrCode(failSQL, mysql.ErrCannotAddForeign) // Test drop column with foreign key. - tk.MustExec("create global temporary table t3 (c int,d int,foreign key (d) references t1 (b)) on commit delete rows;") - failSQL = "alter table t3 drop foreign key d" + 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;") } diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 23f0febf44080..3dc37796dee65 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -5299,9 +5299,6 @@ func (d *ddl) DropForeignKey(ctx sessionctx.Context, ti ast.Ident, fkName model. if err != nil { return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ti.Schema, ti.Name)) } - if t.Meta().TempTableType != model.TempTableNone { - return infoschema.ErrCannotAddForeign - } job := &model.Job{ SchemaID: schema.ID, diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index 6640af5785b81..f3e59e5d1c420 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -3471,6 +3471,13 @@ 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 { + 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, b.ctx.GetSessionVars().User.AuthHostname, v.Table.Name.L) From 88802e60b83394c78d325b67a0c9412315f29d3f Mon Sep 17 00:00:00 2001 From: lihaowei Date: Wed, 2 Jun 2021 16:17:22 +0800 Subject: [PATCH 4/4] remove unrelated Signed-off-by: lihaowei --- ddl/serial_test.go | 7 ------- planner/core/planbuilder.go | 3 --- 2 files changed, 10 deletions(-) diff --git a/ddl/serial_test.go b/ddl/serial_test.go index 8d9217e1df8e3..f78ff3d16577b 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 9cb607d3e1f1a..0a43cb85ea0f9 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -3480,9 +3480,6 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err return nil, infoschema.ErrCannotAddForeign } } - if v.ReferTable != nil { - return nil, ErrOptOnTemporaryTable.GenWithStackByArgs("create table like") - } } if b.ctx.GetSessionVars().User != nil { authErr = ErrTableaccessDenied.GenWithStackByArgs("CREATE", b.ctx.GetSessionVars().User.AuthUsername,