From 34496801d0a679634ae0aa2c4fbe7640189c6284 Mon Sep 17 00:00:00 2001 From: lihaowei Date: Tue, 22 Jun 2021 10:25:53 +0800 Subject: [PATCH 1/6] fix issue#25613 Signed-off-by: lihaowei --- ddl/ddl_api.go | 7 +++++++ ddl/serial_test.go | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index a2cb983d533ac..dda4c7051489e 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1815,6 +1815,13 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e if err != nil { return errors.Trace(err) } + switch s.TemporaryKeyword { + case ast.TemporaryGlobal: + tbInfo.TempTableType = model.TempTableGlobal + case ast.TemporaryLocal: + tbInfo.TempTableType = model.TempTableLocal + default: + } if err = checkTableInfoValidWithStmt(ctx, tbInfo, s); err != nil { return err diff --git a/ddl/serial_test.go b/ddl/serial_test.go index b06139c8dd312..76d222a8947ed 100644 --- a/ddl/serial_test.go +++ b/ddl/serial_test.go @@ -613,6 +613,23 @@ func (s *testSerialSuite) TestCreateTableWithLikeAtTemporaryMode(c *C) { c.Assert(err, IsNil) tableInfo := table.Meta() c.Assert(len(tableInfo.ForeignKeys), Equals, 0) + + // Issue 25613. + tk.MustExec("drop table if exists tb2, tb3") + tk.MustExec("create table tb2(id int);") + tk.MustExec("create global temporary table tb3 like tb2 on commit delete rows;") + defer tk.MustExec("drop table if exists tb2, tb3") + tk.MustQuery("show create table tb3;").Check(testkit.Rows("tb3 CREATE GLOBAL TEMPORARY TABLE `tb3` (\n" + + " `id` int(11) DEFAULT NULL\n" + + ") ENGINE=memory DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ON COMMIT DELETE ROWS")) + + tk.MustExec("drop table if exists tb4, tb5") + tk.MustExec("create table tb4(id int);") + tk.MustExec("create table tb5 like tb4") + defer tk.MustExec("drop table if exists tb4, tb5") + tk.MustQuery("show create table tb5;").Check(testkit.Rows("tb5 CREATE TABLE `tb5` (\n" + + " `id` int(11) DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) } // TestCancelAddIndex1 tests canceling ddl job when the add index worker is not started. From 2f6509c0de0e0c5ef65a58e9279107dceb0e83fb Mon Sep 17 00:00:00 2001 From: lihaowei Date: Tue, 22 Jun 2021 12:52:23 +0800 Subject: [PATCH 2/6] extract a func Signed-off-by: lihaowei --- ddl/ddl_api.go | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index dda4c7051489e..eabd592503a07 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1731,9 +1731,9 @@ func buildTableInfoWithStmt(ctx sessionctx.Context, s *ast.CreateTableStmt, dbCh if err != nil { return nil, errors.Trace(err) } + setTemporaryType(tbInfo, s.TemporaryKeyword) switch s.TemporaryKeyword { case ast.TemporaryGlobal: - tbInfo.TempTableType = model.TempTableGlobal if !ctx.GetSessionVars().EnableGlobalTemporaryTable { return nil, errors.New("global temporary table is experimental and it is switched off by tidb_enable_global_temporary_table") } @@ -1742,11 +1742,8 @@ func buildTableInfoWithStmt(ctx sessionctx.Context, s *ast.CreateTableStmt, dbCh return nil, errors.Trace(errUnsupportedOnCommitPreserve) } case ast.TemporaryLocal: - // TODO: set "tbInfo.TempTableType = model.TempTableLocal" after local temporary table is supported. - tbInfo.TempTableType = model.TempTableNone ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("local TEMPORARY TABLE is not supported yet, TEMPORARY will be parsed but ignored")) - case ast.TemporaryNone: - tbInfo.TempTableType = model.TempTableNone + default: } if err = setTableAutoRandomBits(ctx, tbInfo, colDefs); err != nil { @@ -1815,13 +1812,7 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e if err != nil { return errors.Trace(err) } - switch s.TemporaryKeyword { - case ast.TemporaryGlobal: - tbInfo.TempTableType = model.TempTableGlobal - case ast.TemporaryLocal: - tbInfo.TempTableType = model.TempTableLocal - default: - } + setTemporaryType(tbInfo, s.TemporaryKeyword) if err = checkTableInfoValidWithStmt(ctx, tbInfo, s); err != nil { return err @@ -1835,6 +1826,18 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e return d.CreateTableWithInfo(ctx, schema.Name, tbInfo, onExist, false /*tryRetainID*/) } +func setTemporaryType(tbInfo *model.TableInfo, temporaryWord ast.TemporaryKeyword) { + switch temporaryWord { + case ast.TemporaryGlobal: + tbInfo.TempTableType = model.TempTableGlobal + case ast.TemporaryLocal: + // TODO: set "tbInfo.TempTableType = model.TempTableLocal" after local temporary table is supported. + tbInfo.TempTableType = model.TempTableNone + default: + tbInfo.TempTableType = model.TempTableNone + } +} + func (d *ddl) CreateTableWithInfo( ctx sessionctx.Context, dbName model.CIStr, From d1e0a76783465f5290f4e1a731cff894c20abdbd Mon Sep 17 00:00:00 2001 From: lihaowei Date: Tue, 22 Jun 2021 15:36:20 +0800 Subject: [PATCH 3/6] modify Signed-off-by: lihaowei --- ddl/ddl_api.go | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index eabd592503a07..a1fefdb11d9a3 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1731,19 +1731,8 @@ func buildTableInfoWithStmt(ctx sessionctx.Context, s *ast.CreateTableStmt, dbCh if err != nil { return nil, errors.Trace(err) } - setTemporaryType(tbInfo, s.TemporaryKeyword) - switch s.TemporaryKeyword { - case ast.TemporaryGlobal: - if !ctx.GetSessionVars().EnableGlobalTemporaryTable { - return nil, errors.New("global temporary table is experimental and it is switched off by tidb_enable_global_temporary_table") - } - // "create global temporary table ... on commit preserve rows" - if !s.OnCommitDelete { - return nil, errors.Trace(errUnsupportedOnCommitPreserve) - } - case ast.TemporaryLocal: - ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("local TEMPORARY TABLE is not supported yet, TEMPORARY will be parsed but ignored")) - default: + if err = setTemporaryType(ctx, tbInfo, s); err != nil { + return nil, errors.Trace(err) } if err = setTableAutoRandomBits(ctx, tbInfo, colDefs); err != nil { @@ -1812,7 +1801,9 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e if err != nil { return errors.Trace(err) } - setTemporaryType(tbInfo, s.TemporaryKeyword) + if err = setTemporaryType(ctx, tbInfo, s); err != nil { + return errors.Trace(err) + } if err = checkTableInfoValidWithStmt(ctx, tbInfo, s); err != nil { return err @@ -1826,16 +1817,25 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e return d.CreateTableWithInfo(ctx, schema.Name, tbInfo, onExist, false /*tryRetainID*/) } -func setTemporaryType(tbInfo *model.TableInfo, temporaryWord ast.TemporaryKeyword) { - switch temporaryWord { +func setTemporaryType(ctx sessionctx.Context, tbInfo *model.TableInfo, s *ast.CreateTableStmt) error { + switch s.TemporaryKeyword { case ast.TemporaryGlobal: tbInfo.TempTableType = model.TempTableGlobal + if !ctx.GetSessionVars().EnableGlobalTemporaryTable { + return errors.New("global temporary table is experimental and it is switched off by tidb_enable_global_temporary_table") + } + // "create global temporary table ... on commit preserve rows" + if !s.OnCommitDelete { + return errors.Trace(errUnsupportedOnCommitPreserve) + } case ast.TemporaryLocal: // TODO: set "tbInfo.TempTableType = model.TempTableLocal" after local temporary table is supported. tbInfo.TempTableType = model.TempTableNone + ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("local TEMPORARY TABLE is not supported yet, TEMPORARY will be parsed but ignored")) default: tbInfo.TempTableType = model.TempTableNone } + return nil } func (d *ddl) CreateTableWithInfo( From 6489a9f7cee8c1bddbf8c77b24df54e5b4acfe44 Mon Sep 17 00:00:00 2001 From: lihaowei Date: Tue, 22 Jun 2021 16:09:08 +0800 Subject: [PATCH 4/6] fix err Signed-off-by: lihaowei --- ddl/ddl_api.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index a1fefdb11d9a3..fc2a0f88aeec1 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1734,6 +1734,9 @@ func buildTableInfoWithStmt(ctx sessionctx.Context, s *ast.CreateTableStmt, dbCh if err = setTemporaryType(ctx, tbInfo, s); err != nil { return nil, errors.Trace(err) } + if s.TemporaryKeyword == ast.TemporaryLocal { + ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("local TEMPORARY TABLE is not supported yet, TEMPORARY will be parsed but ignored")) + } if err = setTableAutoRandomBits(ctx, tbInfo, colDefs); err != nil { return nil, errors.Trace(err) @@ -1831,7 +1834,6 @@ func setTemporaryType(ctx sessionctx.Context, tbInfo *model.TableInfo, s *ast.Cr case ast.TemporaryLocal: // TODO: set "tbInfo.TempTableType = model.TempTableLocal" after local temporary table is supported. tbInfo.TempTableType = model.TempTableNone - ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("local TEMPORARY TABLE is not supported yet, TEMPORARY will be parsed but ignored")) default: tbInfo.TempTableType = model.TempTableNone } From b6df923ae819c315937a5f709913def39252f1c5 Mon Sep 17 00:00:00 2001 From: lihaowei Date: Wed, 23 Jun 2021 22:13:26 +0800 Subject: [PATCH 5/6] format code --- ddl/ddl_api.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index fc2a0f88aeec1..5cec63b7d51b2 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1638,12 +1638,15 @@ func checkTableInfoValid(tblInfo *model.TableInfo) error { return checkInvisibleIndexOnPK(tblInfo) } -func buildTableInfoWithLike(ident ast.Ident, referTblInfo *model.TableInfo, s *ast.CreateTableStmt) (*model.TableInfo, error) { +func buildTableInfoWithLike(ctx sessionctx.Context, ident ast.Ident, referTblInfo *model.TableInfo, s *ast.CreateTableStmt) (*model.TableInfo, error) { // Check the referred table is a real table object. if referTblInfo.IsSequence() || referTblInfo.IsView() { return nil, ErrWrongObject.GenWithStackByArgs(ident.Schema, referTblInfo.Name, "BASE TABLE") } tblInfo := *referTblInfo + if err := setTemporaryType(ctx, &tblInfo, s); err != nil { + return nil, errors.Trace(err) + } // Check non-public column and adjust column offset. newColumns := referTblInfo.Cols() newIndices := make([]*model.IndexInfo, 0, len(tblInfo.Indices)) @@ -1734,9 +1737,6 @@ func buildTableInfoWithStmt(ctx sessionctx.Context, s *ast.CreateTableStmt, dbCh if err = setTemporaryType(ctx, tbInfo, s); err != nil { return nil, errors.Trace(err) } - if s.TemporaryKeyword == ast.TemporaryLocal { - ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("local TEMPORARY TABLE is not supported yet, TEMPORARY will be parsed but ignored")) - } if err = setTableAutoRandomBits(ctx, tbInfo, colDefs); err != nil { return nil, errors.Trace(err) @@ -1797,16 +1797,13 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e // build tableInfo var tbInfo *model.TableInfo if s.ReferTable != nil { - tbInfo, err = buildTableInfoWithLike(ident, referTbl.Meta(), s) + tbInfo, err = buildTableInfoWithLike(ctx, ident, referTbl.Meta(), s) } else { tbInfo, err = buildTableInfoWithStmt(ctx, s, schema.Charset, schema.Collate) } if err != nil { return errors.Trace(err) } - if err = setTemporaryType(ctx, tbInfo, s); err != nil { - return errors.Trace(err) - } if err = checkTableInfoValidWithStmt(ctx, tbInfo, s); err != nil { return err @@ -1834,6 +1831,7 @@ func setTemporaryType(ctx sessionctx.Context, tbInfo *model.TableInfo, s *ast.Cr case ast.TemporaryLocal: // TODO: set "tbInfo.TempTableType = model.TempTableLocal" after local temporary table is supported. tbInfo.TempTableType = model.TempTableNone + ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("local TEMPORARY TABLE is not supported yet, TEMPORARY will be parsed but ignored")) default: tbInfo.TempTableType = model.TempTableNone } From ec1347c421f2f41eec477172ccb2b281678bd982 Mon Sep 17 00:00:00 2001 From: lihaowei Date: Thu, 24 Jun 2021 16:11:04 +0800 Subject: [PATCH 6/6] add tests --- ddl/serial_test.go | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/ddl/serial_test.go b/ddl/serial_test.go index 76d222a8947ed..82ed77d82fd16 100644 --- a/ddl/serial_test.go +++ b/ddl/serial_test.go @@ -615,21 +615,37 @@ func (s *testSerialSuite) TestCreateTableWithLikeAtTemporaryMode(c *C) { c.Assert(len(tableInfo.ForeignKeys), Equals, 0) // Issue 25613. - tk.MustExec("drop table if exists tb2, tb3") - tk.MustExec("create table tb2(id int);") - tk.MustExec("create global temporary table tb3 like tb2 on commit delete rows;") - defer tk.MustExec("drop table if exists tb2, tb3") - tk.MustQuery("show create table tb3;").Check(testkit.Rows("tb3 CREATE GLOBAL TEMPORARY TABLE `tb3` (\n" + + // Test from->normal, to->normal. + tk.MustExec("drop table if exists tb1, tb2") + tk.MustExec("create table tb1(id int);") + tk.MustExec("create table tb2 like tb1") + defer tk.MustExec("drop table if exists tb1, tb2") + tk.MustQuery("show create table tb2;").Check(testkit.Rows("tb2 CREATE TABLE `tb2` (\n" + " `id` int(11) DEFAULT NULL\n" + - ") ENGINE=memory DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ON COMMIT DELETE ROWS")) + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - tk.MustExec("drop table if exists tb4, tb5") - tk.MustExec("create table tb4(id int);") - tk.MustExec("create table tb5 like tb4") - defer tk.MustExec("drop table if exists tb4, tb5") - tk.MustQuery("show create table tb5;").Check(testkit.Rows("tb5 CREATE TABLE `tb5` (\n" + + // Test from->normal, to->global temporary. + tk.MustExec("drop table if exists tb3, tb4") + tk.MustExec("create table tb3(id int);") + tk.MustExec("create global temporary table tb4 like tb3 on commit delete rows;") + defer tk.MustExec("drop table if exists tb3, tb4") + tk.MustQuery("show create table tb4;").Check(testkit.Rows("tb4 CREATE GLOBAL TEMPORARY TABLE `tb4` (\n" + " `id` int(11) DEFAULT NULL\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + ") ENGINE=memory DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ON COMMIT DELETE ROWS")) + + // Test from->global temporary, to->normal. + tk.MustExec("drop table if exists tb5, tb6") + tk.MustExec("create global temporary table tb5(id int) on commit delete rows;") + _, err = tk.Exec("create table tb6 like tb5;") + c.Assert(err.Error(), Equals, core.ErrOptOnTemporaryTable.GenWithStackByArgs("create table like").Error()) + defer tk.MustExec("drop table if exists tb5, tb6") + + // Test from->global temporary, to->global temporary. + tk.MustExec("drop table if exists tb7, tb8") + tk.MustExec("create global temporary table tb7(id int) on commit delete rows;") + _, err = tk.Exec("create global temporary table tb8 like tb7 on commit delete rows;") + c.Assert(err.Error(), Equals, core.ErrOptOnTemporaryTable.GenWithStackByArgs("create table like").Error()) + defer tk.MustExec("drop table if exists tb7, tb8") } // TestCancelAddIndex1 tests canceling ddl job when the add index worker is not started.