From 05355ab51e013eddddc803d03cfbd41d71b243e7 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Tue, 18 May 2021 18:10:39 +0800 Subject: [PATCH 1/3] ddl: grammar check for create unsupported temporary table --- ddl/db_integration_test.go | 22 ++++++++++++++++++++++ ddl/ddl_api.go | 14 +++++++++++++- ddl/error.go | 3 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index 405ada57f15ec..1db598d420fc3 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -2803,3 +2803,25 @@ func (s *testIntegrationSuite3) TestIssue21835(c *C) { _, err := tk.Exec("create table t( col decimal(1,2) not null default 0);") c.Assert(err.Error(), Equals, "[types:1427]For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'col').") } + +func (s *testIntegrationSuite3) TestCreateTemporaryTable(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t;") + + // Grammar error. + tk.MustGetErrCode("create global temporary table t(a double(0, 0))", errno.ErrParse) + tk.MustGetErrCode("create temporary table t(id int) on commit delete rows", errno.ErrParse) + tk.MustGetErrCode("create temporary table t(id int) on commit preserve rows", errno.ErrParse) + + // Not support yet. + tk.MustGetErrCode("create global temporary table t (id int) on commit preserve rows", errno.ErrUnsupportedDDLOperation) + // Engine type can only be 'memory' or empty for now. + tk.MustGetErrCode("create global temporary table t (id int) engine = 'innodb' on commit delete rows", errno.ErrUnsupportedDDLOperation) + // Follow the behaviour of the old version TiDB: parse and ignore the 'temporary' keyword. + tk.MustGetErrCode("create temporary table t(id int)", errno.ErrNotSupportedYet) + + tk.MustExec("set @@tidb_enable_noop_functions = 1") + tk.MustExec("create temporary table t (id int)") + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning 1105 TiDB doesn't support local TEMPORARY TABLE yet, TEMPORARY will be parsed but ignored.")) +} diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index d0289dc19e39f..c4cf7d2858dcd 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1736,8 +1736,14 @@ func buildTableInfoWithStmt(ctx sessionctx.Context, s *ast.CreateTableStmt, dbCh switch s.TemporaryKeyword { case ast.TemporaryGlobal: tbInfo.TempTableType = model.TempTableGlobal + // "create global temporary table ... on commit preserve rows" + if s.OnCommitDelete == false { + return nil, errors.Trace(errUnsupportedOnCommitPreserve) + } case ast.TemporaryLocal: - tbInfo.TempTableType = model.TempTableLocal + // TODO: set "tbInfo.TempTableType = model.TempTableLocal" after local temporary table is supported. + tbInfo.TempTableType = model.TempTableNone + ctx.GetSessionVars().StmtCtx.AppendWarning(errors.New("TiDB doesn't support local TEMPORARY TABLE yet, TEMPORARY will be parsed but ignored.")) case ast.TemporaryNone: tbInfo.TempTableType = model.TempTableNone } @@ -2217,6 +2223,12 @@ func handleTableOptions(options []*ast.TableOption, tbInfo *model.TableInfo) err tbInfo.PreSplitRegions = op.UintValue case ast.TableOptionCharset, ast.TableOptionCollate: // We don't handle charset and collate here since they're handled in `getCharsetAndCollateInTableOption`. + case ast.TableOptionEngine: + if tbInfo.TempTableType != model.TempTableNone { + if op.StrValue != "" && op.StrValue != "memory" { + return errors.Trace(errUnsupportedEngineTemporary) + } + } } } shardingBits := shardingBits(tbInfo) diff --git a/ddl/error.go b/ddl/error.go index 463c9c405a19e..f6ca69b216341 100644 --- a/ddl/error.go +++ b/ddl/error.go @@ -277,4 +277,7 @@ var ( // ErrPartitionNoTemporary returns when partition at temporary mode ErrPartitionNoTemporary = dbterror.ClassDDL.NewStd(mysql.ErrPartitionNoTemporary) + + errUnsupportedOnCommitPreserve = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message("TiDB doesn't support ON COMMIT PRESERVE ROWS for now", nil)) + errUnsupportedEngineTemporary = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message("TiDB doesn't this kind of engine for temporary table", nil)) ) From 80198b6c6e6489cd3790b83350af9dcb370ea7ce Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Tue, 18 May 2021 19:24:23 +0800 Subject: [PATCH 2/3] make golint happy --- ddl/db_integration_test.go | 2 +- ddl/ddl_api.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index 1db598d420fc3..9ad3ca49c2259 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -2823,5 +2823,5 @@ func (s *testIntegrationSuite3) TestCreateTemporaryTable(c *C) { tk.MustExec("set @@tidb_enable_noop_functions = 1") tk.MustExec("create temporary table t (id int)") - tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning 1105 TiDB doesn't support local TEMPORARY TABLE yet, TEMPORARY will be parsed but ignored.")) + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning 1105 local TEMPORARY TABLE is not supported yet, TEMPORARY will be parsed but ignored")) } diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index c4cf7d2858dcd..1da5804bba366 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1737,13 +1737,13 @@ func buildTableInfoWithStmt(ctx sessionctx.Context, s *ast.CreateTableStmt, dbCh case ast.TemporaryGlobal: tbInfo.TempTableType = model.TempTableGlobal // "create global temporary table ... on commit preserve rows" - if s.OnCommitDelete == false { + if !s.OnCommitDelete { 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("TiDB doesn't support local TEMPORARY TABLE yet, TEMPORARY will be parsed but ignored.")) + 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 } From dc9349bc4aa23b18815bb8bd08e9bcb16e8f980f Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Wed, 19 May 2021 16:14:42 +0800 Subject: [PATCH 3/3] address comment --- ddl/db_integration_test.go | 2 ++ ddl/ddl_api.go | 2 +- ddl/error.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index 9ad3ca49c2259..b1eabd3fc3661 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -2813,6 +2813,8 @@ func (s *testIntegrationSuite3) TestCreateTemporaryTable(c *C) { tk.MustGetErrCode("create global temporary table t(a double(0, 0))", errno.ErrParse) tk.MustGetErrCode("create temporary table t(id int) on commit delete rows", errno.ErrParse) tk.MustGetErrCode("create temporary table t(id int) on commit preserve rows", errno.ErrParse) + tk.MustGetErrCode("create table t(id int) on commit delete rows", errno.ErrParse) + tk.MustGetErrCode("create table t(id int) on commit preserve rows", errno.ErrParse) // Not support yet. tk.MustGetErrCode("create global temporary table t (id int) on commit preserve rows", errno.ErrUnsupportedDDLOperation) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 1da5804bba366..2cfd3f524a29f 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -2225,7 +2225,7 @@ func handleTableOptions(options []*ast.TableOption, tbInfo *model.TableInfo) err // We don't handle charset and collate here since they're handled in `getCharsetAndCollateInTableOption`. case ast.TableOptionEngine: if tbInfo.TempTableType != model.TempTableNone { - if op.StrValue != "" && op.StrValue != "memory" { + if op.StrValue != "" && !strings.EqualFold(op.StrValue, "memory") { return errors.Trace(errUnsupportedEngineTemporary) } } diff --git a/ddl/error.go b/ddl/error.go index f6ca69b216341..6bde83badb41b 100644 --- a/ddl/error.go +++ b/ddl/error.go @@ -279,5 +279,5 @@ var ( ErrPartitionNoTemporary = dbterror.ClassDDL.NewStd(mysql.ErrPartitionNoTemporary) errUnsupportedOnCommitPreserve = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message("TiDB doesn't support ON COMMIT PRESERVE ROWS for now", nil)) - errUnsupportedEngineTemporary = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message("TiDB doesn't this kind of engine for temporary table", nil)) + errUnsupportedEngineTemporary = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message("TiDB doesn't support this kind of engine for temporary table", nil)) )