github.com/XiaoMi/Gaea@v1.2.5/parser/ast/ddl_test.go (about) 1 // Copyright 2017 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package ast_test 15 16 import ( 17 . "github.com/pingcap/check" 18 19 . "github.com/XiaoMi/Gaea/parser/ast" 20 ) 21 22 var _ = Suite(&testDDLSuite{}) 23 24 type testDDLSuite struct { 25 } 26 27 func (ts *testDDLSuite) TestDDLVisitorCover(c *C) { 28 ce := &checkExpr{} 29 constraint := &Constraint{Keys: []*IndexColName{{Column: &ColumnName{}}, {Column: &ColumnName{}}}, Refer: &ReferenceDef{}, Option: &IndexOption{}} 30 31 alterTableSpec := &AlterTableSpec{Constraint: constraint, Options: []*TableOption{{}}, NewTable: &TableName{}, NewColumns: []*ColumnDef{{Name: &ColumnName{}}}, OldColumnName: &ColumnName{}, Position: &ColumnPosition{RelativeColumn: &ColumnName{}}} 32 33 stmts := []struct { 34 node Node 35 expectedEnterCnt int 36 expectedLeaveCnt int 37 }{ 38 {&CreateDatabaseStmt{}, 0, 0}, 39 {&DropDatabaseStmt{}, 0, 0}, 40 {&DropIndexStmt{Table: &TableName{}}, 0, 0}, 41 {&DropTableStmt{Tables: []*TableName{{}, {}}}, 0, 0}, 42 {&RenameTableStmt{OldTable: &TableName{}, NewTable: &TableName{}}, 0, 0}, 43 {&TruncateTableStmt{Table: &TableName{}}, 0, 0}, 44 45 // TODO: cover children 46 {&AlterTableStmt{Table: &TableName{}, Specs: []*AlterTableSpec{alterTableSpec}}, 0, 0}, 47 {&CreateIndexStmt{Table: &TableName{}}, 0, 0}, 48 {&CreateTableStmt{Table: &TableName{}, ReferTable: &TableName{}}, 0, 0}, 49 {&CreateViewStmt{ViewName: &TableName{}, Select: &SelectStmt{}}, 0, 0}, 50 {&AlterTableSpec{}, 0, 0}, 51 {&ColumnDef{Name: &ColumnName{}, Options: []*ColumnOption{{Expr: ce}}}, 1, 1}, 52 {&ColumnOption{Expr: ce}, 1, 1}, 53 {&ColumnPosition{RelativeColumn: &ColumnName{}}, 0, 0}, 54 {&Constraint{Keys: []*IndexColName{{Column: &ColumnName{}}, {Column: &ColumnName{}}}, Refer: &ReferenceDef{}, Option: &IndexOption{}}, 0, 0}, 55 {&IndexColName{Column: &ColumnName{}}, 0, 0}, 56 {&ReferenceDef{Table: &TableName{}, IndexColNames: []*IndexColName{{Column: &ColumnName{}}, {Column: &ColumnName{}}}, OnDelete: &OnDeleteOpt{}, OnUpdate: &OnUpdateOpt{}}, 0, 0}, 57 } 58 59 for _, v := range stmts { 60 ce.reset() 61 v.node.Accept(checkVisitor{}) 62 c.Check(ce.enterCnt, Equals, v.expectedEnterCnt) 63 c.Check(ce.leaveCnt, Equals, v.expectedLeaveCnt) 64 v.node.Accept(visitor1{}) 65 } 66 } 67 68 func (ts *testDDLSuite) TestDDLIndexColNameRestore(c *C) { 69 testCases := []NodeRestoreTestCase{ 70 {"world", "`world`"}, 71 {"world(2)", "`world`(2)"}, 72 } 73 extractNodeFunc := func(node Node) Node { 74 return node.(*CreateIndexStmt).IndexColNames[0] 75 } 76 RunNodeRestoreTest(c, testCases, "CREATE INDEX idx ON t (%s) USING HASH", extractNodeFunc) 77 } 78 79 func (ts *testDDLSuite) TestDDLOnDeleteRestore(c *C) { 80 testCases := []NodeRestoreTestCase{ 81 {"on delete restrict", "ON DELETE RESTRICT"}, 82 {"on delete CASCADE", "ON DELETE CASCADE"}, 83 {"on delete SET NULL", "ON DELETE SET NULL"}, 84 {"on delete no action", "ON DELETE NO ACTION"}, 85 } 86 extractNodeFunc := func(node Node) Node { 87 return node.(*CreateTableStmt).Constraints[1].Refer.OnDelete 88 } 89 RunNodeRestoreTest(c, testCases, "CREATE TABLE child (id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) %s)", extractNodeFunc) 90 } 91 92 func (ts *testDDLSuite) TestDDLOnUpdateRestore(c *C) { 93 testCases := []NodeRestoreTestCase{ 94 {"ON UPDATE RESTRICT", "ON UPDATE RESTRICT"}, 95 {"on update CASCADE", "ON UPDATE CASCADE"}, 96 {"on update SET NULL", "ON UPDATE SET NULL"}, 97 {"on update no action", "ON UPDATE NO ACTION"}, 98 } 99 extractNodeFunc := func(node Node) Node { 100 return node.(*CreateTableStmt).Constraints[1].Refer.OnUpdate 101 } 102 RunNodeRestoreTest(c, testCases, "CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE %s )", extractNodeFunc) 103 } 104 105 func (ts *testDDLSuite) TestDDLIndexOption(c *C) { 106 testCases := []NodeRestoreTestCase{ 107 {"key_block_size=16", "KEY_BLOCK_SIZE=16"}, 108 {"USING HASH", "USING HASH"}, 109 {"comment 'hello'", "COMMENT 'hello'"}, 110 {"key_block_size=16 USING HASH", "KEY_BLOCK_SIZE=16 USING HASH"}, 111 {"USING HASH KEY_BLOCK_SIZE=16", "KEY_BLOCK_SIZE=16 USING HASH"}, 112 {"USING HASH COMMENT 'foo'", "USING HASH COMMENT 'foo'"}, 113 {"COMMENT 'foo'", "COMMENT 'foo'"}, 114 {"key_block_size = 32 using hash comment 'hello'", "KEY_BLOCK_SIZE=32 USING HASH COMMENT 'hello'"}, 115 {"key_block_size=32 using btree comment 'hello'", "KEY_BLOCK_SIZE=32 USING BTREE COMMENT 'hello'"}, 116 } 117 extractNodeFunc := func(node Node) Node { 118 return node.(*CreateIndexStmt).IndexOption 119 } 120 RunNodeRestoreTest(c, testCases, "CREATE INDEX idx ON t (a) %s", extractNodeFunc) 121 } 122 123 func (ts *testDDLSuite) TestTableToTableRestore(c *C) { 124 testCases := []NodeRestoreTestCase{ 125 {"t1 to t2", "`t1` TO `t2`"}, 126 } 127 extractNodeFunc := func(node Node) Node { 128 return node.(*RenameTableStmt).TableToTables[0] 129 } 130 RunNodeRestoreTest(c, testCases, "rename table %s", extractNodeFunc) 131 } 132 133 func (ts *testDDLSuite) TestDDLReferenceDefRestore(c *C) { 134 testCases := []NodeRestoreTestCase{ 135 {"REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, 136 {"REFERENCES parent(id) ON DELETE CASCADE", "REFERENCES `parent`(`id`) ON DELETE CASCADE"}, 137 {"REFERENCES parent(id,hello) ON DELETE CASCADE", "REFERENCES `parent`(`id`, `hello`) ON DELETE CASCADE"}, 138 {"REFERENCES parent(id,hello(12)) ON DELETE CASCADE", "REFERENCES `parent`(`id`, `hello`(12)) ON DELETE CASCADE"}, 139 {"REFERENCES parent(id(8),hello(12)) ON DELETE CASCADE", "REFERENCES `parent`(`id`(8), `hello`(12)) ON DELETE CASCADE"}, 140 {"REFERENCES parent(id)", "REFERENCES `parent`(`id`)"}, 141 } 142 extractNodeFunc := func(node Node) Node { 143 return node.(*CreateTableStmt).Constraints[1].Refer 144 } 145 RunNodeRestoreTest(c, testCases, "CREATE TABLE child (id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) %s)", extractNodeFunc) 146 } 147 148 func (ts *testDDLSuite) TestDDLConstraintRestore(c *C) { 149 testCases := []NodeRestoreTestCase{ 150 {"INDEX par_ind (parent_id)", "INDEX `par_ind`(`parent_id`)"}, 151 {"INDEX par_ind (parent_id(6))", "INDEX `par_ind`(`parent_id`(6))"}, 152 {"key par_ind (parent_id)", "INDEX `par_ind`(`parent_id`)"}, 153 {"unique par_ind (parent_id)", "UNIQUE `par_ind`(`parent_id`)"}, 154 {"unique key par_ind (parent_id)", "UNIQUE `par_ind`(`parent_id`)"}, 155 {"unique index par_ind (parent_id)", "UNIQUE `par_ind`(`parent_id`)"}, 156 {"fulltext key full_id (parent_id)", "FULLTEXT `full_id`(`parent_id`)"}, 157 {"fulltext INDEX full_id (parent_id)", "FULLTEXT `full_id`(`parent_id`)"}, 158 {"PRIMARY KEY (id)", "PRIMARY KEY(`id`)"}, 159 {"PRIMARY KEY (id) key_block_size = 32 using hash comment 'hello'", "PRIMARY KEY(`id`) KEY_BLOCK_SIZE=32 USING HASH COMMENT 'hello'"}, 160 {"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"}, 161 {"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"}, 162 {"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"}, 163 {"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"}, 164 {"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"}, 165 {"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"}, 166 } 167 extractNodeFunc := func(node Node) Node { 168 return node.(*CreateTableStmt).Constraints[0] 169 } 170 RunNodeRestoreTest(c, testCases, "CREATE TABLE child (id INT, parent_id INT, %s)", extractNodeFunc) 171 } 172 173 func (ts *testDDLSuite) TestDDLColumnOptionRestore(c *C) { 174 testCases := []NodeRestoreTestCase{ 175 {"primary key", "PRIMARY KEY"}, 176 {"not null", "NOT NULL"}, 177 {"null", "NULL"}, 178 {"auto_increment", "AUTO_INCREMENT"}, 179 {"DEFAULT 10", "DEFAULT 10"}, 180 {"DEFAULT '10'", "DEFAULT '10'"}, 181 {"DEFAULT 'hello'", "DEFAULT 'hello'"}, 182 {"DEFAULT 1.1", "DEFAULT 1.1"}, 183 {"DEFAULT NULL", "DEFAULT NULL"}, 184 {"DEFAULT ''", "DEFAULT ''"}, 185 {"DEFAULT TRUE", "DEFAULT TRUE"}, 186 {"DEFAULT FALSE", "DEFAULT FALSE"}, 187 {"UNIQUE KEY", "UNIQUE KEY"}, 188 {"on update CURRENT_TIMESTAMP", "ON UPDATE CURRENT_TIMESTAMP()"}, 189 {"comment 'hello'", "COMMENT 'hello'"}, 190 {"generated always as(id + 1)", "GENERATED ALWAYS AS(`id`+1) VIRTUAL"}, 191 {"generated always as(id + 1) virtual", "GENERATED ALWAYS AS(`id`+1) VIRTUAL"}, 192 {"generated always as(id + 1) stored", "GENERATED ALWAYS AS(`id`+1) STORED"}, 193 {"REFERENCES parent(id)", "REFERENCES `parent`(`id`)"}, 194 } 195 extractNodeFunc := func(node Node) Node { 196 return node.(*CreateTableStmt).Cols[0].Options[0] 197 } 198 RunNodeRestoreTest(c, testCases, "CREATE TABLE child (id INT %s)", extractNodeFunc) 199 } 200 201 func (ts *testDDLSuite) TestDDLColumnDefRestore(c *C) { 202 testCases := []NodeRestoreTestCase{ 203 // for type 204 {"id json", "`id` JSON"}, 205 {"id time(5)", "`id` TIME(5)"}, 206 {"id int(5) unsigned", "`id` INT(5) UNSIGNED"}, 207 {"id int(5) UNSIGNED ZEROFILL", "`id` INT(5) UNSIGNED ZEROFILL"}, 208 {"id float(12,3)", "`id` FLOAT(12,3)"}, 209 {"id float", "`id` FLOAT"}, 210 {"id double(22,3)", "`id` DOUBLE(22,3)"}, 211 {"id double", "`id` DOUBLE"}, 212 {"id tinyint(4)", "`id` TINYINT(4)"}, 213 {"id smallint(6)", "`id` SMALLINT(6)"}, 214 {"id mediumint(9)", "`id` MEDIUMINT(9)"}, 215 {"id integer(11)", "`id` INT(11)"}, 216 {"id bigint(20)", "`id` BIGINT(20)"}, 217 {"id DATE", "`id` DATE"}, 218 {"id DATETIME", "`id` DATETIME"}, 219 {"id DECIMAL(4,2)", "`id` DECIMAL(4,2)"}, 220 {"id char(1)", "`id` CHAR(1)"}, 221 {"id varchar(10) BINARY", "`id` VARCHAR(10) BINARY"}, 222 {"id binary(1)", "`id` BINARY(1)"}, 223 {"id timestamp(2)", "`id` TIMESTAMP(2)"}, 224 {"id timestamp", "`id` TIMESTAMP"}, 225 {"id datetime(2)", "`id` DATETIME(2)"}, 226 {"id date", "`id` DATE"}, 227 {"id year", "`id` YEAR"}, 228 {"id INT", "`id` INT"}, 229 {"id INT NULL", "`id` INT NULL"}, 230 {"id enum('a','b')", "`id` ENUM('a','b')"}, 231 {"id enum('''a''','''b''')", "`id` ENUM('''a''','''b''')"}, 232 {"id enum('a\\nb','a\\tb','a\\rb')", "`id` ENUM('a\nb','a\tb','a\rb')"}, 233 {"id set('a','b')", "`id` SET('a','b')"}, 234 {"id set('''a''','''b''')", "`id` SET('''a''','''b''')"}, 235 {"id set('a\\nb','a'' \\r\\nb','a\\rb')", "`id` SET('a\nb','a'' \r\nb','a\rb')"}, 236 {`id set("a'\nb","a'b\tc")`, "`id` SET('a''\nb','a''b\tc')"}, 237 {"id TEXT CHARACTER SET UTF8 COLLATE UTF8_UNICODE_G", "`id` TEXT CHARACTER SET UTF8 COLLATE UTF8_UNICODE_G"}, 238 {"id text character set UTF8", "`id` TEXT CHARACTER SET UTF8"}, 239 {"id text charset UTF8", "`id` TEXT CHARACTER SET UTF8"}, 240 {"id varchar(50) collate UTF8MB4_CZECH_CI", "`id` VARCHAR(50) COLLATE UTF8MB4_CZECH_CI"}, 241 {"id varchar(50) collate utf8", "`id` VARCHAR(50) COLLATE utf8"}, 242 {"c1 char(10) character set LATIN1 collate latin1_german1_ci", "`c1` CHAR(10) CHARACTER SET LATIN1 COLLATE latin1_german1_ci"}, 243 244 {"id int(11) PRIMARY KEY", "`id` INT(11) PRIMARY KEY"}, 245 {"id int(11) NOT NULL", "`id` INT(11) NOT NULL"}, 246 {"id INT(11) NULL", "`id` INT(11) NULL"}, 247 {"id INT(11) auto_increment", "`id` INT(11) AUTO_INCREMENT"}, 248 {"id INT(11) DEFAULT 10", "`id` INT(11) DEFAULT 10"}, 249 {"id INT(11) DEFAULT '10'", "`id` INT(11) DEFAULT '10'"}, 250 {"id INT(11) DEFAULT 1.1", "`id` INT(11) DEFAULT 1.1"}, 251 {"id INT(11) UNIQUE KEY", "`id` INT(11) UNIQUE KEY"}, 252 {"id INT(11) on update CURRENT_TIMESTAMP", "`id` INT(11) ON UPDATE CURRENT_TIMESTAMP()"}, 253 {"id INT(11) comment 'hello'", "`id` INT(11) COMMENT 'hello'"}, 254 {"id INT(11) generated always as(id + 1)", "`id` INT(11) GENERATED ALWAYS AS(`id`+1) VIRTUAL"}, 255 {"id INT(11) REFERENCES parent(id)", "`id` INT(11) REFERENCES `parent`(`id`)"}, 256 } 257 extractNodeFunc := func(node Node) Node { 258 return node.(*CreateTableStmt).Cols[0] 259 } 260 RunNodeRestoreTest(c, testCases, "CREATE TABLE t (%s)", extractNodeFunc) 261 } 262 263 func (ts *testDDLSuite) TestDDLTruncateTableStmtRestore(c *C) { 264 testCases := []NodeRestoreTestCase{ 265 {"truncate t1", "TRUNCATE TABLE `t1`"}, 266 {"truncate table t1", "TRUNCATE TABLE `t1`"}, 267 {"truncate a.t1", "TRUNCATE TABLE `a`.`t1`"}, 268 } 269 extractNodeFunc := func(node Node) Node { 270 return node.(*TruncateTableStmt) 271 } 272 RunNodeRestoreTest(c, testCases, "%s", extractNodeFunc) 273 } 274 275 func (ts *testDDLSuite) TestColumnPositionRestore(c *C) { 276 testCases := []NodeRestoreTestCase{ 277 {"", ""}, 278 {"first", "FIRST"}, 279 {"after b", "AFTER `b`"}, 280 } 281 extractNodeFunc := func(node Node) Node { 282 return node.(*AlterTableStmt).Specs[0].Position 283 } 284 RunNodeRestoreTest(c, testCases, "alter table t add column a varchar(255) %s", extractNodeFunc) 285 } 286 287 func (ts *testDDLSuite) TestAlterTableSpecRestore(c *C) { 288 testCases := []NodeRestoreTestCase{ 289 {"ENGINE innodb", "ENGINE = innodb"}, 290 {"ENGINE = innodb", "ENGINE = innodb"}, 291 {"ENGINE = 'innodb'", "ENGINE = innodb"}, 292 {"DEFAULT CHARACTER SET utf8", "DEFAULT CHARACTER SET = UTF8"}, 293 {"DEFAULT CHARACTER SET = utf8", "DEFAULT CHARACTER SET = UTF8"}, 294 {"DEFAULT CHARSET utf8", "DEFAULT CHARACTER SET = UTF8"}, 295 {"DEFAULT CHARSET = utf8", "DEFAULT CHARACTER SET = UTF8"}, 296 {"DEFAULT COLLATE utf8_bin", "DEFAULT COLLATE = UTF8_BIN"}, 297 {"DEFAULT COLLATE = utf8_bin", "DEFAULT COLLATE = UTF8_BIN"}, 298 {"AUTO_INCREMENT 3", "AUTO_INCREMENT = 3"}, 299 {"AUTO_INCREMENT = 6", "AUTO_INCREMENT = 6"}, 300 {"COMMENT ''", "COMMENT = ''"}, 301 {"COMMENT 'system role'", "COMMENT = 'system role'"}, 302 {"COMMENT = 'system role'", "COMMENT = 'system role'"}, 303 {"AVG_ROW_LENGTH 12", "AVG_ROW_LENGTH = 12"}, 304 {"AVG_ROW_LENGTH = 6", "AVG_ROW_LENGTH = 6"}, 305 {"connection 'abc'", "CONNECTION = 'abc'"}, 306 {"CONNECTION = 'abc'", "CONNECTION = 'abc'"}, 307 {"checksum 1", "CHECKSUM = 1"}, 308 {"checksum = 0", "CHECKSUM = 0"}, 309 {"PASSWORD '123456'", "PASSWORD = '123456'"}, 310 {"PASSWORD = ''", "PASSWORD = ''"}, 311 {"compression 'NONE'", "COMPRESSION = 'NONE'"}, 312 {"compression = 'lz4'", "COMPRESSION = 'lz4'"}, 313 {"key_block_size 1024", "KEY_BLOCK_SIZE = 1024"}, 314 {"KEY_BLOCK_SIZE = 1024", "KEY_BLOCK_SIZE = 1024"}, 315 {"max_rows 1000", "MAX_ROWS = 1000"}, 316 {"max_rows = 1000", "MAX_ROWS = 1000"}, 317 {"min_rows 1000", "MIN_ROWS = 1000"}, 318 {"MIN_ROWS = 1000", "MIN_ROWS = 1000"}, 319 {"DELAY_KEY_WRITE 1", "DELAY_KEY_WRITE = 1"}, 320 {"DELAY_KEY_WRITE = 1000", "DELAY_KEY_WRITE = 1000"}, 321 {"ROW_FORMAT default", "ROW_FORMAT = DEFAULT"}, 322 {"ROW_FORMAT = default", "ROW_FORMAT = DEFAULT"}, 323 {"ROW_FORMAT = fixed", "ROW_FORMAT = FIXED"}, 324 {"ROW_FORMAT = compressed", "ROW_FORMAT = COMPRESSED"}, 325 {"ROW_FORMAT = compact", "ROW_FORMAT = COMPACT"}, 326 {"ROW_FORMAT = redundant", "ROW_FORMAT = REDUNDANT"}, 327 {"ROW_FORMAT = dynamic", "ROW_FORMAT = DYNAMIC"}, 328 {"shard_row_id_bits 1", "SHARD_ROW_ID_BITS = 1"}, 329 {"shard_row_id_bits = 1", "SHARD_ROW_ID_BITS = 1"}, 330 {"CONVERT TO CHARACTER SET utf8", "DEFAULT CHARACTER SET = UTF8"}, 331 {"CONVERT TO CHARSET utf8", "DEFAULT CHARACTER SET = UTF8"}, 332 {"CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin", "CONVERT TO CHARACTER SET UTF8 COLLATE UTF8_BIN"}, 333 {"CONVERT TO CHARSET utf8 COLLATE utf8_bin", "CONVERT TO CHARACTER SET UTF8 COLLATE UTF8_BIN"}, 334 {"ADD COLUMN (a SMALLINT UNSIGNED)", "ADD COLUMN (`a` SMALLINT UNSIGNED)"}, 335 {"ADD COLUMN (a SMALLINT UNSIGNED, b varchar(255))", "ADD COLUMN (`a` SMALLINT UNSIGNED, `b` VARCHAR(255))"}, 336 {"ADD COLUMN a SMALLINT UNSIGNED", "ADD COLUMN `a` SMALLINT UNSIGNED"}, 337 {"ADD COLUMN a SMALLINT UNSIGNED FIRST", "ADD COLUMN `a` SMALLINT UNSIGNED FIRST"}, 338 {"ADD COLUMN a SMALLINT UNSIGNED AFTER b", "ADD COLUMN `a` SMALLINT UNSIGNED AFTER `b`"}, 339 {"ADD COLUMN name mediumtext CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci NOT NULL", "ADD COLUMN `name` MEDIUMTEXT CHARACTER SET UTF8MB4 COLLATE utf8mb4_unicode_ci NOT NULL"}, 340 {"ADD CONSTRAINT INDEX par_ind (parent_id)", "ADD INDEX `par_ind`(`parent_id`)"}, 341 {"ADD CONSTRAINT INDEX par_ind (parent_id(6))", "ADD INDEX `par_ind`(`parent_id`(6))"}, 342 {"ADD CONSTRAINT key par_ind (parent_id)", "ADD INDEX `par_ind`(`parent_id`)"}, 343 {"ADD CONSTRAINT unique par_ind (parent_id)", "ADD UNIQUE `par_ind`(`parent_id`)"}, 344 {"ADD CONSTRAINT unique key par_ind (parent_id)", "ADD UNIQUE `par_ind`(`parent_id`)"}, 345 {"ADD CONSTRAINT unique index par_ind (parent_id)", "ADD UNIQUE `par_ind`(`parent_id`)"}, 346 {"ADD CONSTRAINT fulltext key full_id (parent_id)", "ADD FULLTEXT `full_id`(`parent_id`)"}, 347 {"ADD CONSTRAINT fulltext INDEX full_id (parent_id)", "ADD FULLTEXT `full_id`(`parent_id`)"}, 348 {"ADD CONSTRAINT PRIMARY KEY (id)", "ADD PRIMARY KEY(`id`)"}, 349 {"ADD CONSTRAINT PRIMARY KEY (id) key_block_size = 32 using hash comment 'hello'", "ADD PRIMARY KEY(`id`) KEY_BLOCK_SIZE=32 USING HASH COMMENT 'hello'"}, 350 {"ADD CONSTRAINT FOREIGN KEY (parent_id(2),hello(4)) REFERENCES parent(id) ON DELETE CASCADE", "ADD CONSTRAINT FOREIGN KEY (`parent_id`(2), `hello`(4)) REFERENCES `parent`(`id`) ON DELETE CASCADE"}, 351 {"ADD CONSTRAINT FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "ADD CONSTRAINT FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, 352 {"ADD CONSTRAINT fk_123 FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE RESTRICT", "ADD CONSTRAINT `fk_123` FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT"}, 353 {"DROP COLUMN a", "DROP COLUMN `a`"}, 354 {"DROP COLUMN a RESTRICT", "DROP COLUMN `a`"}, 355 {"DROP COLUMN a CASCADE", "DROP COLUMN `a`"}, 356 {"DROP PRIMARY KEY", "DROP PRIMARY KEY"}, 357 {"drop index a", "DROP INDEX `a`"}, 358 {"drop key a", "DROP INDEX `a`"}, 359 {"drop FOREIGN key a", "DROP FOREIGN KEY `a`"}, 360 {"MODIFY column a varchar(255)", "MODIFY COLUMN `a` VARCHAR(255)"}, 361 {"modify COLUMN a varchar(255) FIRST", "MODIFY COLUMN `a` VARCHAR(255) FIRST"}, 362 {"modify COLUMN a varchar(255) AFTER b", "MODIFY COLUMN `a` VARCHAR(255) AFTER `b`"}, 363 {"change column a b VARCHAR(255)", "CHANGE COLUMN `a` `b` VARCHAR(255)"}, 364 {"change COLUMN a b varchar(255) CHARACTER SET UTF8 BINARY", "CHANGE COLUMN `a` `b` VARCHAR(255) BINARY CHARACTER SET UTF8"}, 365 {"CHANGE column a b varchar(255) FIRST", "CHANGE COLUMN `a` `b` VARCHAR(255) FIRST"}, 366 {"change COLUMN a b varchar(255) AFTER c", "CHANGE COLUMN `a` `b` VARCHAR(255) AFTER `c`"}, 367 {"RENAME db1.t1", "RENAME AS `db1`.`t1`"}, 368 {"RENAME to db1.t1", "RENAME AS `db1`.`t1`"}, 369 {"RENAME as t1", "RENAME AS `t1`"}, 370 {"ALTER a SET DEFAULT 1", "ALTER COLUMN `a` SET DEFAULT 1"}, 371 {"ALTER a DROP DEFAULT", "ALTER COLUMN `a` DROP DEFAULT"}, 372 {"ALTER COLUMN a SET DEFAULT 1", "ALTER COLUMN `a` SET DEFAULT 1"}, 373 {"ALTER COLUMN a DROP DEFAULT", "ALTER COLUMN `a` DROP DEFAULT"}, 374 {"LOCK=NONE", "LOCK = NONE"}, 375 {"LOCK=DEFAULT", "LOCK = DEFAULT"}, 376 {"LOCK=SHARED", "LOCK = SHARED"}, 377 {"LOCK=EXCLUSIVE", "LOCK = EXCLUSIVE"}, 378 {"RENAME KEY a TO b", "RENAME INDEX `a` TO `b`"}, 379 {"RENAME INDEX a TO b", "RENAME INDEX `a` TO `b`"}, 380 {"ADD PARTITION", "ADD PARTITION"}, 381 {"ADD PARTITION ( PARTITION P1 VALUES LESS THAN (2010))", "ADD PARTITION (PARTITION `P1` VALUES LESS THAN (2010))"}, 382 {"ADD PARTITION ( PARTITION P2 VALUES LESS THAN MAXVALUE)", "ADD PARTITION (PARTITION `P2` VALUES LESS THAN (MAXVALUE))"}, 383 {"ADD PARTITION (\nPARTITION P1 VALUES LESS THAN (2010),\nPARTITION P2 VALUES LESS THAN (2015),\nPARTITION P3 VALUES LESS THAN MAXVALUE)", "ADD PARTITION (PARTITION `P1` VALUES LESS THAN (2010), PARTITION `P2` VALUES LESS THAN (2015), PARTITION `P3` VALUES LESS THAN (MAXVALUE))"}, 384 {"ADD PARTITION (PARTITION `p5` VALUES LESS THAN (2010) COMMENT 'AP_START \\' AP_END')", "ADD PARTITION (PARTITION `p5` VALUES LESS THAN (2010) COMMENT = 'AP_START '' AP_END')"}, 385 {"ADD PARTITION (PARTITION `p5` VALUES LESS THAN (2010) COMMENT = 'xxx')", "ADD PARTITION (PARTITION `p5` VALUES LESS THAN (2010) COMMENT = 'xxx')"}, 386 {"coalesce partition 3", "COALESCE PARTITION 3"}, 387 {"drop partition p1", "DROP PARTITION `p1`"}, 388 {"TRUNCATE PARTITION p0", "TRUNCATE PARTITION `p0`"}, 389 } 390 extractNodeFunc := func(node Node) Node { 391 return node.(*AlterTableStmt).Specs[0] 392 } 393 RunNodeRestoreTest(c, testCases, "ALTER TABLE t %s", extractNodeFunc) 394 }