diff --git a/executor/show.go b/executor/show.go index eec2437d52..ee8c286280 100644 --- a/executor/show.go +++ b/executor/show.go @@ -813,7 +813,7 @@ func ConstructResultOfShowCreateTable(ctx sessionctx.Context, tableInfo *model.T } } if tableInfo.PKIsHandle && tableInfo.ContainsAutoRandomBits() && tableInfo.GetPkName().L == col.Name.L { - buf.WriteString(fmt.Sprintf(" /*T!%s AUTO_RANDOM(%d) */", parser.CommentCodeAutoRandom, tableInfo.AutoRandomBits)) + buf.WriteString(fmt.Sprintf(" /*T![auto_rand] AUTO_RANDOM(%d) */", tableInfo.AutoRandomBits)) } if len(col.Comment) > 0 { buf.WriteString(fmt.Sprintf(" COMMENT '%s'", format.OutputFormat(col.Comment))) diff --git a/executor/show_test.go b/executor/show_test.go index db5f2d01d1..5955f08686 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -663,7 +663,7 @@ func (s *testAutoRandomSuite) TestShowCreateTableAutoRandom(c *C) { tk.MustQuery("show create table `auto_random_tbl1`").Check(testutil.RowsWithSep("|", ""+ "auto_random_tbl1 CREATE TABLE `auto_random_tbl1` (\n"+ - " `a` bigint(20) NOT NULL /*T!30100 AUTO_RANDOM(3) */,\n"+ + " `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(3) */,\n"+ " `b` varchar(255) DEFAULT NULL,\n"+ " PRIMARY KEY (`a`)\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", @@ -674,18 +674,18 @@ func (s *testAutoRandomSuite) TestShowCreateTableAutoRandom(c *C) { tk.MustQuery("show create table auto_random_tbl2").Check(testutil.RowsWithSep("|", ""+ "auto_random_tbl2 CREATE TABLE `auto_random_tbl2` (\n"+ - " `a` bigint(20) NOT NULL /*T!30100 AUTO_RANDOM(5) */,\n"+ + " `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+ " `b` char(1) DEFAULT NULL,\n"+ " PRIMARY KEY (`a`)\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", )) // Special version comment can be shown in TiDB with new version. - tk.MustExec("create table auto_random_tbl3 (a bigint /*T!30100 auto_random */ primary key)") + tk.MustExec("create table auto_random_tbl3 (a bigint /*T![auto_rand] auto_random */ primary key)") tk.MustQuery("show create table auto_random_tbl3").Check(testutil.RowsWithSep("|", ""+ "auto_random_tbl3 CREATE TABLE `auto_random_tbl3` (\n"+ - " `a` bigint(20) NOT NULL /*T!30100 AUTO_RANDOM(5) */,\n"+ + " `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+ " PRIMARY KEY (`a`)\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", )) diff --git a/go.mod b/go.mod index 9b0422046e..4567c04e1b 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 github.com/pingcap/kvproto v0.0.0-20200330093347-98f910b71904 github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd - github.com/pingcap/parser v0.0.0-20200326020624-68d423641be5 + github.com/pingcap/parser v0.0.0-20200331080149-8dce7a46a199 github.com/pingcap/pd/v4 v4.0.0-beta.1.0.20200305072537-61d9f9cc35d3 github.com/pingcap/sysutil v0.0.0-20200309085538-962fd285f3bb github.com/pingcap/tidb-tools v4.0.0-beta.1.0.20200306084441-875bd09aa3d5+incompatible diff --git a/go.sum b/go.sum index 88d54f492d..a4c20afd0a 100644 --- a/go.sum +++ b/go.sum @@ -267,8 +267,8 @@ github.com/pingcap/kvproto v0.0.0-20200330093347-98f910b71904/go.mod h1:IOdRDPLy github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd h1:CV3VsP3Z02MVtdpTMfEgRJ4T9NGgGTxdHpJerent7rM= github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= -github.com/pingcap/parser v0.0.0-20200326020624-68d423641be5 h1:fXVqoeYfV+xI8K2he5NNv00c6YksrjeM6+vkNo1ZK2Q= -github.com/pingcap/parser v0.0.0-20200326020624-68d423641be5/go.mod h1:9v0Edh8IbgjGYW2ArJr19E+bvL8zKahsFp+ixWeId+4= +github.com/pingcap/parser v0.0.0-20200331080149-8dce7a46a199 h1:ooT7ZSLDA1VkTXppmDxCEmJO3p/nWWIBQG+3pOguSK0= +github.com/pingcap/parser v0.0.0-20200331080149-8dce7a46a199/go.mod h1:9v0Edh8IbgjGYW2ArJr19E+bvL8zKahsFp+ixWeId+4= github.com/pingcap/pd/v4 v4.0.0-beta.1.0.20200305072537-61d9f9cc35d3 h1:Yrp99FnjHAEuDrSBql2l0IqCtJX7KwJbTsD5hIArkvk= github.com/pingcap/pd/v4 v4.0.0-beta.1.0.20200305072537-61d9f9cc35d3/go.mod h1:25GfNw6+Jcr9kca5rtmTb4gKCJ4jOpow2zV2S9Dgafs= github.com/pingcap/sysutil v0.0.0-20200206130906-2bfa6dc40bcd/go.mod h1:EB/852NMQ+aRKioCpToQ94Wl7fktV+FNnxf3CX/TTXI= diff --git a/sessionctx/binloginfo/binloginfo.go b/sessionctx/binloginfo/binloginfo.go index eb1da52b06..608abe4ecd 100644 --- a/sessionctx/binloginfo/binloginfo.go +++ b/sessionctx/binloginfo/binloginfo.go @@ -14,7 +14,6 @@ package binloginfo import ( - "fmt" "math" "regexp" "strings" @@ -23,7 +22,6 @@ import ( "time" "github.com/pingcap/errors" - "github.com/pingcap/parser" "github.com/pingcap/parser/terror" "github.com/pingcap/tidb-tools/tidb-binlog/node" pumpcli "github.com/pingcap/tidb-tools/tidb-binlog/pump_client" @@ -31,6 +29,7 @@ import ( "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/sessionctx" + driver "github.com/pingcap/tidb/types/parser_driver" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tipb/go-binlog" "go.uber.org/zap" @@ -300,16 +299,17 @@ func SetDDLBinlog(client *pumpcli.PumpsClient, txn kv.Transaction, jobID int64, } const specialPrefix = `/*!90000 ` -const specialVersionPrefix = `/*T!%s ` // AddSpecialComment uses to add comment for table option in DDL query. // Export for testing. func AddSpecialComment(ddlQuery string) string { - if strings.Contains(ddlQuery, specialPrefix) || parser.SpecVersionCodePattern.MatchString(ddlQuery) { + if strings.Contains(ddlQuery, specialPrefix) || strings.Contains(ddlQuery, driver.SpecialCommentVersionPrefix) { return ddlQuery } ddlQuery = addSpecialCommentByRegexps(ddlQuery, specialPrefix, shardPat, preSplitPat) - ddlQuery = addSpecialCommentByRegexps(ddlQuery, fmt.Sprintf(specialVersionPrefix, parser.CommentCodeAutoRandom), autoRandomPat) + for featureID, pattern := range driver.FeatureIDPatterns { + ddlQuery = addSpecialCommentByRegexps(ddlQuery, driver.BuildSpecialCommentPrefix(featureID), pattern) + } return ddlQuery } diff --git a/sessionctx/binloginfo/binloginfo_test.go b/sessionctx/binloginfo/binloginfo_test.go index 1ad3973f93..9ed7bb0c7d 100644 --- a/sessionctx/binloginfo/binloginfo_test.go +++ b/sessionctx/binloginfo/binloginfo_test.go @@ -549,15 +549,15 @@ func (s *testBinlogSuite) TestAddSpecialComment(c *C) { }, { "create table t1 (id int primary key auto_random(2));", - "create table t1 (id int primary key /*T!30100 auto_random(2) */ );", + "create table t1 (id int primary key /*T![auto_rand] auto_random(2) */ );", }, { "create table t1 (id int auto_random ( 4 ) primary key);", - "create table t1 (id int /*T!30100 auto_random ( 4 ) */ primary key);", + "create table t1 (id int /*T![auto_rand] auto_random ( 4 ) */ primary key);", }, { "create table t1 (id int auto_random ( 4 ) primary key);", - "create table t1 (id int /*T!30100 auto_random ( 4 ) */ primary key);", + "create table t1 (id int /*T![auto_rand] auto_random ( 4 ) */ primary key);", }, } for _, ca := range testCase { diff --git a/types/parser_driver/special_cmt_ctrl.go b/types/parser_driver/special_cmt_ctrl.go new file mode 100644 index 0000000000..8a43241411 --- /dev/null +++ b/types/parser_driver/special_cmt_ctrl.go @@ -0,0 +1,55 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package driver + +import ( + "fmt" + "regexp" + + "github.com/pingcap/parser" +) + +// To add new features that needs to be downgrade-compatible, +// 1. Define a featureID below and make sure it is unique. +// For example, `const FeatureIDMyFea = "my_fea"`. +// 2. Register the new featureID in init(). +// Only the registered parser can parse the comment annotated with `my_fea`. +// Now, the parser treats `/*T![my_fea] what_ever */` and `what_ever` equivalent. +// In other word, the parser in old-version TiDB will ignores these comments. +// 3. [optional] Add a pattern into FeatureIDPatterns. +// This is only required if the new feature is contained in DDL, +// and we want to comment out this part of SQL in binlog. +func init() { + parser.SpecialCommentsController.Register(string(FeatureIDAutoRandom)) +} + +// SpecialCommentVersionPrefix is the prefix of TiDB executable comments. +const SpecialCommentVersionPrefix = `/*T!` + +// BuildSpecialCommentPrefix returns the prefix of `featureID` special comment. +func BuildSpecialCommentPrefix(featureID featureID) string { + return fmt.Sprintf("%s[%s]", SpecialCommentVersionPrefix, featureID) +} + +type featureID string + +const ( + // FeatureIDAutoRandom is the `auto_random` feature. + FeatureIDAutoRandom featureID = "auto_rand" +) + +// FeatureIDPatterns is used to record special comments patterns. +var FeatureIDPatterns = map[featureID]*regexp.Regexp{ + FeatureIDAutoRandom: regexp.MustCompile(`(?i)AUTO_RANDOM\s*(\(\s*\d+\s*\))?\s*`), +}