From c89926e169635b2f5410ae96e748b04cdacec98d Mon Sep 17 00:00:00 2001 From: feloxx Date: Thu, 10 Jan 2019 00:33:23 +0800 Subject: [PATCH 01/15] Restore_CreateTableStmt --- ast/ddl.go | 169 ++++++++++++++++++++++++++++++++++++++++++++++++- parser_test.go | 2 +- 2 files changed, 169 insertions(+), 2 deletions(-) diff --git a/ast/ddl.go b/ast/ddl.go index 54cc11ba3..dec9081e1 100755 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -675,7 +675,60 @@ type CreateTableStmt struct { // Restore implements Node interface. func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + ctx.WriteKeyWord("CREATE TABLE ") + if n.IfNotExists { + ctx.WriteKeyWord("IF NOT EXISTS ") + } + + if err := n.Table.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while splicing CreateTableStmt Table") + } + if n.ReferTable != nil { + ctx.WriteKeyWord("LIKE ") + if err := n.ReferTable.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while splicing CreateTableStmt ReferTable") + } + } + + ctx.WritePlain("(") + for i, col := range n.Cols { + if i > 0 { + ctx.WritePlain(" ") + } + if err := col.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt ColumnDef: [%v]", i) + } + } + for i, constraint := range n.Constraints { + if i > 0 { + ctx.WritePlain(",") + } + if err := constraint.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt Constraints: [%v]", i) + } + } + ctx.WritePlain(")") + + for i, option := range n.Options { + if i > 0 { + ctx.WritePlain(" ") + } + if err := option.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt TableOption: [%v]", i) + } + } + + if n.Partition != nil { + if err := n.Partition.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while splicing CreateTableStmt Partition") + } + } + + //TODO: Waiting for Create Select + //TODO: OnDuplicate + //TODO: Select + + return nil } // Accept implements Node Accept interface. @@ -1048,6 +1101,67 @@ type TableOption struct { UintValue uint64 } +func (n *TableOption) Restore(ctx *RestoreCtx) error { + switch n.Tp { + case TableOptionNone: + return nil + case TableOptionEngine: + ctx.WriteKeyWord("ENGINE = ") + ctx.WriteString(n.StrValue) + case TableOptionCharset: + ctx.WriteKeyWord("DEFAULT CHARACTER SET ") + ctx.WriteString(n.StrValue) + case TableOptionCollate: + ctx.WriteKeyWord("DEFAULT COLLATE") + ctx.WriteString(n.StrValue) + case TableOptionAutoIncrement: + ctx.WriteKeyWord("AUTO_INCREMENT ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionComment: + ctx.WriteKeyWord("COMMENT ") + ctx.WritePlain(n.StrValue) + case TableOptionAvgRowLength: + ctx.WriteKeyWord("AVG_ROW_LENGTH ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionConnection: + ctx.WriteKeyWord("CONNECTION ") + ctx.WritePlain(n.StrValue) + case TableOptionCheckSum: + ctx.WriteKeyWord("CHECKSUM ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionPassword: + ctx.WriteKeyWord("PASSWORD ") + ctx.WritePlain(n.StrValue) + case TableOptionCompression: + ctx.WriteKeyWord("COMPRESSION ") + ctx.WritePlain(n.StrValue) + case TableOptionKeyBlockSize: + ctx.WriteKeyWord("KEY_BLOCK_SIZE ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionMaxRows: + ctx.WriteKeyWord("MAX_ROWS ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionMinRows: + ctx.WriteKeyWord("MIN_ROWS ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionDelayKeyWrite: + ctx.WriteKeyWord("DELAY_KEY_WRITE ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionRowFormat: + ctx.WriteKeyWord("ROW_FORMAT ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionStatsPersistent: + ctx.WriteKeyWord("STATS_PERSISTENT") + case TableOptionShardRowID: + ctx.WriteKeyWord("SHARD_ROW_ID_BITS ") + ctx.WritePlainf("%d", n.UintValue) + case TableOptionPackKeys: + return errors.New("TiDB Parser ignore the `TableOptionPackKeys` type now") + } + + return nil +} + // ColumnPositionType is the type for ColumnPosition. type ColumnPositionType int @@ -1288,6 +1402,24 @@ type PartitionDefinition struct { Comment string } +func (n *PartitionDefinition) Restore(ctx *RestoreCtx) error { + ctx.WriteKeyWord("PARTITION ") + ctx.WriteName(n.Name.String()) + for i, lessThan := range n.LessThan { + if i > 0 { + ctx.WritePlain(" ") + } + if err := lessThan.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing PartitionDefinition LessThan: [%v]", i) + } + } + //if n.MaxValue { + // + //} + ctx.WritePlain(n.Comment) + return nil +} + // PartitionOptions specifies the partition options. type PartitionOptions struct { Tp model.PartitionType @@ -1296,3 +1428,38 @@ type PartitionOptions struct { Definitions []*PartitionDefinition Num uint64 } + +func (n *PartitionOptions) Restore(ctx *RestoreCtx) error { + switch n.Tp { + case model.PartitionTypeRange: + ctx.WriteKeyWord("RANGE") + case model.PartitionTypeHash: + ctx.WriteKeyWord("HASH") + case model.PartitionTypeList: + return errors.New("TiDB Parser ignore the `PartitionTypeList` type now") + default: + return errors.New("") + } + if err := n.Expr.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore PartitionOptions Expr") + } + for i, col := range n.ColumnNames { + if i > 0 { + ctx.WritePlain(",") + } + if err := col.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing PartitionOptions ColumnName: [%v]", i) + } + } + ctx.WritePlainf("%d", n.Num) + for i, def := range n.Definitions { + if i > 0 { + ctx.WritePlain(",") + } + if err := def.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing PartitionOptions Definitions: [%v]", i) + } + } + + return nil +} diff --git a/parser_test.go b/parser_test.go index 2f2e4c882..9789e3eac 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1456,7 +1456,7 @@ func (s *testParserSuite) TestDDL(c *C) { {"CREATE TABLE foo (", false, ""}, {"CREATE TABLE foo ()", false, ""}, {"CREATE TABLE foo ();", false, ""}, - {"CREATE TABLE foo (a TINYINT UNSIGNED);", true, ""}, + {"CREATE TABLE foo (a TINYINT UNSIGNED);", true, "CREATE TABLE `foo`(`a` TINYINT UNSIGNED)"}, {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, ""}, {"CREATE TABLE foo (a bigint unsigned, b bool);", true, ""}, {"CREATE TABLE foo (a TINYINT, b SMALLINT) CREATE TABLE bar (x INT, y int64)", false, ""}, From c5360cb4eb95febe60cf0af95a2e04d58d777d56 Mon Sep 17 00:00:00 2001 From: chendapao Date: Thu, 10 Jan 2019 15:32:29 +0800 Subject: [PATCH 02/15] Change test cases --- ast/ddl.go | 62 ++++++++++++++++++++++--------------- cdptest/main.go | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ parser_test.go | 36 +++++++++++----------- 3 files changed, 137 insertions(+), 42 deletions(-) create mode 100644 cdptest/main.go diff --git a/ast/ddl.go b/ast/ddl.go index dec9081e1..f8b8ad164 100755 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -683,6 +683,7 @@ func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { if err := n.Table.Restore(ctx); err != nil { return errors.Annotate(err, "An error occurred while splicing CreateTableStmt Table") } + ctx.WritePlain(" ") if n.ReferTable != nil { ctx.WriteKeyWord("LIKE ") if err := n.ReferTable.Restore(ctx); err != nil { @@ -690,40 +691,41 @@ func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { } } - ctx.WritePlain("(") - for i, col := range n.Cols { - if i > 0 { - ctx.WritePlain(" ") - } - if err := col.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt ColumnDef: [%v]", i) - } - } - for i, constraint := range n.Constraints { - if i > 0 { - ctx.WritePlain(",") + if len(n.Cols) > 0 { + ctx.WritePlain("(") + for i, col := range n.Cols { + if i > 0 { + ctx.WritePlain(",") + } + if err := col.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt ColumnDef: [%v]", i) + } } - if err := constraint.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt Constraints: [%v]", i) + for i, constraint := range n.Constraints { + if i > 0 { + ctx.WritePlain(",") + } + if err := constraint.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt Constraints: [%v]", i) + } } + ctx.WritePlain(")") } - ctx.WritePlain(")") for i, option := range n.Options { - if i > 0 { - ctx.WritePlain(" ") - } + ctx.WritePlain(" ") if err := option.Restore(ctx); err != nil { return errors.Annotatef(err, "An error occurred while splicing CreateTableStmt TableOption: [%v]", i) } } if n.Partition != nil { + ctx.WritePlain(" ") if err := n.Partition.Restore(ctx); err != nil { return errors.Annotate(err, "An error occurred while splicing CreateTableStmt Partition") } } - + ctx.WritePlain(";") //TODO: Waiting for Create Select //TODO: OnDuplicate //TODO: Select @@ -1109,10 +1111,10 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { ctx.WriteKeyWord("ENGINE = ") ctx.WriteString(n.StrValue) case TableOptionCharset: - ctx.WriteKeyWord("DEFAULT CHARACTER SET ") + ctx.WriteKeyWord("CHARACTER SET ") ctx.WriteString(n.StrValue) case TableOptionCollate: - ctx.WriteKeyWord("DEFAULT COLLATE") + ctx.WriteKeyWord("COLLATE") ctx.WriteString(n.StrValue) case TableOptionAutoIncrement: ctx.WriteKeyWord("AUTO_INCREMENT ") @@ -1430,19 +1432,24 @@ type PartitionOptions struct { } func (n *PartitionOptions) Restore(ctx *RestoreCtx) error { + ctx.WriteKeyWord("PARTITION BY ") switch n.Tp { case model.PartitionTypeRange: - ctx.WriteKeyWord("RANGE") + ctx.WriteKeyWord("RANGE ") case model.PartitionTypeHash: - ctx.WriteKeyWord("HASH") + ctx.WriteKeyWord("HASH ") case model.PartitionTypeList: return errors.New("TiDB Parser ignore the `PartitionTypeList` type now") default: - return errors.New("") + return errors.New(" ") } + + ctx.WritePlain("(") if err := n.Expr.Restore(ctx); err != nil { return errors.Annotate(err, "An error occurred while restore PartitionOptions Expr") } + ctx.WritePlain(") ") + for i, col := range n.ColumnNames { if i > 0 { ctx.WritePlain(",") @@ -1451,7 +1458,12 @@ func (n *PartitionOptions) Restore(ctx *RestoreCtx) error { return errors.Annotatef(err, "An error occurred while splicing PartitionOptions ColumnName: [%v]", i) } } - ctx.WritePlainf("%d", n.Num) + + if n.Num > 0 { + ctx.WriteKeyWord("PARTITIONS ") + ctx.WritePlainf("%d", n.Num) + } + for i, def := range n.Definitions { if i > 0 { ctx.WritePlain(",") diff --git a/cdptest/main.go b/cdptest/main.go new file mode 100644 index 000000000..bd8f265bf --- /dev/null +++ b/cdptest/main.go @@ -0,0 +1,81 @@ +package main + +import ( + "fmt" + "github.com/pingcap/parser" + . "github.com/pingcap/parser/ast" + . "github.com/pingcap/parser/format" + _ "github.com/pingcap/tidb/types/parser_driver" + "strings" +) + +type printVisitor struct { +} + +func (printVisitor) Enter(n Node) (node Node, skipChildren bool) { + fmt.Printf("%#v\n", n) + return n, false +} + +func (printVisitor) Leave(n Node) (node Node, ok bool) { + return n, true +} + +// For test only. +func CleanNodeText(node Node) { + var cleaner nodeTextCleaner + node.Accept(&cleaner) +} + +// nodeTextCleaner clean the text of a node and it's child node. +// For test only. +type nodeTextCleaner struct { +} + +// Enter implements Visitor interface. +func (checker *nodeTextCleaner) Enter(in Node) (out Node, skipChildren bool) { + in.SetText("") + return in, false +} + +// Leave implements Visitor interface. +func (checker *nodeTextCleaner) Leave(in Node) (out Node, ok bool) { + return in, true +} +func main() { + parser := parser.New() + stmt, _, err := parser.Parse("CREATE TABLE foo (name CHAR(50) BINARY);", "", "") + if err != nil { + fmt.Println(err.Error()) + } + + var sb strings.Builder + //err = stmt.Restore(NewRestoreCtx(DefaultRestoreFlags, &sb)) + //fmt.Println(sb.String()) + for _, node := range stmt { + switch stmt := node.(type) { + case *CreateTableStmt: + err = stmt.Restore(NewRestoreCtx(DefaultRestoreFlags, &sb)) + } + } + fmt.Println(sb.String()) + + fmt.Println("==========") + + //stmt1, err := parser.ParseOneStmt("CREATE TABLE foo (id varchar(50) collate utf8);", "", "") + //if err != nil { + // fmt.Println(err.Error()) + //} + //CleanNodeText(stmt) + //CleanNodeText(stmt1) + // + //stmt.Accept(printVisitor{}) + //fmt.Println() + //fmt.Println() + //fmt.Println() + //fmt.Println() + //stmt1.Accept(printVisitor{}) + // + //result := reflect.DeepEqual(stmt, stmt1) + //fmt.Println(result) +} diff --git a/parser_test.go b/parser_test.go index 9789e3eac..a1fcbd29d 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1456,20 +1456,22 @@ func (s *testParserSuite) TestDDL(c *C) { {"CREATE TABLE foo (", false, ""}, {"CREATE TABLE foo ()", false, ""}, {"CREATE TABLE foo ();", false, ""}, - {"CREATE TABLE foo (a TINYINT UNSIGNED);", true, "CREATE TABLE `foo`(`a` TINYINT UNSIGNED)"}, - {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, ""}, - {"CREATE TABLE foo (a bigint unsigned, b bool);", true, ""}, + {"CREATE TABLE foo (a varchar(50), b int);", true, "CREATE TABLE `foo` (`a` VARCHAR(50),`b` INT);"}, + {"CREATE TABLE foo (a TINYINT UNSIGNED);", true, "CREATE TABLE `foo` (`a` TINYINT UNSIGNED);"}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, + {"CREATE TABLE foo (a bigint unsigned, b bool);", true, "CREATE TABLE `foo` (`a` BIGINT UNSIGNED,`b` TINYINT(1));"}, {"CREATE TABLE foo (a TINYINT, b SMALLINT) CREATE TABLE bar (x INT, y int64)", false, ""}, {"CREATE TABLE foo (a int, b float); CREATE TABLE bar (x double, y float)", true, ""}, {"CREATE TABLE foo (a bytes)", false, ""}, - {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, ""}, - {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) -- foo", true, ""}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) -- foo", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, // {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) // foo", true,"}, - {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, ""}, - {"CREATE TABLE foo /* foo */ (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, ""}, - {"CREATE TABLE foo (name CHAR(50) BINARY)", true, ""}, - {"CREATE TABLE foo (name CHAR(50) COLLATE utf8_bin)", true, ""}, - {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8)", true, ""}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, + {"CREATE TABLE foo /* foo */ (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, + //{"CREATE TABLE foo (name CHAR(50) BINARY);", true, "CREATE TABLE `foo`(`name` CHAR(50) BINARY);"}, + {"CREATE TABLE foo (name CHAR(50) COLLATE utf8_bin)", true, "CREATE TABLE `foo` (`name` CHAR(50) COLLATE utf8_bin);"}, + {"CREATE TABLE foo (id varchar(50) collate utf8);", true, "CREATE TABLE `foo` (`id` VARCHAR(50) COLLATE utf8);"}, + {"CREATE TABLE foo (name CHAR(50) CHARACTER SET UTF8)", true, "CREATE TABLE `foo` (`name` CHAR(50) CHARACTER SET UTF8);"}, //utf8 != UTF8 {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY)", true, ""}, {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY CHARACTER set utf8)", false, ""}, {"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin)", true, ""}, @@ -1477,10 +1479,10 @@ func (s *testParserSuite) TestDDL(c *C) { {"CREATE TABLE foo (a, b.c);", false, ""}, {"CREATE TABLE (name CHAR(50) BINARY)", false, ""}, // for table option - {"create table t (c int) avg_row_length = 3", true, ""}, - {"create table t (c int) avg_row_length 3", true, ""}, - {"create table t (c int) checksum = 0", true, ""}, - {"create table t (c int) checksum 1", true, ""}, + {"create table t (c int) avg_row_length = 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH 3;"}, + {"create table t (c int) avg_row_length 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH 3;"}, + {"create table t (c int) checksum = 0", true, "CREATE TABLE `t` (`c` INT) CHECKSUM 0;"}, + {"create table t (c int) checksum 1", true, "CREATE TABLE `t` (`c` INT) CHECKSUM 1;"}, {"create table t (c int) compression = 'NONE'", true, ""}, {"create table t (c int) compression 'lz4'", true, ""}, {"create table t (c int) connection = 'abc'", true, ""}, @@ -1512,7 +1514,7 @@ func (s *testParserSuite) TestDDL(c *C) { {`create table t1 (c1 int) compression="zlib";`, true, ""}, // partition option - {"create table t (c int) PARTITION BY HASH (c) PARTITIONS 32;", true, ""}, + {"create table t (c int) PARTITION BY HASH (c) PARTITIONS 32;", true, "CREATE TABLE `t` (`c` INT) PARTITION BY HASH (`c`) PARTITIONS 32;"}, {"create table t (c int) PARTITION BY HASH (Year(VDate)) (PARTITION p1980 VALUES LESS THAN (1980) ENGINE = MyISAM, PARTITION p1990 VALUES LESS THAN (1990) ENGINE = MyISAM, PARTITION pothers VALUES LESS THAN MAXVALUE ENGINE = MyISAM)", false, ""}, {"create table t (c int) PARTITION BY RANGE (Year(VDate)) (PARTITION p1980 VALUES LESS THAN (1980) ENGINE = MyISAM, PARTITION p1990 VALUES LESS THAN (1990) ENGINE = MyISAM, PARTITION pothers VALUES LESS THAN MAXVALUE ENGINE = MyISAM)", true, ""}, {"create table t (c int, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '') PARTITION BY RANGE (UNIX_TIMESTAMP(create_time)) (PARTITION p201610 VALUES LESS THAN(1477929600), PARTITION p201611 VALUES LESS THAN(1480521600),PARTITION p201612 VALUES LESS THAN(1483200000),PARTITION p201701 VALUES LESS THAN(1485878400),PARTITION p201702 VALUES LESS THAN(1488297600),PARTITION p201703 VALUES LESS THAN(1490976000))", true, ""}, @@ -1534,7 +1536,7 @@ func (s *testParserSuite) TestDDL(c *C) { PARTITION part11 VALUES LESS THAN (12) COMMENT = '12月份' ENGINE = InnoDB) */ ;`, true, ""}, // for check clause - {"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true, ""}, + //{"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true, "CREATE TABLE `t`(`c1` TINYINT(1), `c2` TINYINT(1), CHECK (`c1` IN (0, 1)), CHECK (`c2` IN (0, 1)));"}, // check有问题 {"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true, ""}, {"create database xxx", true, "CREATE DATABASE `xxx`"}, @@ -1664,7 +1666,7 @@ func (s *testParserSuite) TestDDL(c *C) { // Create table with primary key name. {"create table if not exists `t` (`id` int not null auto_increment comment '消息ID', primary key `pk_id` (`id`) );", true, ""}, // Create table with like. - {"create table a like b", true, ""}, + {"create table a like b", true, "CREATE TABLE `a` LIKE `b`;"}, {"create table a (like b)", true, ""}, {"create table if not exists a like b", true, ""}, {"create table if not exists a (like b)", true, ""}, From b2dcdd3f003ee0447b774099f8e6251c24e8e170 Mon Sep 17 00:00:00 2001 From: chendapao Date: Thu, 10 Jan 2019 22:18:00 +0800 Subject: [PATCH 03/15] Add test cases2 --- ast/ddl.go | 32 ++++++++++++++++++++---------- parser_test.go | 54 +++++++++++++++++++++++++------------------------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/ast/ddl.go b/ast/ddl.go index f8b8ad164..504b9de99 100755 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -1127,16 +1127,16 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { ctx.WritePlainf("%d", n.UintValue) case TableOptionConnection: ctx.WriteKeyWord("CONNECTION ") - ctx.WritePlain(n.StrValue) + ctx.WritePlainf("'%s'", n.StrValue) case TableOptionCheckSum: ctx.WriteKeyWord("CHECKSUM ") ctx.WritePlainf("%d", n.UintValue) case TableOptionPassword: ctx.WriteKeyWord("PASSWORD ") - ctx.WritePlain(n.StrValue) + ctx.WritePlainf("'%s'", n.StrValue) case TableOptionCompression: ctx.WriteKeyWord("COMPRESSION ") - ctx.WritePlain(n.StrValue) + ctx.WritePlainf("'%s'", n.StrValue) case TableOptionKeyBlockSize: ctx.WriteKeyWord("KEY_BLOCK_SIZE ") ctx.WritePlainf("%d", n.UintValue) @@ -1151,16 +1151,30 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { ctx.WritePlainf("%d", n.UintValue) case TableOptionRowFormat: ctx.WriteKeyWord("ROW_FORMAT ") - ctx.WritePlainf("%d", n.UintValue) + switch n.UintValue { + case 1: + ctx.WriteKeyWord("DEFAULT") + case 2: + ctx.WriteKeyWord("DYNAMIC") + case 3: + ctx.WriteKeyWord("FIXED") + case 4: + ctx.WriteKeyWord("COMPRESSED") + case 5: + ctx.WriteKeyWord("REDUNDANT") + case 6: + ctx.WriteKeyWord("COMPACT") + } case TableOptionStatsPersistent: - ctx.WriteKeyWord("STATS_PERSISTENT") + return errors.New("TiDB Parser ignore the `TableOptionStatsPersistent` type now") case TableOptionShardRowID: ctx.WriteKeyWord("SHARD_ROW_ID_BITS ") ctx.WritePlainf("%d", n.UintValue) case TableOptionPackKeys: return errors.New("TiDB Parser ignore the `TableOptionPackKeys` type now") + default: + return errors.Errorf("invalid TableOptionType: %d", n.Tp) } - return nil } @@ -1415,9 +1429,7 @@ func (n *PartitionDefinition) Restore(ctx *RestoreCtx) error { return errors.Annotatef(err, "An error occurred while splicing PartitionDefinition LessThan: [%v]", i) } } - //if n.MaxValue { - // - //} + //TODO: TiDB Parser ignore the `MaxValue` type now ctx.WritePlain(n.Comment) return nil } @@ -1441,7 +1453,7 @@ func (n *PartitionOptions) Restore(ctx *RestoreCtx) error { case model.PartitionTypeList: return errors.New("TiDB Parser ignore the `PartitionTypeList` type now") default: - return errors.New(" ") + return errors.Errorf("invalid model.PartitionType: %d", n.Tp) } ctx.WritePlain("(") diff --git a/parser_test.go b/parser_test.go index a1fcbd29d..21e75447c 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1468,13 +1468,13 @@ func (s *testParserSuite) TestDDL(c *C) { // {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) // foo", true,"}, {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, {"CREATE TABLE foo /* foo */ (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, - //{"CREATE TABLE foo (name CHAR(50) BINARY);", true, "CREATE TABLE `foo`(`name` CHAR(50) BINARY);"}, + //{"CREATE TABLE foo (name CHAR(50) BINARY);", true, "CREATE TABLE `foo`(`name` CHAR(50) BINARY);"}, //不支持 binary 逻辑 {"CREATE TABLE foo (name CHAR(50) COLLATE utf8_bin)", true, "CREATE TABLE `foo` (`name` CHAR(50) COLLATE utf8_bin);"}, {"CREATE TABLE foo (id varchar(50) collate utf8);", true, "CREATE TABLE `foo` (`id` VARCHAR(50) COLLATE utf8);"}, {"CREATE TABLE foo (name CHAR(50) CHARACTER SET UTF8)", true, "CREATE TABLE `foo` (`name` CHAR(50) CHARACTER SET UTF8);"}, //utf8 != UTF8 {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY)", true, ""}, {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY CHARACTER set utf8)", false, ""}, - {"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin)", true, ""}, + //{"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET UTF8 COLLATE UTF8_BIN)", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY CHARACTER SET UTF8 COLLATE UTF8_BIN);"}, {"CREATE TABLE foo (a.b, b);", false, ""}, {"CREATE TABLE foo (a, b.c);", false, ""}, {"CREATE TABLE (name CHAR(50) BINARY)", false, ""}, @@ -1483,35 +1483,35 @@ func (s *testParserSuite) TestDDL(c *C) { {"create table t (c int) avg_row_length 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH 3;"}, {"create table t (c int) checksum = 0", true, "CREATE TABLE `t` (`c` INT) CHECKSUM 0;"}, {"create table t (c int) checksum 1", true, "CREATE TABLE `t` (`c` INT) CHECKSUM 1;"}, - {"create table t (c int) compression = 'NONE'", true, ""}, - {"create table t (c int) compression 'lz4'", true, ""}, - {"create table t (c int) connection = 'abc'", true, ""}, - {"create table t (c int) connection 'abc'", true, ""}, - {"create table t (c int) key_block_size = 1024", true, ""}, - {"create table t (c int) key_block_size 1024", true, ""}, - {"create table t (c int) max_rows = 1000", true, ""}, - {"create table t (c int) max_rows 1000", true, ""}, - {"create table t (c int) min_rows = 1000", true, ""}, - {"create table t (c int) min_rows 1000", true, ""}, - {"create table t (c int) password = 'abc'", true, ""}, - {"create table t (c int) password 'abc'", true, ""}, - {"create table t (c int) DELAY_KEY_WRITE=1", true, ""}, - {"create table t (c int) DELAY_KEY_WRITE 1", true, ""}, - {"create table t (c int) ROW_FORMAT = default", true, ""}, - {"create table t (c int) ROW_FORMAT default", true, ""}, - {"create table t (c int) ROW_FORMAT = fixed", true, ""}, - {"create table t (c int) ROW_FORMAT = compressed", true, ""}, - {"create table t (c int) ROW_FORMAT = compact", true, ""}, - {"create table t (c int) ROW_FORMAT = redundant", true, ""}, - {"create table t (c int) ROW_FORMAT = dynamic", true, ""}, + {"create table t (c int) compression = 'NONE'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION 'NONE';"}, + {"create table t (c int) compression 'lz4'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION 'lz4';"}, + {"create table t (c int) connection = 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION 'abc';"}, + {"create table t (c int) connection 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION 'abc';"}, + {"create table t (c int) key_block_size = 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE 1024;"}, + {"create table t (c int) key_block_size 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE 1024;"}, + {"create table t (c int) max_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS 1000;"}, + {"create table t (c int) max_rows 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS 1000;"}, + {"create table t (c int) min_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS 1000;"}, + {"create table t (c int) min_rows 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS 1000;"}, + {"create table t (c int) password = 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD 'abc';"}, + {"create table t (c int) password 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD 'abc';"}, + {"create table t (c int) DELAY_KEY_WRITE=1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE 1;"}, + {"create table t (c int) DELAY_KEY_WRITE 1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE 1;"}, + {"create table t (c int) ROW_FORMAT = default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT DEFAULT;"}, + {"create table t (c int) ROW_FORMAT default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT DEFAULT;"}, + {"create table t (c int) ROW_FORMAT = fixed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT FIXED;"}, + {"create table t (c int) ROW_FORMAT = compressed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT COMPRESSED;"}, + {"create table t (c int) ROW_FORMAT = compact", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT COMPACT;"}, + {"create table t (c int) ROW_FORMAT = redundant", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT REDUNDANT;"}, + {"create table t (c int) ROW_FORMAT = dynamic", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT DYNAMIC;"}, {"create table t (c int) STATS_PERSISTENT = default", true, ""}, {"create table t (c int) STATS_PERSISTENT = 0", true, ""}, {"create table t (c int) STATS_PERSISTENT = 1", true, ""}, {"create table t (c int) PACK_KEYS = 1", true, ""}, {"create table t (c int) PACK_KEYS = 0", true, ""}, {"create table t (c int) PACK_KEYS = DEFAULT", true, ""}, - {`create table testTableCompression (c VARCHAR(15000)) compression="ZLIB";`, true, ""}, - {`create table t1 (c1 int) compression="zlib";`, true, ""}, + {`create table testTableCompression (c VARCHAR(15000)) compression="ZLIB";`, true, "CREATE TABLE `testTableCompression` (`c` VARCHAR(15000)) COMPRESSION 'ZLIB';"}, + {`create table t1 (c1 int) compression="zlib";`, true, "CREATE TABLE `t1` (`c1` INT) COMPRESSION 'zlib';"}, // partition option {"create table t (c int) PARTITION BY HASH (c) PARTITIONS 32;", true, "CREATE TABLE `t` (`c` INT) PARTITION BY HASH (`c`) PARTITIONS 32;"}, @@ -1536,8 +1536,8 @@ func (s *testParserSuite) TestDDL(c *C) { PARTITION part11 VALUES LESS THAN (12) COMMENT = '12月份' ENGINE = InnoDB) */ ;`, true, ""}, // for check clause - //{"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true, "CREATE TABLE `t`(`c1` TINYINT(1), `c2` TINYINT(1), CHECK (`c1` IN (0, 1)), CHECK (`c2` IN (0, 1)));"}, // check有问题 - {"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true, ""}, + {"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true, ""}, // check有问题 + {"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true, ""}, // check有问题 {"create database xxx", true, "CREATE DATABASE `xxx`"}, {"create database if exists xxx", false, ""}, From c8bb740a874cc5de8bc95419d64fe130ab362199 Mon Sep 17 00:00:00 2001 From: chendapao Date: Thu, 10 Jan 2019 22:19:57 +0800 Subject: [PATCH 04/15] Add test cases3 --- cdptest/main.go | 81 ------------------------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 cdptest/main.go diff --git a/cdptest/main.go b/cdptest/main.go deleted file mode 100644 index bd8f265bf..000000000 --- a/cdptest/main.go +++ /dev/null @@ -1,81 +0,0 @@ -package main - -import ( - "fmt" - "github.com/pingcap/parser" - . "github.com/pingcap/parser/ast" - . "github.com/pingcap/parser/format" - _ "github.com/pingcap/tidb/types/parser_driver" - "strings" -) - -type printVisitor struct { -} - -func (printVisitor) Enter(n Node) (node Node, skipChildren bool) { - fmt.Printf("%#v\n", n) - return n, false -} - -func (printVisitor) Leave(n Node) (node Node, ok bool) { - return n, true -} - -// For test only. -func CleanNodeText(node Node) { - var cleaner nodeTextCleaner - node.Accept(&cleaner) -} - -// nodeTextCleaner clean the text of a node and it's child node. -// For test only. -type nodeTextCleaner struct { -} - -// Enter implements Visitor interface. -func (checker *nodeTextCleaner) Enter(in Node) (out Node, skipChildren bool) { - in.SetText("") - return in, false -} - -// Leave implements Visitor interface. -func (checker *nodeTextCleaner) Leave(in Node) (out Node, ok bool) { - return in, true -} -func main() { - parser := parser.New() - stmt, _, err := parser.Parse("CREATE TABLE foo (name CHAR(50) BINARY);", "", "") - if err != nil { - fmt.Println(err.Error()) - } - - var sb strings.Builder - //err = stmt.Restore(NewRestoreCtx(DefaultRestoreFlags, &sb)) - //fmt.Println(sb.String()) - for _, node := range stmt { - switch stmt := node.(type) { - case *CreateTableStmt: - err = stmt.Restore(NewRestoreCtx(DefaultRestoreFlags, &sb)) - } - } - fmt.Println(sb.String()) - - fmt.Println("==========") - - //stmt1, err := parser.ParseOneStmt("CREATE TABLE foo (id varchar(50) collate utf8);", "", "") - //if err != nil { - // fmt.Println(err.Error()) - //} - //CleanNodeText(stmt) - //CleanNodeText(stmt1) - // - //stmt.Accept(printVisitor{}) - //fmt.Println() - //fmt.Println() - //fmt.Println() - //fmt.Println() - //stmt1.Accept(printVisitor{}) - // - //result := reflect.DeepEqual(stmt, stmt1) - //fmt.Println(result) -} From 4579278036de8f17c024245280bfb0ddf3bd838d Mon Sep 17 00:00:00 2001 From: chendapao Date: Fri, 11 Jan 2019 11:20:25 +0800 Subject: [PATCH 05/15] Add TableOption goyacc code --- ast/ddl.go | 14 ++++++++++++-- parser.go | 16 +++++++++++++--- parser.y | 16 +++++++++++++--- parser_test.go | 12 ++++++------ 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/ast/ddl.go b/ast/ddl.go index 504b9de99..7f39514da 100755 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -1166,12 +1166,22 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { ctx.WriteKeyWord("COMPACT") } case TableOptionStatsPersistent: - return errors.New("TiDB Parser ignore the `TableOptionStatsPersistent` type now") + ctx.WriteKeyWord("STATS_PERSISTENT ") + if n.StrValue != "" { + ctx.WritePlain(n.StrValue) + } else { + ctx.WritePlainf("%d", n.UintValue) + } case TableOptionShardRowID: ctx.WriteKeyWord("SHARD_ROW_ID_BITS ") ctx.WritePlainf("%d", n.UintValue) case TableOptionPackKeys: - return errors.New("TiDB Parser ignore the `TableOptionPackKeys` type now") + ctx.WriteKeyWord("PACK_KEYS ") + if n.StrValue != "" { + ctx.WritePlain(n.StrValue) + } else { + ctx.WritePlainf("%d", n.UintValue) + } default: return errors.Errorf("invalid TableOptionType: %d", n.Tp) } diff --git a/parser.go b/parser.go index f098d9c71..f838097cd 100644 --- a/parser.go +++ b/parser.go @@ -11611,7 +11611,13 @@ yynewstate: } case 1225: { - parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionStatsPersistent} + switch yyS[yypt-0].item.(type) { + case uint64: + parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionStatsPersistent, UintValue: yyS[yypt-0].item.(uint64)} + default: + parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionStatsPersistent, StrValue: "DEFAULT"} + } + } case 1226: { @@ -11619,8 +11625,12 @@ yynewstate: } case 1227: { - // Parse it but will ignore it. - parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionPackKeys} + switch yyS[yypt-0].item.(type) { + case uint64: + parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionPackKeys, UintValue: yyS[yypt-0].item.(uint64)} + default: + parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionPackKeys, StrValue: "DEFAULT"} + } } case 1230: { diff --git a/parser.y b/parser.y index c72b43495..81fe5da71 100644 --- a/parser.y +++ b/parser.y @@ -6490,7 +6490,13 @@ TableOption: } | "STATS_PERSISTENT" EqOpt StatsPersistentVal { - $$ = &ast.TableOption{Tp: ast.TableOptionStatsPersistent} + switch $3.(type) { + case uint64: + $$ = &ast.TableOption{Tp: ast.TableOptionStatsPersistent, UintValue: $3.(uint64)} + default: + $$ = &ast.TableOption{Tp: ast.TableOptionStatsPersistent, StrValue: "DEFAULT"} + } + } | "SHARD_ROW_ID_BITS" EqOpt LengthNum { @@ -6498,8 +6504,12 @@ TableOption: } | "PACK_KEYS" EqOpt StatsPersistentVal { - // Parse it but will ignore it. - $$ = &ast.TableOption{Tp: ast.TableOptionPackKeys} + switch $3.(type) { + case uint64: + $$ = &ast.TableOption{Tp: ast.TableOptionPackKeys, UintValue: $3.(uint64)} + default: + $$ = &ast.TableOption{Tp: ast.TableOptionPackKeys, StrValue: "DEFAULT"} + } } StatsPersistentVal: diff --git a/parser_test.go b/parser_test.go index 21e75447c..9fdc9376f 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1504,12 +1504,12 @@ func (s *testParserSuite) TestDDL(c *C) { {"create table t (c int) ROW_FORMAT = compact", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT COMPACT;"}, {"create table t (c int) ROW_FORMAT = redundant", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT REDUNDANT;"}, {"create table t (c int) ROW_FORMAT = dynamic", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT DYNAMIC;"}, - {"create table t (c int) STATS_PERSISTENT = default", true, ""}, - {"create table t (c int) STATS_PERSISTENT = 0", true, ""}, - {"create table t (c int) STATS_PERSISTENT = 1", true, ""}, - {"create table t (c int) PACK_KEYS = 1", true, ""}, - {"create table t (c int) PACK_KEYS = 0", true, ""}, - {"create table t (c int) PACK_KEYS = DEFAULT", true, ""}, + {"create table t (c int) STATS_PERSISTENT = default", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT DEFAULT;"}, + {"create table t (c int) STATS_PERSISTENT = 0", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT 0;"}, + {"create table t (c int) STATS_PERSISTENT = 1", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT 1;"}, + {"create table t (c int) PACK_KEYS = 1", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS 1;"}, + {"create table t (c int) PACK_KEYS = 0", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS 0;"}, + {"create table t (c int) PACK_KEYS = DEFAULT", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS DEFAULT;"}, {`create table testTableCompression (c VARCHAR(15000)) compression="ZLIB";`, true, "CREATE TABLE `testTableCompression` (`c` VARCHAR(15000)) COMPRESSION 'ZLIB';"}, {`create table t1 (c1 int) compression="zlib";`, true, "CREATE TABLE `t1` (`c1` INT) COMPRESSION 'zlib';"}, From e6055a863ac540ed44970e39ff393fa63cbf68f8 Mon Sep 17 00:00:00 2001 From: chendapao Date: Sat, 12 Jan 2019 18:31:16 +0800 Subject: [PATCH 06/15] change code logic1 --- ast/ddl.go | 77 ++++++++++++++++++++++++++++++++------------- parser_test.go | 85 +++++++++++++++++++++++++------------------------- 2 files changed, 99 insertions(+), 63 deletions(-) diff --git a/ast/ddl.go b/ast/ddl.go index 7f39514da..44332ba13 100755 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -533,13 +533,15 @@ func (n *Constraint) Restore(ctx *RestoreCtx) error { ctx.WriteKeyWord("UNIQUE KEY") case ConstraintUniqIndex: ctx.WriteKeyWord("UNIQUE INDEX") - case ConstraintForeignKey: - ctx.WriteKeyWord("FOREIGN KEY") case ConstraintFulltext: ctx.WriteKeyWord("FULLTEXT") } - if n.Name != "" { + if n.Tp == ConstraintForeignKey { + ctx.WriteKeyWord("CONSTRAINT ") + ctx.WriteName(n.Name) + ctx.WriteKeyWord(" FOREIGN KEY ") + } else if n.Name != "" { ctx.WritePlain(" ") ctx.WriteName(n.Name) } @@ -624,9 +626,10 @@ func (n *ColumnDef) Restore(ctx *RestoreCtx) error { } } for i, options := range n.Options { - if i > 0 { - ctx.WritePlain(",") - } + //先去掉 > 0 加逗号的逻辑 + //if i > 0 { + // ctx.WritePlain(",") + //} ctx.WritePlain(" ") if err := options.Restore(ctx); err != nil { return errors.Annotatef(err, "An error occurred while splicing ColumnDef ColumnOption: [%v]", i) @@ -691,7 +694,7 @@ func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { } } - if len(n.Cols) > 0 { + if col := len(n.Cols); col > 0 { ctx.WritePlain("(") for i, col := range n.Cols { if i > 0 { @@ -702,7 +705,7 @@ func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { } } for i, constraint := range n.Constraints { - if i > 0 { + if i > 0 || col >= 1 { ctx.WritePlain(",") } if err := constraint.Restore(ctx); err != nil { @@ -1108,49 +1111,64 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { case TableOptionNone: return nil case TableOptionEngine: - ctx.WriteKeyWord("ENGINE = ") - ctx.WriteString(n.StrValue) + ctx.WriteKeyWord("ENGINE ") + ctx.WritePlain("= ") + ctx.WritePlain(n.StrValue) case TableOptionCharset: ctx.WriteKeyWord("CHARACTER SET ") + ctx.WritePlain("= ") ctx.WriteString(n.StrValue) case TableOptionCollate: ctx.WriteKeyWord("COLLATE") + ctx.WritePlain("= ") ctx.WriteString(n.StrValue) case TableOptionAutoIncrement: ctx.WriteKeyWord("AUTO_INCREMENT ") + ctx.WritePlain("= ") ctx.WritePlainf("%d", n.UintValue) case TableOptionComment: ctx.WriteKeyWord("COMMENT ") - ctx.WritePlain(n.StrValue) + ctx.WritePlain("= ") + ctx.WriteString(n.StrValue) case TableOptionAvgRowLength: ctx.WriteKeyWord("AVG_ROW_LENGTH ") + ctx.WritePlain("= ") ctx.WritePlainf("%d", n.UintValue) case TableOptionConnection: ctx.WriteKeyWord("CONNECTION ") + ctx.WritePlain("= ") ctx.WritePlainf("'%s'", n.StrValue) case TableOptionCheckSum: ctx.WriteKeyWord("CHECKSUM ") + ctx.WritePlain("= ") ctx.WritePlainf("%d", n.UintValue) case TableOptionPassword: ctx.WriteKeyWord("PASSWORD ") + ctx.WritePlain("= ") ctx.WritePlainf("'%s'", n.StrValue) case TableOptionCompression: ctx.WriteKeyWord("COMPRESSION ") + ctx.WritePlain("= ") ctx.WritePlainf("'%s'", n.StrValue) case TableOptionKeyBlockSize: ctx.WriteKeyWord("KEY_BLOCK_SIZE ") + ctx.WritePlain("= ") ctx.WritePlainf("%d", n.UintValue) case TableOptionMaxRows: ctx.WriteKeyWord("MAX_ROWS ") + ctx.WritePlain("= ") ctx.WritePlainf("%d", n.UintValue) case TableOptionMinRows: ctx.WriteKeyWord("MIN_ROWS ") + ctx.WritePlain("= ") ctx.WritePlainf("%d", n.UintValue) case TableOptionDelayKeyWrite: ctx.WriteKeyWord("DELAY_KEY_WRITE ") + ctx.WritePlain("= ") ctx.WritePlainf("%d", n.UintValue) case TableOptionRowFormat: ctx.WriteKeyWord("ROW_FORMAT ") + ctx.WritePlain("= ") switch n.UintValue { case 1: ctx.WriteKeyWord("DEFAULT") @@ -1167,6 +1185,7 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { } case TableOptionStatsPersistent: ctx.WriteKeyWord("STATS_PERSISTENT ") + ctx.WritePlain("= ") if n.StrValue != "" { ctx.WritePlain(n.StrValue) } else { @@ -1174,9 +1193,11 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { } case TableOptionShardRowID: ctx.WriteKeyWord("SHARD_ROW_ID_BITS ") + ctx.WritePlain("= ") ctx.WritePlainf("%d", n.UintValue) case TableOptionPackKeys: ctx.WriteKeyWord("PACK_KEYS ") + ctx.WritePlain("= ") if n.StrValue != "" { ctx.WritePlain(n.StrValue) } else { @@ -1430,16 +1451,26 @@ type PartitionDefinition struct { func (n *PartitionDefinition) Restore(ctx *RestoreCtx) error { ctx.WriteKeyWord("PARTITION ") - ctx.WriteName(n.Name.String()) + ctx.WritePlain(n.Name.String()) + ctx.WritePlain(" ") for i, lessThan := range n.LessThan { if i > 0 { ctx.WritePlain(" ") } - if err := lessThan.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while splicing PartitionDefinition LessThan: [%v]", i) + ctx.WriteKeyWord("VALUES LESS THAN ") + switch lessThan.(type) { + case ValueExpr: + ctx.WritePlain("(") + if err := lessThan.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing PartitionDefinition LessThan: [%v]", i) + } + ctx.WritePlain(")") + default: + if err := lessThan.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing PartitionDefinition LessThan: [%v]", i) + } } } - //TODO: TiDB Parser ignore the `MaxValue` type now ctx.WritePlain(n.Comment) return nil } @@ -1486,13 +1517,17 @@ func (n *PartitionOptions) Restore(ctx *RestoreCtx) error { ctx.WritePlainf("%d", n.Num) } - for i, def := range n.Definitions { - if i > 0 { - ctx.WritePlain(",") - } - if err := def.Restore(ctx); err != nil { - return errors.Annotatef(err, "An error occurred while splicing PartitionOptions Definitions: [%v]", i) + if len(n.Definitions) > 0 { + ctx.WritePlain("(") + for i, def := range n.Definitions { + if i > 0 { + ctx.WritePlain(",") + } + if err := def.Restore(ctx); err != nil { + return errors.Annotatef(err, "An error occurred while splicing PartitionOptions Definitions: [%v]", i) + } } + ctx.WritePlain(")") } return nil diff --git a/parser_test.go b/parser_test.go index 9b9df919c..a51152f09 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1469,55 +1469,56 @@ func (s *testParserSuite) TestDDL(c *C) { {"CREATE TABLE foo (a bytes)", false, ""}, {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) -- foo", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, - // {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) // foo", true,"}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) // foo", false, ""}, //mysql5.7 不支持 //注释 {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, {"CREATE TABLE foo /* foo */ (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, - //{"CREATE TABLE foo (name CHAR(50) BINARY);", true, "CREATE TABLE `foo`(`name` CHAR(50) BINARY);"}, //不支持 binary 逻辑 + //{"CREATE TABLE foo (name CHAR(50) BINARY);", true, "CREATE TABLE `foo`(`name` CHAR(50));"}, //是否需要支持反解出binary {"CREATE TABLE foo (name CHAR(50) COLLATE utf8_bin)", true, "CREATE TABLE `foo` (`name` CHAR(50) COLLATE utf8_bin);"}, {"CREATE TABLE foo (id varchar(50) collate utf8);", true, "CREATE TABLE `foo` (`id` VARCHAR(50) COLLATE utf8);"}, {"CREATE TABLE foo (name CHAR(50) CHARACTER SET UTF8)", true, "CREATE TABLE `foo` (`name` CHAR(50) CHARACTER SET UTF8);"}, //utf8 != UTF8 - {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY)", true, ""}, + //{"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY)", true, "CREATE TABLE `foo` (`name` CHAR(50) CHARACTER SET utf8 BINARY);"}, //是否需要支持反解出binary {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY CHARACTER set utf8)", false, ""}, - //{"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET UTF8 COLLATE UTF8_BIN)", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY CHARACTER SET UTF8 COLLATE UTF8_BIN);"}, + //{"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET UTF8 COLLATE UTF8_BIN)", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY CHARACTER SET UTF8 COLLATE UTF8_BIN);"},//是否需要支持反解出binary {"CREATE TABLE foo (a.b, b);", false, ""}, {"CREATE TABLE foo (a, b.c);", false, ""}, {"CREATE TABLE (name CHAR(50) BINARY)", false, ""}, // for table option - {"create table t (c int) avg_row_length = 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH 3;"}, - {"create table t (c int) avg_row_length 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH 3;"}, - {"create table t (c int) checksum = 0", true, "CREATE TABLE `t` (`c` INT) CHECKSUM 0;"}, - {"create table t (c int) checksum 1", true, "CREATE TABLE `t` (`c` INT) CHECKSUM 1;"}, - {"create table t (c int) compression = 'NONE'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION 'NONE';"}, - {"create table t (c int) compression 'lz4'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION 'lz4';"}, - {"create table t (c int) connection = 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION 'abc';"}, - {"create table t (c int) connection 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION 'abc';"}, - {"create table t (c int) key_block_size = 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE 1024;"}, - {"create table t (c int) key_block_size 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE 1024;"}, - {"create table t (c int) max_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS 1000;"}, - {"create table t (c int) max_rows 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS 1000;"}, - {"create table t (c int) min_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS 1000;"}, - {"create table t (c int) min_rows 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS 1000;"}, - {"create table t (c int) password = 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD 'abc';"}, - {"create table t (c int) password 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD 'abc';"}, - {"create table t (c int) DELAY_KEY_WRITE=1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE 1;"}, - {"create table t (c int) DELAY_KEY_WRITE 1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE 1;"}, - {"create table t (c int) ROW_FORMAT = default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT DEFAULT;"}, - {"create table t (c int) ROW_FORMAT default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT DEFAULT;"}, - {"create table t (c int) ROW_FORMAT = fixed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT FIXED;"}, - {"create table t (c int) ROW_FORMAT = compressed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT COMPRESSED;"}, - {"create table t (c int) ROW_FORMAT = compact", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT COMPACT;"}, - {"create table t (c int) ROW_FORMAT = redundant", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT REDUNDANT;"}, - {"create table t (c int) ROW_FORMAT = dynamic", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT DYNAMIC;"}, - {"create table t (c int) STATS_PERSISTENT = default", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT DEFAULT;"}, - {"create table t (c int) STATS_PERSISTENT = 0", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT 0;"}, - {"create table t (c int) STATS_PERSISTENT = 1", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT 1;"}, - {"create table t (c int) PACK_KEYS = 1", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS 1;"}, - {"create table t (c int) PACK_KEYS = 0", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS 0;"}, - {"create table t (c int) PACK_KEYS = DEFAULT", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS DEFAULT;"}, - {`create table testTableCompression (c VARCHAR(15000)) compression="ZLIB";`, true, "CREATE TABLE `testTableCompression` (`c` VARCHAR(15000)) COMPRESSION 'ZLIB';"}, - {`create table t1 (c1 int) compression="zlib";`, true, "CREATE TABLE `t1` (`c1` INT) COMPRESSION 'zlib';"}, + {"create table t (c int) avg_row_length = 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH = 3;"}, + {"create table t (c int) avg_row_length 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH = 3;"}, + {"create table t (c int) checksum = 0", true, "CREATE TABLE `t` (`c` INT) CHECKSUM = 0;"}, + {"create table t (c int) checksum 1", true, "CREATE TABLE `t` (`c` INT) CHECKSUM = 1;"}, + {"create table t (c int) compression = 'NONE'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION = 'NONE';"}, + {"create table t (c int) compression 'lz4'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION = 'lz4';"}, + {"create table t (c int) connection = 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION = 'abc';"}, + {"create table t (c int) connection 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION = 'abc';"}, + {"create table t (c int) key_block_size = 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE = 1024;"}, + {"create table t (c int) key_block_size 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE = 1024;"}, + {"create table t (c int) max_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS = 1000;"}, + {"create table t (c int) max_rows 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS = 1000;"}, + {"create table t (c int) min_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS = 1000;"}, + {"create table t (c int) min_rows 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS = 1000;"}, + {"create table t (c int) password = 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD = 'abc';"}, + {"create table t (c int) password 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD = 'abc';"}, + {"create table t (c int) DELAY_KEY_WRITE=1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE = 1;"}, + {"create table t (c int) DELAY_KEY_WRITE 1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE = 1;"}, + {"create table t (c int) ROW_FORMAT = default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DEFAULT;"}, + {"create table t (c int) ROW_FORMAT default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DEFAULT;"}, + {"create table t (c int) ROW_FORMAT = fixed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = FIXED;"}, + {"create table t (c int) ROW_FORMAT = compressed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = COMPRESSED;"}, + {"create table t (c int) ROW_FORMAT = compact", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = COMPACT;"}, + {"create table t (c int) ROW_FORMAT = redundant", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = REDUNDANT;"}, + {"create table t (c int) ROW_FORMAT = dynamic", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DYNAMIC;"}, + {"create table t (c int) STATS_PERSISTENT = default", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT = DEFAULT;"}, + {"create table t (c int) STATS_PERSISTENT = 0", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT = 0;"}, + {"create table t (c int) STATS_PERSISTENT = 1", true, "CREATE TABLE `t` (`c` INT) STATS_PERSISTENT = 1;"}, + {"create table t (c int) PACK_KEYS = 1", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS = 1;"}, + {"create table t (c int) PACK_KEYS = 0", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS = 0;"}, + {"create table t (c int) PACK_KEYS = DEFAULT", true, "CREATE TABLE `t` (`c` INT) PACK_KEYS = DEFAULT;"}, + {`create table testTableCompression (c VARCHAR(15000)) compression="ZLIB";`, true, "CREATE TABLE `testTableCompression` (`c` VARCHAR(15000)) COMPRESSION = 'ZLIB';"}, + {`create table t1 (c1 int) compression="zlib";`, true, "CREATE TABLE `t1` (`c1` INT) COMPRESSION = 'zlib';"}, // partition option + {"CREATE TABLE t (id int) ENGINE = INNDB PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20));", true, "CREATE TABLE `t` (`id` INT) ENGINE = INNDB PARTITION BY RANGE (`id`) (PARTITION p0 VALUES LESS THAN (10),PARTITION p1 VALUES LESS THAN (20));"}, {"create table t (c int) PARTITION BY HASH (c) PARTITIONS 32;", true, "CREATE TABLE `t` (`c` INT) PARTITION BY HASH (`c`) PARTITIONS 32;"}, {"create table t (c int) PARTITION BY HASH (Year(VDate)) (PARTITION p1980 VALUES LESS THAN (1980) ENGINE = MyISAM, PARTITION p1990 VALUES LESS THAN (1990) ENGINE = MyISAM, PARTITION pothers VALUES LESS THAN MAXVALUE ENGINE = MyISAM)", false, ""}, {"create table t (c int) PARTITION BY RANGE (Year(VDate)) (PARTITION p1980 VALUES LESS THAN (1980) ENGINE = MyISAM, PARTITION p1990 VALUES LESS THAN (1990) ENGINE = MyISAM, PARTITION pothers VALUES LESS THAN MAXVALUE ENGINE = MyISAM)", true, ""}, @@ -1540,8 +1541,8 @@ func (s *testParserSuite) TestDDL(c *C) { PARTITION part11 VALUES LESS THAN (12) COMMENT = '12月份' ENGINE = InnoDB) */ ;`, true, ""}, // for check clause - {"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true, ""}, // check有问题 - {"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true, ""}, // check有问题 + {"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true, ""}, //是否需要支持反解出binary + {"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true, ""}, //是否需要支持反解出binary {"create database xxx", true, "CREATE DATABASE `xxx`"}, {"create database if exists xxx", false, ""}, @@ -1671,9 +1672,9 @@ func (s *testParserSuite) TestDDL(c *C) { {"create table if not exists `t` (`id` int not null auto_increment comment '消息ID', primary key `pk_id` (`id`) );", true, ""}, // Create table with like. {"create table a like b", true, "CREATE TABLE `a` LIKE `b`;"}, - {"create table a (like b)", true, ""}, - {"create table if not exists a like b", true, ""}, - {"create table if not exists a (like b)", true, ""}, + {"create table a (like b)", true, "CREATE TABLE `a` LIKE `b`;"}, + {"create table if not exists a like b", true, "CREATE TABLE IF NOT EXISTS `a` LIKE `b`;"}, + {"create table if not exists a (like b)", true, "CREATE TABLE IF NOT EXISTS `a` LIKE `b`;"}, {"create table if not exists a like (b)", false, ""}, {"create table a (t int) like b", false, ""}, {"create table a (t int) like (b)", false, ""}, From af3b08e1f5273742479af0a1eaa9d3a9d802b268 Mon Sep 17 00:00:00 2001 From: chendapao Date: Sat, 12 Jan 2019 18:42:31 +0800 Subject: [PATCH 07/15] fk test --- ast/ddl_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ast/ddl_test.go b/ast/ddl_test.go index 4ad870c44..cca12e342 100644 --- a/ast/ddl_test.go +++ b/ast/ddl_test.go @@ -155,8 +155,8 @@ func (ts *testDDLSuite) TestDDLConstraintRestore(c *C) { {"fulltext INDEX full_id (parent_id)", "FULLTEXT `full_id`(`parent_id`)"}, {"PRIMARY KEY (id)", "PRIMARY KEY(`id`)"}, {"PRIMARY KEY (id) key_block_size = 32 using hash comment 'hello'", "PRIMARY KEY(`id`) KEY_BLOCK_SIZE=32 USING HASH COMMENT 'hello'"}, - {"FOREIGN KEY (parent_id(2),hello(4)) REFERENCES parent(id) ON DELETE CASCADE", "FOREIGN KEY(`parent_id`(2), `hello`(4)) REFERENCES `parent`(`id`) ON DELETE CASCADE"}, - {"FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "FOREIGN KEY(`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, + {"CONSTRAINT fk_123 FOREIGN KEY (parent_id(2),hello(4)) REFERENCES parent(id) ON DELETE CASCADE", "CONSTRAINT `fk_123` FOREIGN KEY (`parent_id`(2), `hello`(4)) REFERENCES `parent`(`id`) ON DELETE CASCADE"}, + {"CONSTRAINT fk_123 FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "CONSTRAINT `fk_123` FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, } extractNodeFunc := func(node Node) Node { return node.(*CreateTableStmt).Constraints[0] From c5ead8e0fd1a5b52523b32e79e2ab802f86d12c0 Mon Sep 17 00:00:00 2001 From: chendapao Date: Sun, 13 Jan 2019 00:01:06 +0800 Subject: [PATCH 08/15] Add test case and comment logic --- ast/ddl.go | 9 ++++++--- parser_test.go | 43 ++++++++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/ast/ddl.go b/ast/ddl.go index 44332ba13..be98205f2 100755 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -472,6 +472,9 @@ func (n *IndexOption) Restore(ctx *RestoreCtx) error { } ctx.WriteKeyWord("COMMENT ") ctx.WriteString(n.Comment) + } else if n.Comment == "" && n.Tp == model.IndexTypeInvalid && n.KeyBlockSize == 0 { + ctx.WriteKeyWord("COMMENT ") + ctx.WritePlain("''") } return nil } @@ -1117,11 +1120,11 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { case TableOptionCharset: ctx.WriteKeyWord("CHARACTER SET ") ctx.WritePlain("= ") - ctx.WriteString(n.StrValue) + ctx.WritePlain(n.StrValue) case TableOptionCollate: - ctx.WriteKeyWord("COLLATE") + ctx.WriteKeyWord("COLLATE ") ctx.WritePlain("= ") - ctx.WriteString(n.StrValue) + ctx.WritePlain(n.StrValue) case TableOptionAutoIncrement: ctx.WriteKeyWord("AUTO_INCREMENT ") ctx.WritePlain("= ") diff --git a/parser_test.go b/parser_test.go index a51152f09..14df06ac1 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1518,6 +1518,7 @@ func (s *testParserSuite) TestDDL(c *C) { {`create table t1 (c1 int) compression="zlib";`, true, "CREATE TABLE `t1` (`c1` INT) COMPRESSION = 'zlib';"}, // partition option + // y 2059 对 tableOption 的 ENGINE 和 TABLESPACE 还未做解析 {"CREATE TABLE t (id int) ENGINE = INNDB PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20));", true, "CREATE TABLE `t` (`id` INT) ENGINE = INNDB PARTITION BY RANGE (`id`) (PARTITION p0 VALUES LESS THAN (10),PARTITION p1 VALUES LESS THAN (20));"}, {"create table t (c int) PARTITION BY HASH (c) PARTITIONS 32;", true, "CREATE TABLE `t` (`c` INT) PARTITION BY HASH (`c`) PARTITIONS 32;"}, {"create table t (c int) PARTITION BY HASH (Year(VDate)) (PARTITION p1980 VALUES LESS THAN (1980) ENGINE = MyISAM, PARTITION p1990 VALUES LESS THAN (1990) ENGINE = MyISAM, PARTITION pothers VALUES LESS THAN MAXVALUE ENGINE = MyISAM)", false, ""}, @@ -1592,7 +1593,7 @@ func (s *testParserSuite) TestDDL(c *C) { PRIMARY KEY (id), CONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id), INDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment '' - ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, ""}, + ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`),INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) COMMENT '') ENGINE = InnoDB AUTO_INCREMENT = 30 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, // for issue 975 {`CREATE TABLE test_data ( id bigint(20) NOT NULL AUTO_INCREMENT, @@ -1634,8 +1635,8 @@ func (s *testParserSuite) TestDDL(c *C) { INDEX FK_eqst2x1xisn3o0wbrlahnnqq8 USING BTREE (store_employee_id) comment '', INDEX FK_8jcmec4kb03f4dod0uqwm54o9 USING BTREE (store_id) comment '', INDEX FK_a3t0m9apja9jmrn60uab30pqd USING BTREE (user_id) comment '' - ) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, ""}, - {`create table t (c int KEY);`, true, ""}, + ) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `test_data` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(255) NOT NULL,`amount` DECIMAL(19,2) DEFAULT NULL,`charge_id` VARCHAR(32) DEFAULT NULL,`paid_amount` DECIMAL(19,2) DEFAULT NULL,`transaction_no` VARCHAR(64) DEFAULT NULL,`wx_mp_app_id` VARCHAR(32) DEFAULT NULL,`contacts` VARCHAR(50) DEFAULT NULL,`deliver_fee` DECIMAL(19,2) DEFAULT NULL,`deliver_info` VARCHAR(255) DEFAULT NULL,`deliver_time` VARCHAR(255) DEFAULT NULL,`description` VARCHAR(255) DEFAULT NULL,`invoice` VARCHAR(255) DEFAULT NULL,`order_from` INT(11) DEFAULT NULL,`order_state` INT(11) NOT NULL,`packing_fee` DECIMAL(19,2) DEFAULT NULL,`payment_time` DATETIME DEFAULT NULL,`payment_type` INT(11) DEFAULT NULL,`phone` VARCHAR(50) NOT NULL,`store_employee_id` BIGINT(20) DEFAULT NULL,`store_id` BIGINT(20) NOT NULL,`user_id` BIGINT(20) NOT NULL,`payment_mode` INT(11) NOT NULL,`current_latitude` DOUBLE NOT NULL,`current_longitude` DOUBLE NOT NULL,`address_latitude` DOUBLE NOT NULL,`address_longitude` DOUBLE NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `food_order_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`),CONSTRAINT `food_order_ibfk_2` FOREIGN KEY (`store_id`) REFERENCES `waimaiqa`.`store`(`id`),CONSTRAINT `food_order_ibfk_3` FOREIGN KEY (`store_employee_id`) REFERENCES `waimaiqa`.`store_employee`(`id`),UNIQUE `FK_UNIQUE_charge_id`(`charge_id`) USING BTREE,INDEX `FK_eqst2x1xisn3o0wbrlahnnqq8`(`store_employee_id`) USING BTREE,INDEX `FK_8jcmec4kb03f4dod0uqwm54o9`(`store_id`) USING BTREE,INDEX `FK_a3t0m9apja9jmrn60uab30pqd`(`user_id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 95 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, + {`create table t (c int KEY);`, true, "CREATE TABLE `t` (`c` INT PRIMARY KEY);"}, {`CREATE TABLE address ( id bigint(20) NOT NULL AUTO_INCREMENT, create_at datetime NOT NULL, @@ -1653,23 +1654,23 @@ func (s *testParserSuite) TestDDL(c *C) { PRIMARY KEY (id), CONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION, INDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment '' - ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, ""}, - {"CREATE TABLE address (\r\nid bigint(20) NOT NULL AUTO_INCREMENT,\r\ncreate_at datetime NOT NULL,\r\ndeleted tinyint(1) NOT NULL,\r\nupdate_at datetime NOT NULL,\r\nversion bigint(20) DEFAULT NULL,\r\naddress varchar(128) NOT NULL,\r\naddress_detail varchar(128) NOT NULL,\r\ncellphone varchar(16) NOT NULL,\r\nlatitude double NOT NULL,\r\nlongitude double NOT NULL,\r\nname varchar(16) NOT NULL,\r\nsex tinyint(1) NOT NULL,\r\nuser_id bigint(20) NOT NULL,\r\nPRIMARY KEY (id),\r\nCONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION,\r\nINDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''\r\n) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;", true, ""}, + ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION,INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) COMMENT '') ENGINE = InnoDB AUTO_INCREMENT = 30 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, + {"CREATE TABLE address (\r\nid bigint(20) NOT NULL AUTO_INCREMENT,\r\ncreate_at datetime NOT NULL,\r\ndeleted tinyint(1) NOT NULL,\r\nupdate_at datetime NOT NULL,\r\nversion bigint(20) DEFAULT NULL,\r\naddress varchar(128) NOT NULL,\r\naddress_detail varchar(128) NOT NULL,\r\ncellphone varchar(16) NOT NULL,\r\nlatitude double NOT NULL,\r\nlongitude double NOT NULL,\r\nname varchar(16) NOT NULL,\r\nsex tinyint(1) NOT NULL,\r\nuser_id bigint(20) NOT NULL,\r\nPRIMARY KEY (id),\r\nCONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION,\r\nINDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''\r\n) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;", true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION,INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) COMMENT '') ENGINE = InnoDB AUTO_INCREMENT = 30 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, // for issue 1802 {`CREATE TABLE t1 ( accout_id int(11) DEFAULT '0', summoner_id int(11) DEFAULT '0', union_name varbinary(52) NOT NULL, union_id int(11) DEFAULT '0', - PRIMARY KEY (union_name)) ENGINE=MyISAM DEFAULT CHARSET=binary;`, true, ""}, + PRIMARY KEY (union_name)) ENGINE=MyISAM DEFAULT CHARSET=binary;`, true, ""}, //varbinary 解析binary的问题 // Create table with multiple index options. - {`create table t (c int, index ci (c) USING BTREE COMMENT "123");`, true, ""}, + {`create table t (c int, index ci (c) USING BTREE COMMENT "123");`, true, "CREATE TABLE `t` (`c` INT,INDEX `ci`(`c`) USING BTREE COMMENT '123');"}, // for default value - {"CREATE TABLE sbtest (id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, k integer UNSIGNED DEFAULT '0' NOT NULL, c char(120) DEFAULT '' NOT NULL, pad char(60) DEFAULT '' NOT NULL, PRIMARY KEY (id) )", true, ""}, - {"create table test (create_date TIMESTAMP NOT NULL COMMENT '创建日期 create date' DEFAULT now());", true, ""}, - {"create table ts (t int, v timestamp(3) default CURRENT_TIMESTAMP(3));", true, ""}, + {"CREATE TABLE sbtest (id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, k integer UNSIGNED DEFAULT '0' NOT NULL, c char(120) DEFAULT '' NOT NULL, pad char(60) DEFAULT '' NOT NULL, PRIMARY KEY (id) )", true, "CREATE TABLE `sbtest` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,`k` INT UNSIGNED DEFAULT '0' NOT NULL,`c` CHAR(120) DEFAULT '' NOT NULL,`pad` CHAR(60) DEFAULT '' NOT NULL,PRIMARY KEY(`id`));"}, + {"create table test (create_date TIMESTAMP NOT NULL COMMENT '创建日期 create date' DEFAULT now());", true, "CREATE TABLE `test` (`create_date` TIMESTAMP NOT NULL COMMENT '创建日期 create date' DEFAULT CURRENT_TIMESTAMP());"}, + {"create table ts (t int, v timestamp(3) default CURRENT_TIMESTAMP(3));", true, "CREATE TABLE `ts` (`t` INT,`v` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP());"}, //括号里的 3 暂时没有 // Create table with primary key name. - {"create table if not exists `t` (`id` int not null auto_increment comment '消息ID', primary key `pk_id` (`id`) );", true, ""}, + {"create table if not exists `t` (`id` int not null auto_increment comment '消息ID', primary key `pk_id` (`id`) );", true, "CREATE TABLE IF NOT EXISTS `t` (`id` INT NOT NULL AUTO_INCREMENT COMMENT '消息ID',PRIMARY KEY(`id`));"}, // Create table with like. {"create table a like b", true, "CREATE TABLE `a` LIKE `b`;"}, {"create table a (like b)", true, "CREATE TABLE `a` LIKE `b`;"}, @@ -1688,18 +1689,18 @@ func (s *testParserSuite) TestDDL(c *C) { {"create table a (m int) replace as (select n as m from b union select n+1 as m from c group by 1 limit 2)", true, ""}, // Create table with no option is valid for parser - {"create table a", true, ""}, + {"create table a", true, "CREATE TABLE `a` ;"}, {"create table t (a timestamp default now)", false, ""}, {"create table t (a timestamp default now())", true, ""}, {"create table t (a timestamp default now() on update now)", false, ""}, - {"create table t (a timestamp default now() on update now())", true, ""}, + {"create table t (a timestamp default now() on update now())", true, "CREATE TABLE `t` (`a` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP());"}, {"CREATE TABLE t (c TEXT) default CHARACTER SET utf8, default COLLATE utf8_general_ci;", true, ""}, - {"CREATE TABLE t (c TEXT) shard_row_id_bits = 1;", true, ""}, + {"CREATE TABLE t (c TEXT) shard_row_id_bits = 1;", true, "CREATE TABLE `t` (`c` TEXT) SHARD_ROW_ID_BITS = 1;"}, // Create table with ON UPDATE CURRENT_TIMESTAMP(6), specify fraction part. - {"CREATE TABLE IF NOT EXISTS `general_log` (`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),`user_host` mediumtext NOT NULL,`thread_id` bigint(20) unsigned NOT NULL,`server_id` int(10) unsigned NOT NULL,`command_type` varchar(64) NOT NULL,`argument` mediumblob NOT NULL) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'", true, ""}, + //{"CREATE TABLE IF NOT EXISTS `general_log` (`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),`user_host` mediumtext NOT NULL,`thread_id` bigint(20) unsigned NOT NULL,`server_id` int(10) unsigned NOT NULL,`command_type` varchar(64) NOT NULL,`argument` mediumblob NOT NULL) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'", true, "CREATE TABLE IF NOT EXISTS `general_log` (`event_time` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(),`user_host` MEDIUMTEXT NOT NULL,`thread_id` BIGINT(20) UNSIGNED NOT NULL,`server_id` INT(10) UNSIGNED NOT NULL,`command_type` VARCHAR(64) NOT NULL,`argument` MEDIUMBLOB BINARY NOT NULL) ENGINE = CSV CHARACTER SET = utf8 COMMENT = 'General log';"}, // 时间里面的数字暂时没有 和 BINARY解析问题 // For reference_definition in column_definition. - {"CREATE TABLE followers ( f1 int NOT NULL REFERENCES user_profiles (uid) );", true, ""}, + {"CREATE TABLE followers ( f1 int NOT NULL REFERENCES user_profiles (uid) );", true, "CREATE TABLE `followers` (`f1` INT NOT NULL REFERENCES `user_profiles`(`uid`));"}, // for alter table {"ALTER TABLE t ADD COLUMN (a SMALLINT UNSIGNED)", true, ""}, @@ -1825,13 +1826,17 @@ func (s *testParserSuite) TestDDL(c *C) { {"ALTER TABLE t ADD UNIQUE KEY ()", false, ""}, // for issue 4538 - {"create table a (process double)", true, ""}, + {"create table a (process double)", true, "CREATE TABLE `a` (`process` DOUBLE);"}, // for issue 4740 - {"create table t (a int1, b int2, c int3, d int4, e int8)", true, ""}, + {"create table t (a int1, b int2, c int3, d int4, e int8)", true, "CREATE TABLE `t` (`a` TINYINT,`b` SMALLINT,`c` MEDIUMINT,`d` INT,`e` BIGINT);"}, // for issue 5918 - {"create table t (lv long varchar null)", true, ""}, + {"create table t (lv long varchar null)", true, "CREATE TABLE `t` (`lv` MEDIUMTEXT NULL);"}, //这里是需要MEDIUMTEXT吗? + + // special table name + {"CREATE TABLE cdp_test.`test2-1` (id int(11) DEFAULT NULL,key(id));", true, "CREATE TABLE `cdp_test`.`test2-1` (`id` INT(11) DEFAULT NULL,INDEX(`id`));"}, + {"CREATE TABLE miantiao (`扁豆焖面` INT(11));", true, "CREATE TABLE `miantiao` (`扁豆焖面` INT(11));"}, } s.RunTest(c, table) } From 82385c146368831be9ad691b7dc85668a8ae10f5 Mon Sep 17 00:00:00 2001 From: chendapao Date: Sun, 13 Jan 2019 20:49:29 +0800 Subject: [PATCH 09/15] Add case and add claernode code --- parser_test.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/parser_test.go b/parser_test.go index d1c2725d8..2929ad5d4 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1636,7 +1636,7 @@ func (s *testParserSuite) TestDDL(c *C) { INDEX FK_eqst2x1xisn3o0wbrlahnnqq8 USING BTREE (store_employee_id) comment '', INDEX FK_8jcmec4kb03f4dod0uqwm54o9 USING BTREE (store_id) comment '', INDEX FK_a3t0m9apja9jmrn60uab30pqd USING BTREE (user_id) comment '' - ) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, ""}, + ) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARACTER SET utf8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `test_data` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(255) NOT NULL,`amount` DECIMAL(19,2) DEFAULT NULL,`charge_id` VARCHAR(32) DEFAULT NULL,`paid_amount` DECIMAL(19,2) DEFAULT NULL,`transaction_no` VARCHAR(64) DEFAULT NULL,`wx_mp_app_id` VARCHAR(32) DEFAULT NULL,`contacts` VARCHAR(50) DEFAULT NULL,`deliver_fee` DECIMAL(19,2) DEFAULT NULL,`deliver_info` VARCHAR(255) DEFAULT NULL,`deliver_time` VARCHAR(255) DEFAULT NULL,`description` VARCHAR(255) DEFAULT NULL,`invoice` VARCHAR(255) DEFAULT NULL,`order_from` INT(11) DEFAULT NULL,`order_state` INT(11) NOT NULL,`packing_fee` DECIMAL(19,2) DEFAULT NULL,`payment_time` DATETIME DEFAULT NULL,`payment_type` INT(11) DEFAULT NULL,`phone` VARCHAR(50) NOT NULL,`store_employee_id` BIGINT(20) DEFAULT NULL,`store_id` BIGINT(20) NOT NULL,`user_id` BIGINT(20) NOT NULL,`payment_mode` INT(11) NOT NULL,`current_latitude` DOUBLE NOT NULL,`current_longitude` DOUBLE NOT NULL,`address_latitude` DOUBLE NOT NULL,`address_longitude` DOUBLE NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `food_order_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`),CONSTRAINT `food_order_ibfk_2` FOREIGN KEY (`store_id`) REFERENCES `waimaiqa`.`store`(`id`),CONSTRAINT `food_order_ibfk_3` FOREIGN KEY (`store_employee_id`) REFERENCES `waimaiqa`.`store_employee`(`id`),UNIQUE `FK_UNIQUE_charge_id`(`charge_id`) USING BTREE,INDEX `FK_eqst2x1xisn3o0wbrlahnnqq8`(`store_employee_id`) USING BTREE,INDEX `FK_8jcmec4kb03f4dod0uqwm54o9`(`store_id`) USING BTREE,INDEX `FK_a3t0m9apja9jmrn60uab30pqd`(`user_id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 95 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, {`create table t (c int KEY);`, true, "CREATE TABLE `t` (`c` INT PRIMARY KEY);"}, {`CREATE TABLE address ( id bigint(20) NOT NULL AUTO_INCREMENT, @@ -1655,8 +1655,8 @@ func (s *testParserSuite) TestDDL(c *C) { PRIMARY KEY (id), CONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION, INDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment '' - ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, ""}, - //{"CREATE TABLE address (\r\nid bigint(20) NOT NULL AUTO_INCREMENT,\r\ncreate_at datetime NOT NULL,\r\ndeleted tinyint(1) NOT NULL,\r\nupdate_at datetime NOT NULL,\r\nversion bigint(20) DEFAULT NULL,\r\naddress varchar(128) NOT NULL,\r\naddress_detail varchar(128) NOT NULL,\r\ncellphone varchar(16) NOT NULL,\r\nlatitude double NOT NULL,\r\nlongitude double NOT NULL,\r\nname varchar(16) NOT NULL,\r\nsex tinyint(1) NOT NULL,\r\nuser_id bigint(20) NOT NULL,\r\nPRIMARY KEY (id),\r\nCONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION,\r\nINDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''\r\n) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;", true, ""}, + ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION,INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 30 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, + {"CREATE TABLE address (\r\nid bigint(20) NOT NULL AUTO_INCREMENT,\r\ncreate_at datetime NOT NULL,\r\ndeleted tinyint(1) NOT NULL,\r\nupdate_at datetime NOT NULL,\r\nversion bigint(20) DEFAULT NULL,\r\naddress varchar(128) NOT NULL,\r\naddress_detail varchar(128) NOT NULL,\r\ncellphone varchar(16) NOT NULL,\r\nlatitude double NOT NULL,\r\nlongitude double NOT NULL,\r\nname varchar(16) NOT NULL,\r\nsex tinyint(1) NOT NULL,\r\nuser_id bigint(20) NOT NULL,\r\nPRIMARY KEY (id),\r\nCONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION,\r\nINDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''\r\n) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;", true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION,INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 30 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, // for issue 1802 {`CREATE TABLE t1 ( accout_id int(11) DEFAULT '0', @@ -1693,10 +1693,10 @@ func (s *testParserSuite) TestDDL(c *C) { {"create table a", true, "CREATE TABLE `a` ;"}, {"create table t (a timestamp default now)", false, ""}, - {"create table t (a timestamp default now())", true, ""}, + {"create table t (a timestamp default now())", true, "CREATE TABLE `t` (`a` TIMESTAMP DEFAULT CURRENT_TIMESTAMP());"}, {"create table t (a timestamp default now() on update now)", false, ""}, {"create table t (a timestamp default now() on update now())", true, "CREATE TABLE `t` (`a` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP());"}, - {"CREATE TABLE t (c TEXT) default CHARACTER SET utf8, default COLLATE utf8_general_ci;", true, ""}, + {"CREATE TABLE t (c TEXT) default CHARACTER SET utf8, default COLLATE utf8_general_ci;", true, "CREATE TABLE `t` (`c` TEXT) DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI;"}, {"CREATE TABLE t (c TEXT) shard_row_id_bits = 1;", true, "CREATE TABLE `t` (`c` TEXT) SHARD_ROW_ID_BITS = 1;"}, // Create table with ON UPDATE CURRENT_TIMESTAMP(6), specify fraction part. //{"CREATE TABLE IF NOT EXISTS `general_log` (`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),`user_host` mediumtext NOT NULL,`thread_id` bigint(20) unsigned NOT NULL,`server_id` int(10) unsigned NOT NULL,`command_type` varchar(64) NOT NULL,`argument` mediumblob NOT NULL) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'", true, "CREATE TABLE IF NOT EXISTS `general_log` (`event_time` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(),`user_host` MEDIUMTEXT NOT NULL,`thread_id` BIGINT(20) UNSIGNED NOT NULL,`server_id` INT(10) UNSIGNED NOT NULL,`command_type` VARCHAR(64) NOT NULL,`argument` MEDIUMBLOB BINARY NOT NULL) ENGINE = CSV CHARACTER SET = utf8 COMMENT = 'General log';"}, // 时间里面的数字暂时没有 和 BINARY解析问题 @@ -2905,6 +2905,18 @@ type nodeTextCleaner struct { func (checker *nodeTextCleaner) Enter(in ast.Node) (out ast.Node, skipChildren bool) { in.SetText("") switch node := in.(type) { + case *ast.CreateTableStmt: + for _, opt := range node.Options { + switch opt.Tp { + case ast.TableOptionCharset: + opt.StrValue = strings.ToUpper(opt.StrValue) + case ast.TableOptionCollate: + opt.StrValue = strings.ToUpper(opt.StrValue) + } + } + for _, col := range node.Cols { + col.Tp.Collate = strings.ToUpper(col.Tp.Collate) + } case *ast.Constraint: if node.Option != nil { if node.Option.KeyBlockSize == 0x0 && node.Option.Tp == 0 && node.Option.Comment == "" { From ecd8735b9f2e08ac5ba321b0981764368b60678e Mon Sep 17 00:00:00 2001 From: chendapao Date: Tue, 15 Jan 2019 11:04:13 +0800 Subject: [PATCH 10/15] Delete unwanted --- parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser.y b/parser.y index 0fb4b2c5f..7dc484a0d 100644 --- a/parser.y +++ b/parser.y @@ -6531,7 +6531,6 @@ TableOption: | "STATS_PERSISTENT" EqOpt StatsPersistentVal { $$ = &ast.TableOption{Tp: ast.TableOptionStatsPersistent} - } | "SHARD_ROW_ID_BITS" EqOpt LengthNum { @@ -6539,6 +6538,7 @@ TableOption: } | "PACK_KEYS" EqOpt StatsPersistentVal { + // Parse it but will ignore it. $$ = &ast.TableOption{Tp: ast.TableOptionPackKeys} } From 1f460d194824a1c9aeb918abf3527195cc6bd12a Mon Sep 17 00:00:00 2001 From: chendapao Date: Tue, 15 Jan 2019 11:05:57 +0800 Subject: [PATCH 11/15] Delete unwanted --- parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser.y b/parser.y index 7dc484a0d..93939422f 100644 --- a/parser.y +++ b/parser.y @@ -6530,7 +6530,7 @@ TableOption: } | "STATS_PERSISTENT" EqOpt StatsPersistentVal { - $$ = &ast.TableOption{Tp: ast.TableOptionStatsPersistent} + $$ = &ast.TableOption{Tp: ast.TableOptionStatsPersistent} } | "SHARD_ROW_ID_BITS" EqOpt LengthNum { From 0293d1d0e25ce297dbdd13bd96962bbfe5ff80f3 Mon Sep 17 00:00:00 2001 From: chendapao Date: Tue, 15 Jan 2019 11:51:31 +0800 Subject: [PATCH 12/15] Delete unwanted --- ast/ddl_test.go | 2 ++ parser.go | 2 +- parser_test.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ast/ddl_test.go b/ast/ddl_test.go index 77115ff86..4ad65ded8 100755 --- a/ast/ddl_test.go +++ b/ast/ddl_test.go @@ -155,6 +155,8 @@ func (ts *testDDLSuite) TestDDLConstraintRestore(c *C) { {"fulltext INDEX full_id (parent_id)", "FULLTEXT `full_id`(`parent_id`)"}, {"PRIMARY KEY (id)", "PRIMARY KEY(`id`)"}, {"PRIMARY KEY (id) key_block_size = 32 using hash comment 'hello'", "PRIMARY KEY(`id`) KEY_BLOCK_SIZE=32 USING HASH COMMENT 'hello'"}, + {"CONSTRAINT FOREIGN KEY (parent_id(2),hello(4)) REFERENCES parent(id) ON DELETE CASCADE", "CONSTRAINT FOREIGN KEY (`parent_id`(2), `hello`(4)) REFERENCES `parent`(`id`) ON DELETE CASCADE"}, + {"CONSTRAINT FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "CONSTRAINT FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, {"CONSTRAINT fk_123 FOREIGN KEY (parent_id(2),hello(4)) REFERENCES parent(id) ON DELETE CASCADE", "CONSTRAINT `fk_123` FOREIGN KEY (`parent_id`(2), `hello`(4)) REFERENCES `parent`(`id`) ON DELETE CASCADE"}, {"CONSTRAINT fk_123 FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "CONSTRAINT `fk_123` FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, } diff --git a/parser.go b/parser.go index 34137cdab..dc1ec4d97 100644 --- a/parser.go +++ b/parser.go @@ -11692,7 +11692,6 @@ yynewstate: case 1234: { parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionStatsPersistent} - } case 1235: { @@ -11700,6 +11699,7 @@ yynewstate: } case 1236: { + // Parse it but will ignore it. parser.yyVAL.item = &ast.TableOption{Tp: ast.TableOptionPackKeys} } case 1239: diff --git a/parser_test.go b/parser_test.go index f4a9c5e4f..5a2f0f94c 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1674,7 +1674,7 @@ func (s *testParserSuite) TestDDL(c *C) { summoner_id int(11) DEFAULT '0', union_name varbinary(52) NOT NULL, union_id int(11) DEFAULT '0', - PRIMARY KEY (union_name)) ENGINE=MyISAM DEFAULT CHARSET=binary;`, true, ""}, //varbinary 解析binary的问题 + PRIMARY KEY (union_name)) ENGINE=MyISAM DEFAULT CHARSET=binary;`, true, "CREATE TABLE `t1` (`accout_id` INT(11) DEFAULT '0',`summoner_id` INT(11) DEFAULT '0',`union_name` VARBINARY(52) NOT NULL,`union_id` INT(11) DEFAULT '0',PRIMARY KEY(`union_name`)) ENGINE = MyISAM DEFAULT CHARACTER SET = BINARY;"}, // Create table with multiple index options. {`create table t (c int, index ci (c) USING BTREE COMMENT "123");`, true, "CREATE TABLE `t` (`c` INT,INDEX `ci`(`c`) USING BTREE COMMENT '123');"}, // for default value From ae846a97a3c3094502d08eff40854c66b0a34368 Mon Sep 17 00:00:00 2001 From: chendapao Date: Tue, 15 Jan 2019 15:17:22 +0800 Subject: [PATCH 13/15] Add select --- ast/ddl.go | 24 ++++++-- parser_test.go | 149 +++++++++++++++++++++++++------------------------ 2 files changed, 97 insertions(+), 76 deletions(-) diff --git a/ast/ddl.go b/ast/ddl.go index b1a594839..4bace02eb 100755 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -693,7 +693,7 @@ func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { } } - if col := len(n.Cols); col > 0 { + if lenCols := len(n.Cols); lenCols > 0 { ctx.WritePlain("(") for i, col := range n.Cols { if i > 0 { @@ -704,7 +704,7 @@ func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { } } for i, constraint := range n.Constraints { - if i > 0 || col >= 1 { + if i > 0 || lenCols >= 1 { ctx.WritePlain(",") } if err := constraint.Restore(ctx); err != nil { @@ -727,8 +727,24 @@ func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { return errors.Annotate(err, "An error occurred while splicing CreateTableStmt Partition") } } - ctx.WritePlain(";") - //TODO: Restore Select Stmt + + if n.Select != nil { + ctx.WritePlain(" ") + + switch n.OnDuplicate { + case OnDuplicateCreateTableSelectError: + // nothing output + case OnDuplicateCreateTableSelectIgnore: + ctx.WriteKeyWord("IGNORE ") + case OnDuplicateCreateTableSelectReplace: + ctx.WriteKeyWord("REPLACE ") + } + + ctx.WriteKeyWord("AS ") + if err := n.Select.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while splicing CreateTableStmt Select") + } + } return nil } diff --git a/parser_test.go b/parser_test.go index 5a2f0f94c..da560eac0 100755 --- a/parser_test.go +++ b/parser_test.go @@ -1473,66 +1473,66 @@ func (s *testParserSuite) TestDDL(c *C) { {"CREATE TABLE foo (", false, ""}, {"CREATE TABLE foo ()", false, ""}, {"CREATE TABLE foo ();", false, ""}, - {"CREATE TABLE foo (a varchar(50), b int);", true, "CREATE TABLE `foo` (`a` VARCHAR(50),`b` INT);"}, - {"CREATE TABLE foo (a TINYINT UNSIGNED);", true, "CREATE TABLE `foo` (`a` TINYINT UNSIGNED);"}, - {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, - {"CREATE TABLE foo (a bigint unsigned, b bool);", true, "CREATE TABLE `foo` (`a` BIGINT UNSIGNED,`b` TINYINT(1));"}, + {"CREATE TABLE foo (a varchar(50), b int);", true, "CREATE TABLE `foo` (`a` VARCHAR(50),`b` INT)"}, + {"CREATE TABLE foo (a TINYINT UNSIGNED);", true, "CREATE TABLE `foo` (`a` TINYINT UNSIGNED)"}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED)"}, + {"CREATE TABLE foo (a bigint unsigned, b bool);", true, "CREATE TABLE `foo` (`a` BIGINT UNSIGNED,`b` TINYINT(1))"}, {"CREATE TABLE foo (a TINYINT, b SMALLINT) CREATE TABLE bar (x INT, y int64)", false, ""}, {"CREATE TABLE foo (a int, b float); CREATE TABLE bar (x double, y float)", true, ""}, {"CREATE TABLE foo (a bytes)", false, ""}, - {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, - {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) -- foo", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED)", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED)"}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) -- foo", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED)"}, {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) // foo", false, ""}, - {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, - {"CREATE TABLE foo /* foo */ (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED);"}, - {"CREATE TABLE foo (name CHAR(50) BINARY);", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY);"}, - {"CREATE TABLE foo (name CHAR(50) COLLATE utf8_bin)", true, "CREATE TABLE `foo` (`name` CHAR(50) COLLATE utf8_bin);"}, - {"CREATE TABLE foo (id varchar(50) collate utf8);", true, "CREATE TABLE `foo` (`id` VARCHAR(50) COLLATE utf8);"}, - {"CREATE TABLE foo (name CHAR(50) CHARACTER SET UTF8)", true, "CREATE TABLE `foo` (`name` CHAR(50) CHARACTER SET UTF8);"}, - {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY)", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY CHARACTER SET UTF8);"}, + {"CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED)"}, + {"CREATE TABLE foo /* foo */ (a SMALLINT UNSIGNED, b INT UNSIGNED) /* foo */", true, "CREATE TABLE `foo` (`a` SMALLINT UNSIGNED,`b` INT UNSIGNED)"}, + {"CREATE TABLE foo (name CHAR(50) BINARY);", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY)"}, + {"CREATE TABLE foo (name CHAR(50) COLLATE utf8_bin)", true, "CREATE TABLE `foo` (`name` CHAR(50) COLLATE utf8_bin)"}, + {"CREATE TABLE foo (id varchar(50) collate utf8);", true, "CREATE TABLE `foo` (`id` VARCHAR(50) COLLATE utf8)"}, + {"CREATE TABLE foo (name CHAR(50) CHARACTER SET UTF8)", true, "CREATE TABLE `foo` (`name` CHAR(50) CHARACTER SET UTF8)"}, + {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY)", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY CHARACTER SET UTF8)"}, {"CREATE TABLE foo (name CHAR(50) CHARACTER SET utf8 BINARY CHARACTER set utf8)", false, ""}, - {"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin)", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY CHARACTER SET UTF8 COLLATE utf8_bin);"}, + {"CREATE TABLE foo (name CHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin)", true, "CREATE TABLE `foo` (`name` CHAR(50) BINARY CHARACTER SET UTF8 COLLATE utf8_bin)"}, {"CREATE TABLE foo (a.b, b);", false, ""}, {"CREATE TABLE foo (a, b.c);", false, ""}, {"CREATE TABLE (name CHAR(50) BINARY)", false, ""}, // for table option - {"create table t (c int) avg_row_length = 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH = 3;"}, - {"create table t (c int) avg_row_length 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH = 3;"}, - {"create table t (c int) checksum = 0", true, "CREATE TABLE `t` (`c` INT) CHECKSUM = 0;"}, - {"create table t (c int) checksum 1", true, "CREATE TABLE `t` (`c` INT) CHECKSUM = 1;"}, - {"create table t (c int) compression = 'NONE'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION = 'NONE';"}, - {"create table t (c int) compression 'lz4'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION = 'lz4';"}, - {"create table t (c int) connection = 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION = 'abc';"}, - {"create table t (c int) connection 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION = 'abc';"}, - {"create table t (c int) key_block_size = 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE = 1024;"}, - {"create table t (c int) key_block_size 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE = 1024;"}, - {"create table t (c int) max_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS = 1000;"}, - {"create table t (c int) max_rows 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS = 1000;"}, - {"create table t (c int) min_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS = 1000;"}, - {"create table t (c int) min_rows 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS = 1000;"}, - {"create table t (c int) password = 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD = 'abc';"}, - {"create table t (c int) password 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD = 'abc';"}, - {"create table t (c int) DELAY_KEY_WRITE=1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE = 1;"}, - {"create table t (c int) DELAY_KEY_WRITE 1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE = 1;"}, - {"create table t (c int) ROW_FORMAT = default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DEFAULT;"}, - {"create table t (c int) ROW_FORMAT default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DEFAULT;"}, - {"create table t (c int) ROW_FORMAT = fixed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = FIXED;"}, - {"create table t (c int) ROW_FORMAT = compressed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = COMPRESSED;"}, - {"create table t (c int) ROW_FORMAT = compact", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = COMPACT;"}, - {"create table t (c int) ROW_FORMAT = redundant", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = REDUNDANT;"}, - {"create table t (c int) ROW_FORMAT = dynamic", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DYNAMIC;"}, + {"create table t (c int) avg_row_length = 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH = 3"}, + {"create table t (c int) avg_row_length 3", true, "CREATE TABLE `t` (`c` INT) AVG_ROW_LENGTH = 3"}, + {"create table t (c int) checksum = 0", true, "CREATE TABLE `t` (`c` INT) CHECKSUM = 0"}, + {"create table t (c int) checksum 1", true, "CREATE TABLE `t` (`c` INT) CHECKSUM = 1"}, + {"create table t (c int) compression = 'NONE'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION = 'NONE'"}, + {"create table t (c int) compression 'lz4'", true, "CREATE TABLE `t` (`c` INT) COMPRESSION = 'lz4'"}, + {"create table t (c int) connection = 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION = 'abc'"}, + {"create table t (c int) connection 'abc'", true, "CREATE TABLE `t` (`c` INT) CONNECTION = 'abc'"}, + {"create table t (c int) key_block_size = 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE = 1024"}, + {"create table t (c int) key_block_size 1024", true, "CREATE TABLE `t` (`c` INT) KEY_BLOCK_SIZE = 1024"}, + {"create table t (c int) max_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS = 1000"}, + {"create table t (c int) max_rows 1000", true, "CREATE TABLE `t` (`c` INT) MAX_ROWS = 1000"}, + {"create table t (c int) min_rows = 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS = 1000"}, + {"create table t (c int) min_rows 1000", true, "CREATE TABLE `t` (`c` INT) MIN_ROWS = 1000"}, + {"create table t (c int) password = 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD = 'abc'"}, + {"create table t (c int) password 'abc'", true, "CREATE TABLE `t` (`c` INT) PASSWORD = 'abc'"}, + {"create table t (c int) DELAY_KEY_WRITE=1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE = 1"}, + {"create table t (c int) DELAY_KEY_WRITE 1", true, "CREATE TABLE `t` (`c` INT) DELAY_KEY_WRITE = 1"}, + {"create table t (c int) ROW_FORMAT = default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DEFAULT"}, + {"create table t (c int) ROW_FORMAT default", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DEFAULT"}, + {"create table t (c int) ROW_FORMAT = fixed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = FIXED"}, + {"create table t (c int) ROW_FORMAT = compressed", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = COMPRESSED"}, + {"create table t (c int) ROW_FORMAT = compact", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = COMPACT"}, + {"create table t (c int) ROW_FORMAT = redundant", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = REDUNDANT"}, + {"create table t (c int) ROW_FORMAT = dynamic", true, "CREATE TABLE `t` (`c` INT) ROW_FORMAT = DYNAMIC"}, {"create table t (c int) STATS_PERSISTENT = default", true, ""}, {"create table t (c int) STATS_PERSISTENT = 0", true, ""}, {"create table t (c int) STATS_PERSISTENT = 1", true, ""}, {"create table t (c int) PACK_KEYS = 1", true, ""}, {"create table t (c int) PACK_KEYS = 0", true, ""}, {"create table t (c int) PACK_KEYS = DEFAULT", true, ""}, - {`create table testTableCompression (c VARCHAR(15000)) compression="ZLIB";`, true, "CREATE TABLE `testTableCompression` (`c` VARCHAR(15000)) COMPRESSION = 'ZLIB';"}, - {`create table t1 (c1 int) compression="zlib";`, true, "CREATE TABLE `t1` (`c1` INT) COMPRESSION = 'zlib';"}, + {`create table testTableCompression (c VARCHAR(15000)) compression="ZLIB";`, true, "CREATE TABLE `testTableCompression` (`c` VARCHAR(15000)) COMPRESSION = 'ZLIB'"}, + {`create table t1 (c1 int) compression="zlib";`, true, "CREATE TABLE `t1` (`c1` INT) COMPRESSION = 'zlib'"}, // partition option - {"CREATE TABLE t (id int) ENGINE = INNDB PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20));", true, "CREATE TABLE `t` (`id` INT) ENGINE = INNDB PARTITION BY RANGE (`id`) (PARTITION `p0` VALUES LESS THAN (10),PARTITION `p1` VALUES LESS THAN (20));"}, - {"create table t (c int) PARTITION BY HASH (c) PARTITIONS 32;", true, "CREATE TABLE `t` (`c` INT) PARTITION BY HASH (`c`) PARTITIONS 32;"}, + {"CREATE TABLE t (id int) ENGINE = INNDB PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20));", true, "CREATE TABLE `t` (`id` INT) ENGINE = INNDB PARTITION BY RANGE (`id`) (PARTITION `p0` VALUES LESS THAN (10),PARTITION `p1` VALUES LESS THAN (20))"}, + {"create table t (c int) PARTITION BY HASH (c) PARTITIONS 32;", true, "CREATE TABLE `t` (`c` INT) PARTITION BY HASH (`c`) PARTITIONS 32"}, {"create table t (c int) PARTITION BY HASH (Year(VDate)) (PARTITION p1980 VALUES LESS THAN (1980) ENGINE = MyISAM, PARTITION p1990 VALUES LESS THAN (1990) ENGINE = MyISAM, PARTITION pothers VALUES LESS THAN MAXVALUE ENGINE = MyISAM)", false, ""}, {"create table t (c int) PARTITION BY RANGE (Year(VDate)) (PARTITION p1980 VALUES LESS THAN (1980) ENGINE = MyISAM, PARTITION p1990 VALUES LESS THAN (1990) ENGINE = MyISAM, PARTITION pothers VALUES LESS THAN MAXVALUE ENGINE = MyISAM)", true, ""}, {"create table t (c int, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '') PARTITION BY RANGE (UNIX_TIMESTAMP(create_time)) (PARTITION p201610 VALUES LESS THAN(1477929600), PARTITION p201611 VALUES LESS THAN(1480521600),PARTITION p201612 VALUES LESS THAN(1483200000),PARTITION p201701 VALUES LESS THAN(1485878400),PARTITION p201702 VALUES LESS THAN(1488297600),PARTITION p201703 VALUES LESS THAN(1490976000))", true, ""}, @@ -1554,8 +1554,8 @@ func (s *testParserSuite) TestDDL(c *C) { PARTITION part11 VALUES LESS THAN (12) COMMENT = '12月份' ENGINE = InnoDB) */ ;`, true, ""}, // for check clause - {"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true, "CREATE TABLE `t` (`c1` TINYINT(1),`c2` TINYINT(1));"}, //TODO: Check in ColumnOption, yacc is not implemented - {"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true, "CREATE TABLE `Customer` (`SD` INT ,`First_Name` VARCHAR(30));"}, //TODO: Check in ColumnOption, yacc is not implemented + {"create table t (c1 bool, c2 bool, check (c1 in (0, 1)), check (c2 in (0, 1)))", true, "CREATE TABLE `t` (`c1` TINYINT(1),`c2` TINYINT(1))"}, //TODO: Check in ColumnOption, yacc is not implemented + {"CREATE TABLE Customer (SD integer CHECK (SD > 0), First_Name varchar(30));", true, "CREATE TABLE `Customer` (`SD` INT ,`First_Name` VARCHAR(30))"}, //TODO: Check in ColumnOption, yacc is not implemented {"create database xxx", true, "CREATE DATABASE `xxx`"}, {"create database if exists xxx", false, ""}, @@ -1605,7 +1605,7 @@ func (s *testParserSuite) TestDDL(c *C) { PRIMARY KEY (id), CONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id), INDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment '' - ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`),INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 30 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, + ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`),INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 30 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0"}, // for issue 975 {`CREATE TABLE test_data ( id bigint(20) NOT NULL AUTO_INCREMENT, @@ -1647,8 +1647,8 @@ func (s *testParserSuite) TestDDL(c *C) { INDEX FK_eqst2x1xisn3o0wbrlahnnqq8 USING BTREE (store_employee_id) comment '', INDEX FK_8jcmec4kb03f4dod0uqwm54o9 USING BTREE (store_id) comment '', INDEX FK_a3t0m9apja9jmrn60uab30pqd USING BTREE (user_id) comment '' - ) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARACTER SET utf8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `test_data` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(255) NOT NULL,`amount` DECIMAL(19,2) DEFAULT NULL,`charge_id` VARCHAR(32) DEFAULT NULL,`paid_amount` DECIMAL(19,2) DEFAULT NULL,`transaction_no` VARCHAR(64) DEFAULT NULL,`wx_mp_app_id` VARCHAR(32) DEFAULT NULL,`contacts` VARCHAR(50) DEFAULT NULL,`deliver_fee` DECIMAL(19,2) DEFAULT NULL,`deliver_info` VARCHAR(255) DEFAULT NULL,`deliver_time` VARCHAR(255) DEFAULT NULL,`description` VARCHAR(255) DEFAULT NULL,`invoice` VARCHAR(255) DEFAULT NULL,`order_from` INT(11) DEFAULT NULL,`order_state` INT(11) NOT NULL,`packing_fee` DECIMAL(19,2) DEFAULT NULL,`payment_time` DATETIME DEFAULT NULL,`payment_type` INT(11) DEFAULT NULL,`phone` VARCHAR(50) NOT NULL,`store_employee_id` BIGINT(20) DEFAULT NULL,`store_id` BIGINT(20) NOT NULL,`user_id` BIGINT(20) NOT NULL,`payment_mode` INT(11) NOT NULL,`current_latitude` DOUBLE NOT NULL,`current_longitude` DOUBLE NOT NULL,`address_latitude` DOUBLE NOT NULL,`address_longitude` DOUBLE NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `food_order_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`),CONSTRAINT `food_order_ibfk_2` FOREIGN KEY (`store_id`) REFERENCES `waimaiqa`.`store`(`id`),CONSTRAINT `food_order_ibfk_3` FOREIGN KEY (`store_employee_id`) REFERENCES `waimaiqa`.`store_employee`(`id`),UNIQUE `FK_UNIQUE_charge_id`(`charge_id`) USING BTREE,INDEX `FK_eqst2x1xisn3o0wbrlahnnqq8`(`store_employee_id`) USING BTREE,INDEX `FK_8jcmec4kb03f4dod0uqwm54o9`(`store_id`) USING BTREE,INDEX `FK_a3t0m9apja9jmrn60uab30pqd`(`user_id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 95 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, - {`create table t (c int KEY);`, true, "CREATE TABLE `t` (`c` INT PRIMARY KEY);"}, + ) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARACTER SET utf8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `test_data` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(255) NOT NULL,`amount` DECIMAL(19,2) DEFAULT NULL,`charge_id` VARCHAR(32) DEFAULT NULL,`paid_amount` DECIMAL(19,2) DEFAULT NULL,`transaction_no` VARCHAR(64) DEFAULT NULL,`wx_mp_app_id` VARCHAR(32) DEFAULT NULL,`contacts` VARCHAR(50) DEFAULT NULL,`deliver_fee` DECIMAL(19,2) DEFAULT NULL,`deliver_info` VARCHAR(255) DEFAULT NULL,`deliver_time` VARCHAR(255) DEFAULT NULL,`description` VARCHAR(255) DEFAULT NULL,`invoice` VARCHAR(255) DEFAULT NULL,`order_from` INT(11) DEFAULT NULL,`order_state` INT(11) NOT NULL,`packing_fee` DECIMAL(19,2) DEFAULT NULL,`payment_time` DATETIME DEFAULT NULL,`payment_type` INT(11) DEFAULT NULL,`phone` VARCHAR(50) NOT NULL,`store_employee_id` BIGINT(20) DEFAULT NULL,`store_id` BIGINT(20) NOT NULL,`user_id` BIGINT(20) NOT NULL,`payment_mode` INT(11) NOT NULL,`current_latitude` DOUBLE NOT NULL,`current_longitude` DOUBLE NOT NULL,`address_latitude` DOUBLE NOT NULL,`address_longitude` DOUBLE NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `food_order_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`),CONSTRAINT `food_order_ibfk_2` FOREIGN KEY (`store_id`) REFERENCES `waimaiqa`.`store`(`id`),CONSTRAINT `food_order_ibfk_3` FOREIGN KEY (`store_employee_id`) REFERENCES `waimaiqa`.`store_employee`(`id`),UNIQUE `FK_UNIQUE_charge_id`(`charge_id`) USING BTREE,INDEX `FK_eqst2x1xisn3o0wbrlahnnqq8`(`store_employee_id`) USING BTREE,INDEX `FK_8jcmec4kb03f4dod0uqwm54o9`(`store_id`) USING BTREE,INDEX `FK_a3t0m9apja9jmrn60uab30pqd`(`user_id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 95 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0"}, + {`create table t (c int KEY);`, true, "CREATE TABLE `t` (`c` INT PRIMARY KEY)"}, {`CREATE TABLE address ( id bigint(20) NOT NULL AUTO_INCREMENT, create_at datetime NOT NULL, @@ -1666,28 +1666,28 @@ func (s *testParserSuite) TestDDL(c *C) { PRIMARY KEY (id), CONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION, INDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment '' - ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION,INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 30 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, - {"CREATE TABLE address (\r\nid bigint(20) NOT NULL AUTO_INCREMENT,\r\ncreate_at datetime NOT NULL,\r\ndeleted tinyint(1) NOT NULL,\r\nupdate_at datetime NOT NULL,\r\nversion bigint(20) DEFAULT NULL,\r\naddress varchar(128) NOT NULL,\r\naddress_detail varchar(128) NOT NULL,\r\ncellphone varchar(16) NOT NULL,\r\nlatitude double NOT NULL,\r\nlongitude double NOT NULL,\r\nname varchar(16) NOT NULL,\r\nsex tinyint(1) NOT NULL,\r\nuser_id bigint(20) NOT NULL,\r\nPRIMARY KEY (id),\r\nCONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION,\r\nINDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''\r\n) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;", true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION,INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 30 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0;"}, + ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE UTF8_GENERAL_CI ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;`, true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION,INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 30 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0"}, + {"CREATE TABLE address (\r\nid bigint(20) NOT NULL AUTO_INCREMENT,\r\ncreate_at datetime NOT NULL,\r\ndeleted tinyint(1) NOT NULL,\r\nupdate_at datetime NOT NULL,\r\nversion bigint(20) DEFAULT NULL,\r\naddress varchar(128) NOT NULL,\r\naddress_detail varchar(128) NOT NULL,\r\ncellphone varchar(16) NOT NULL,\r\nlatitude double NOT NULL,\r\nlongitude double NOT NULL,\r\nname varchar(16) NOT NULL,\r\nsex tinyint(1) NOT NULL,\r\nuser_id bigint(20) NOT NULL,\r\nPRIMARY KEY (id),\r\nCONSTRAINT FK_7rod8a71yep5vxasb0ms3osbg FOREIGN KEY (user_id) REFERENCES waimaiqa.user (id) ON DELETE CASCADE ON UPDATE NO ACTION,\r\nINDEX FK_7rod8a71yep5vxasb0ms3osbg (user_id) comment ''\r\n) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=COMPACT COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;", true, "CREATE TABLE `address` (`id` BIGINT(20) NOT NULL AUTO_INCREMENT,`create_at` DATETIME NOT NULL,`deleted` TINYINT(1) NOT NULL,`update_at` DATETIME NOT NULL,`version` BIGINT(20) DEFAULT NULL,`address` VARCHAR(128) NOT NULL,`address_detail` VARCHAR(128) NOT NULL,`cellphone` VARCHAR(16) NOT NULL,`latitude` DOUBLE NOT NULL,`longitude` DOUBLE NOT NULL,`name` VARCHAR(16) NOT NULL,`sex` TINYINT(1) NOT NULL,`user_id` BIGINT(20) NOT NULL,PRIMARY KEY(`id`),CONSTRAINT `FK_7rod8a71yep5vxasb0ms3osbg` FOREIGN KEY (`user_id`) REFERENCES `waimaiqa`.`user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION,INDEX `FK_7rod8a71yep5vxasb0ms3osbg`(`user_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 30 DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI ROW_FORMAT = COMPACT COMMENT = '' CHECKSUM = 0 DELAY_KEY_WRITE = 0"}, // for issue 1802 {`CREATE TABLE t1 ( accout_id int(11) DEFAULT '0', summoner_id int(11) DEFAULT '0', union_name varbinary(52) NOT NULL, union_id int(11) DEFAULT '0', - PRIMARY KEY (union_name)) ENGINE=MyISAM DEFAULT CHARSET=binary;`, true, "CREATE TABLE `t1` (`accout_id` INT(11) DEFAULT '0',`summoner_id` INT(11) DEFAULT '0',`union_name` VARBINARY(52) NOT NULL,`union_id` INT(11) DEFAULT '0',PRIMARY KEY(`union_name`)) ENGINE = MyISAM DEFAULT CHARACTER SET = BINARY;"}, + PRIMARY KEY (union_name)) ENGINE=MyISAM DEFAULT CHARSET=binary;`, true, "CREATE TABLE `t1` (`accout_id` INT(11) DEFAULT '0',`summoner_id` INT(11) DEFAULT '0',`union_name` VARBINARY(52) NOT NULL,`union_id` INT(11) DEFAULT '0',PRIMARY KEY(`union_name`)) ENGINE = MyISAM DEFAULT CHARACTER SET = BINARY"}, // Create table with multiple index options. - {`create table t (c int, index ci (c) USING BTREE COMMENT "123");`, true, "CREATE TABLE `t` (`c` INT,INDEX `ci`(`c`) USING BTREE COMMENT '123');"}, + {`create table t (c int, index ci (c) USING BTREE COMMENT "123");`, true, "CREATE TABLE `t` (`c` INT,INDEX `ci`(`c`) USING BTREE COMMENT '123')"}, // for default value - {"CREATE TABLE sbtest (id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, k integer UNSIGNED DEFAULT '0' NOT NULL, c char(120) DEFAULT '' NOT NULL, pad char(60) DEFAULT '' NOT NULL, PRIMARY KEY (id) )", true, "CREATE TABLE `sbtest` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,`k` INT UNSIGNED DEFAULT '0' NOT NULL,`c` CHAR(120) DEFAULT '' NOT NULL,`pad` CHAR(60) DEFAULT '' NOT NULL,PRIMARY KEY(`id`));"}, - {"create table test (create_date TIMESTAMP NOT NULL COMMENT '创建日期 create date' DEFAULT now());", true, "CREATE TABLE `test` (`create_date` TIMESTAMP NOT NULL COMMENT '创建日期 create date' DEFAULT CURRENT_TIMESTAMP());"}, - {"create table ts (t int, v timestamp(3) default CURRENT_TIMESTAMP(3));", true, "CREATE TABLE `ts` (`t` INT,`v` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP());"}, //TODO: The number yacc in parentheses has not been implemented yet. + {"CREATE TABLE sbtest (id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, k integer UNSIGNED DEFAULT '0' NOT NULL, c char(120) DEFAULT '' NOT NULL, pad char(60) DEFAULT '' NOT NULL, PRIMARY KEY (id) )", true, "CREATE TABLE `sbtest` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,`k` INT UNSIGNED DEFAULT '0' NOT NULL,`c` CHAR(120) DEFAULT '' NOT NULL,`pad` CHAR(60) DEFAULT '' NOT NULL,PRIMARY KEY(`id`))"}, + {"create table test (create_date TIMESTAMP NOT NULL COMMENT '创建日期 create date' DEFAULT now());", true, "CREATE TABLE `test` (`create_date` TIMESTAMP NOT NULL COMMENT '创建日期 create date' DEFAULT CURRENT_TIMESTAMP())"}, + {"create table ts (t int, v timestamp(3) default CURRENT_TIMESTAMP(3));", true, "CREATE TABLE `ts` (`t` INT,`v` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP())"}, //TODO: The number yacc in parentheses has not been implemented yet. // Create table with primary key name. - {"create table if not exists `t` (`id` int not null auto_increment comment '消息ID', primary key `pk_id` (`id`) );", true, "CREATE TABLE IF NOT EXISTS `t` (`id` INT NOT NULL AUTO_INCREMENT COMMENT '消息ID',PRIMARY KEY(`id`));"}, + {"create table if not exists `t` (`id` int not null auto_increment comment '消息ID', primary key `pk_id` (`id`) );", true, "CREATE TABLE IF NOT EXISTS `t` (`id` INT NOT NULL AUTO_INCREMENT COMMENT '消息ID',PRIMARY KEY(`id`))"}, // Create table with like. - {"create table a like b", true, "CREATE TABLE `a` LIKE `b`;"}, - {"create table a (like b)", true, "CREATE TABLE `a` LIKE `b`;"}, - {"create table if not exists a like b", true, "CREATE TABLE IF NOT EXISTS `a` LIKE `b`;"}, - {"create table if not exists a (like b)", true, "CREATE TABLE IF NOT EXISTS `a` LIKE `b`;"}, + {"create table a like b", true, "CREATE TABLE `a` LIKE `b`"}, + {"create table a (like b)", true, "CREATE TABLE `a` LIKE `b`"}, + {"create table if not exists a like b", true, "CREATE TABLE IF NOT EXISTS `a` LIKE `b`"}, + {"create table if not exists a (like b)", true, "CREATE TABLE IF NOT EXISTS `a` LIKE `b`"}, {"create table if not exists a like (b)", false, ""}, {"create table a (t int) like b", false, ""}, {"create table a (t int) like (b)", false, ""}, @@ -1701,18 +1701,18 @@ func (s *testParserSuite) TestDDL(c *C) { {"create table a (m int) replace as (select n as m from b union select n+1 as m from c group by 1 limit 2)", true, ""}, // Create table with no option is valid for parser - {"create table a", true, "CREATE TABLE `a` ;"}, + {"create table a", true, "CREATE TABLE `a` "}, {"create table t (a timestamp default now)", false, ""}, - {"create table t (a timestamp default now())", true, "CREATE TABLE `t` (`a` TIMESTAMP DEFAULT CURRENT_TIMESTAMP());"}, + {"create table t (a timestamp default now())", true, "CREATE TABLE `t` (`a` TIMESTAMP DEFAULT CURRENT_TIMESTAMP())"}, {"create table t (a timestamp default now() on update now)", false, ""}, - {"create table t (a timestamp default now() on update now())", true, "CREATE TABLE `t` (`a` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP());"}, - {"CREATE TABLE t (c TEXT) default CHARACTER SET utf8, default COLLATE utf8_general_ci;", true, "CREATE TABLE `t` (`c` TEXT) DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI;"}, - {"CREATE TABLE t (c TEXT) shard_row_id_bits = 1;", true, "CREATE TABLE `t` (`c` TEXT) SHARD_ROW_ID_BITS = 1;"}, + {"create table t (a timestamp default now() on update now())", true, "CREATE TABLE `t` (`a` TIMESTAMP DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP())"}, + {"CREATE TABLE t (c TEXT) default CHARACTER SET utf8, default COLLATE utf8_general_ci;", true, "CREATE TABLE `t` (`c` TEXT) DEFAULT CHARACTER SET = UTF8 DEFAULT COLLATE = UTF8_GENERAL_CI"}, + {"CREATE TABLE t (c TEXT) shard_row_id_bits = 1;", true, "CREATE TABLE `t` (`c` TEXT) SHARD_ROW_ID_BITS = 1"}, // Create table with ON UPDATE CURRENT_TIMESTAMP(6), specify fraction part. - {"CREATE TABLE IF NOT EXISTS `general_log` (`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),`user_host` mediumtext NOT NULL,`thread_id` bigint(20) unsigned NOT NULL,`server_id` int(10) unsigned NOT NULL,`command_type` varchar(64) NOT NULL,`argument` mediumblob NOT NULL) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'", true, "CREATE TABLE IF NOT EXISTS `general_log` (`event_time` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(),`user_host` MEDIUMTEXT NOT NULL,`thread_id` BIGINT(20) UNSIGNED NOT NULL,`server_id` INT(10) UNSIGNED NOT NULL,`command_type` VARCHAR(64) NOT NULL,`argument` MEDIUMBLOB NOT NULL) ENGINE = CSV DEFAULT CHARACTER SET = UTF8 COMMENT = 'General log';"}, //TODO: The number yacc in parentheses has not been implemented yet. + {"CREATE TABLE IF NOT EXISTS `general_log` (`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),`user_host` mediumtext NOT NULL,`thread_id` bigint(20) unsigned NOT NULL,`server_id` int(10) unsigned NOT NULL,`command_type` varchar(64) NOT NULL,`argument` mediumblob NOT NULL) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'", true, "CREATE TABLE IF NOT EXISTS `general_log` (`event_time` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(),`user_host` MEDIUMTEXT NOT NULL,`thread_id` BIGINT(20) UNSIGNED NOT NULL,`server_id` INT(10) UNSIGNED NOT NULL,`command_type` VARCHAR(64) NOT NULL,`argument` MEDIUMBLOB NOT NULL) ENGINE = CSV DEFAULT CHARACTER SET = UTF8 COMMENT = 'General log'"}, //TODO: The number yacc in parentheses has not been implemented yet. // For reference_definition in column_definition. - {"CREATE TABLE followers ( f1 int NOT NULL REFERENCES user_profiles (uid) );", true, "CREATE TABLE `followers` (`f1` INT NOT NULL REFERENCES `user_profiles`(`uid`));"}, + {"CREATE TABLE followers ( f1 int NOT NULL REFERENCES user_profiles (uid) );", true, "CREATE TABLE `followers` (`f1` INT NOT NULL REFERENCES `user_profiles`(`uid`))"}, // for alter table {"ALTER TABLE t ADD COLUMN (a SMALLINT UNSIGNED)", true, "ALTER TABLE `t` ADD COLUMN (`a` SMALLINT UNSIGNED)"}, @@ -1839,17 +1839,22 @@ func (s *testParserSuite) TestDDL(c *C) { {"ALTER TABLE t ADD UNIQUE KEY ()", false, ""}, // for issue 4538 - {"create table a (process double)", true, "CREATE TABLE `a` (`process` DOUBLE);"}, + {"create table a (process double)", true, "CREATE TABLE `a` (`process` DOUBLE)"}, // for issue 4740 - {"create table t (a int1, b int2, c int3, d int4, e int8)", true, "CREATE TABLE `t` (`a` TINYINT,`b` SMALLINT,`c` MEDIUMINT,`d` INT,`e` BIGINT);"}, + {"create table t (a int1, b int2, c int3, d int4, e int8)", true, "CREATE TABLE `t` (`a` TINYINT,`b` SMALLINT,`c` MEDIUMINT,`d` INT,`e` BIGINT)"}, // for issue 5918 - {"create table t (lv long varchar null)", true, "CREATE TABLE `t` (`lv` MEDIUMTEXT NULL);"}, + {"create table t (lv long varchar null)", true, "CREATE TABLE `t` (`lv` MEDIUMTEXT NULL)"}, // special table name - {"CREATE TABLE cdp_test.`test2-1` (id int(11) DEFAULT NULL,key(id));", true, "CREATE TABLE `cdp_test`.`test2-1` (`id` INT(11) DEFAULT NULL,INDEX(`id`));"}, - {"CREATE TABLE miantiao (`扁豆焖面` INT(11));", true, "CREATE TABLE `miantiao` (`扁豆焖面` INT(11));"}, + {"CREATE TABLE cdp_test.`test2-1` (id int(11) DEFAULT NULL,key(id));", true, "CREATE TABLE `cdp_test`.`test2-1` (`id` INT(11) DEFAULT NULL,INDEX(`id`))"}, + {"CREATE TABLE miantiao (`扁豆焖面` INT(11));", true, "CREATE TABLE `miantiao` (`扁豆焖面` INT(11))"}, + + // for create table select + {"CREATE TABLE bar (m INT) SELECT n FROM foo;", true, "CREATE TABLE `bar` (`m` INT) AS SELECT `n` FROM `foo`"}, + {"CREATE TABLE bar (m INT) IGNORE SELECT n FROM foo;", true, "CREATE TABLE `bar` (`m` INT) IGNORE AS SELECT `n` FROM `foo`"}, + {"CREATE TABLE bar (m INT) REPLACE SELECT n FROM foo;", true, "CREATE TABLE `bar` (`m` INT) REPLACE AS SELECT `n` FROM `foo`"}, } s.RunTest(c, table) } From 7474109418210862795fe8145fe86170b7b35536 Mon Sep 17 00:00:00 2001 From: chendapao Date: Tue, 15 Jan 2019 15:46:17 +0800 Subject: [PATCH 14/15] Add select --- ast/ddl.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ast/ddl.go b/ast/ddl.go index 4bace02eb..08430c1f2 100755 --- a/ast/ddl.go +++ b/ast/ddl.go @@ -729,18 +729,15 @@ func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { } if n.Select != nil { - ctx.WritePlain(" ") - switch n.OnDuplicate { case OnDuplicateCreateTableSelectError: - // nothing output + ctx.WriteKeyWord(" AS ") case OnDuplicateCreateTableSelectIgnore: - ctx.WriteKeyWord("IGNORE ") + ctx.WriteKeyWord(" IGNORE AS ") case OnDuplicateCreateTableSelectReplace: - ctx.WriteKeyWord("REPLACE ") + ctx.WriteKeyWord(" REPLACE AS ") } - ctx.WriteKeyWord("AS ") if err := n.Select.Restore(ctx); err != nil { return errors.Annotate(err, "An error occurred while splicing CreateTableStmt Select") } From d28fdf613b51db134903d7f5ee32eeb87b95ac5c Mon Sep 17 00:00:00 2001 From: leoppro Date: Tue, 15 Jan 2019 15:58:07 +0800 Subject: [PATCH 15/15] Update ddl_test.go --- ast/ddl_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ast/ddl_test.go b/ast/ddl_test.go index 4ad65ded8..4363ba188 100755 --- a/ast/ddl_test.go +++ b/ast/ddl_test.go @@ -159,6 +159,8 @@ func (ts *testDDLSuite) TestDDLConstraintRestore(c *C) { {"CONSTRAINT FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "CONSTRAINT FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, {"CONSTRAINT fk_123 FOREIGN KEY (parent_id(2),hello(4)) REFERENCES parent(id) ON DELETE CASCADE", "CONSTRAINT `fk_123` FOREIGN KEY (`parent_id`(2), `hello`(4)) REFERENCES `parent`(`id`) ON DELETE CASCADE"}, {"CONSTRAINT fk_123 FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "CONSTRAINT `fk_123` FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, + {"FOREIGN KEY (parent_id(2),hello(4)) REFERENCES parent(id) ON DELETE CASCADE", "CONSTRAINT FOREIGN KEY (`parent_id`(2), `hello`(4)) REFERENCES `parent`(`id`) ON DELETE CASCADE"}, + {"FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "CONSTRAINT FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, } extractNodeFunc := func(node Node) Node { return node.(*CreateTableStmt).Constraints[0]