github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/parser/common_test.go (about)

     1  // Copyright 2019 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 parser
    15  
    16  import (
    17  	"testing"
    18  
    19  	"github.com/pingcap/tidb/pkg/parser"
    20  	"github.com/pingcap/tidb/pkg/util/filter"
    21  	"github.com/pingcap/tiflow/dm/pkg/conn"
    22  	"github.com/pingcap/tiflow/dm/pkg/terror"
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  type testCase struct {
    27  	sql                string
    28  	expectedSQLs       []string
    29  	expectedTableNames [][]*filter.Table
    30  	targetTableNames   [][]*filter.Table
    31  	targetSQLs         []string
    32  }
    33  
    34  var testCases = []testCase{
    35  	{
    36  		"create table `t1` (`id` int, `student_id` int, primary key (`id`), foreign key (`student_id`) references `t2`(`id`))",
    37  		[]string{"CREATE TABLE IF NOT EXISTS `test`.`t1` (`id` INT,`student_id` INT,PRIMARY KEY(`id`),CONSTRAINT FOREIGN KEY (`student_id`) REFERENCES `t2`(`id`))"},
    38  		[][]*filter.Table{{genTableName("test", "t1")}},
    39  		[][]*filter.Table{{genTableName("xtest", "t1")}},
    40  		[]string{"CREATE TABLE IF NOT EXISTS `xtest`.`t1` (`id` INT,`student_id` INT,PRIMARY KEY(`id`),CONSTRAINT FOREIGN KEY (`student_id`) REFERENCES `t2`(`id`))"},
    41  	},
    42  	{
    43  		"create schema `s1`",
    44  		[]string{"CREATE DATABASE IF NOT EXISTS `s1`"},
    45  		[][]*filter.Table{{genTableName("s1", "")}},
    46  		[][]*filter.Table{{genTableName("xs1", "")}},
    47  		[]string{"CREATE DATABASE IF NOT EXISTS `xs1`"},
    48  	},
    49  	{
    50  		"create schema if not exists `s1`",
    51  		[]string{"CREATE DATABASE IF NOT EXISTS `s1`"},
    52  		[][]*filter.Table{{genTableName("s1", "")}},
    53  		[][]*filter.Table{{genTableName("xs1", "")}},
    54  		[]string{"CREATE DATABASE IF NOT EXISTS `xs1`"},
    55  	},
    56  	{
    57  		"drop schema `s1`",
    58  		[]string{"DROP DATABASE IF EXISTS `s1`"},
    59  		[][]*filter.Table{{genTableName("s1", "")}},
    60  		[][]*filter.Table{{genTableName("xs1", "")}},
    61  		[]string{"DROP DATABASE IF EXISTS `xs1`"},
    62  	},
    63  	{
    64  		"drop schema if exists `s1`",
    65  		[]string{"DROP DATABASE IF EXISTS `s1`"},
    66  		[][]*filter.Table{{genTableName("s1", "")}},
    67  		[][]*filter.Table{{genTableName("xs1", "")}},
    68  		[]string{"DROP DATABASE IF EXISTS `xs1`"},
    69  	},
    70  	{
    71  		"drop table `Ss1`.`tT1`",
    72  		[]string{"DROP TABLE IF EXISTS `Ss1`.`tT1`"},
    73  		[][]*filter.Table{{genTableName("Ss1", "tT1")}},
    74  		[][]*filter.Table{{genTableName("xSs1", "xtT1")}},
    75  		[]string{"DROP TABLE IF EXISTS `xSs1`.`xtT1`"},
    76  	},
    77  	{
    78  		"drop table `s1`.`t1`, `s2`.`t2`",
    79  		[]string{"DROP TABLE IF EXISTS `s1`.`t1`", "DROP TABLE IF EXISTS `s2`.`t2`"},
    80  		[][]*filter.Table{{genTableName("s1", "t1")}, {genTableName("s2", "t2")}},
    81  		[][]*filter.Table{{genTableName("xs1", "xt1")}, {genTableName("xs2", "xt2")}},
    82  		[]string{"DROP TABLE IF EXISTS `xs1`.`xt1`", "DROP TABLE IF EXISTS `xs2`.`xt2`"},
    83  	},
    84  	{
    85  		"drop table `s1`.`t1`, `s2`.`t2`, `xx`",
    86  		[]string{"DROP TABLE IF EXISTS `s1`.`t1`", "DROP TABLE IF EXISTS `s2`.`t2`", "DROP TABLE IF EXISTS `test`.`xx`"},
    87  		[][]*filter.Table{{genTableName("s1", "t1")}, {genTableName("s2", "t2")}, {genTableName("test", "xx")}},
    88  		[][]*filter.Table{{genTableName("xs1", "xt1")}, {genTableName("xs2", "xt2")}, {genTableName("xtest", "xxx")}},
    89  		[]string{"DROP TABLE IF EXISTS `xs1`.`xt1`", "DROP TABLE IF EXISTS `xs2`.`xt2`", "DROP TABLE IF EXISTS `xtest`.`xxx`"},
    90  	},
    91  	{
    92  		"create table `s1`.`t1` (id int)",
    93  		[]string{"CREATE TABLE IF NOT EXISTS `s1`.`t1` (`id` INT)"},
    94  		[][]*filter.Table{{genTableName("s1", "t1")}},
    95  		[][]*filter.Table{{genTableName("xs1", "xt1")}},
    96  		[]string{"CREATE TABLE IF NOT EXISTS `xs1`.`xt1` (`id` INT)"},
    97  	},
    98  	{
    99  		"create table `t1` (id int)",
   100  		[]string{"CREATE TABLE IF NOT EXISTS `test`.`t1` (`id` INT)"},
   101  		[][]*filter.Table{{genTableName("test", "t1")}},
   102  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   103  		[]string{"CREATE TABLE IF NOT EXISTS `xtest`.`xt1` (`id` INT)"},
   104  	},
   105  	{
   106  		"create table `s1` (c int default '0')",
   107  		[]string{"CREATE TABLE IF NOT EXISTS `test`.`s1` (`c` INT DEFAULT '0')"},
   108  		[][]*filter.Table{{genTableName("test", "s1")}},
   109  		[][]*filter.Table{{genTableName("xtest", "xs1")}},
   110  		[]string{"CREATE TABLE IF NOT EXISTS `xtest`.`xs1` (`c` INT DEFAULT '0')"},
   111  	},
   112  	{
   113  		"create table `t1` like `t2`",
   114  		[]string{"CREATE TABLE IF NOT EXISTS `test`.`t1` LIKE `test`.`t2`"},
   115  		[][]*filter.Table{{genTableName("test", "t1"), genTableName("test", "t2")}},
   116  		[][]*filter.Table{{genTableName("xtest", "xt1"), genTableName("xtest", "xt2")}},
   117  		[]string{"CREATE TABLE IF NOT EXISTS `xtest`.`xt1` LIKE `xtest`.`xt2`"},
   118  	},
   119  	{
   120  		"create table `s1`.`t1` like `t2`",
   121  		[]string{"CREATE TABLE IF NOT EXISTS `s1`.`t1` LIKE `test`.`t2`"},
   122  		[][]*filter.Table{{genTableName("s1", "t1"), genTableName("test", "t2")}},
   123  		[][]*filter.Table{{genTableName("xs1", "xt1"), genTableName("xtest", "xt2")}},
   124  		[]string{"CREATE TABLE IF NOT EXISTS `xs1`.`xt1` LIKE `xtest`.`xt2`"},
   125  	},
   126  	{
   127  		"create table `t1` like `xx`.`t2`",
   128  		[]string{"CREATE TABLE IF NOT EXISTS `test`.`t1` LIKE `xx`.`t2`"},
   129  		[][]*filter.Table{{genTableName("test", "t1"), genTableName("xx", "t2")}},
   130  		[][]*filter.Table{{genTableName("xtest", "xt1"), genTableName("xxx", "xt2")}},
   131  		[]string{"CREATE TABLE IF NOT EXISTS `xtest`.`xt1` LIKE `xxx`.`xt2`"},
   132  	},
   133  	{
   134  		"truncate table `t1`",
   135  		[]string{"TRUNCATE TABLE `test`.`t1`"},
   136  		[][]*filter.Table{{genTableName("test", "t1")}},
   137  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   138  		[]string{"TRUNCATE TABLE `xtest`.`xt1`"},
   139  	},
   140  	{
   141  		"truncate table `s1`.`t1`",
   142  		[]string{"TRUNCATE TABLE `s1`.`t1`"},
   143  		[][]*filter.Table{{genTableName("s1", "t1")}},
   144  		[][]*filter.Table{{genTableName("xs1", "xt1")}},
   145  		[]string{"TRUNCATE TABLE `xs1`.`xt1`"},
   146  	},
   147  	{
   148  		"rename table `s1`.`t1` to `s2`.`t2`",
   149  		[]string{"RENAME TABLE `s1`.`t1` TO `s2`.`t2`"},
   150  		[][]*filter.Table{{genTableName("s1", "t1"), genTableName("s2", "t2")}},
   151  		[][]*filter.Table{{genTableName("xs1", "xt1"), genTableName("xs2", "xt2")}},
   152  		[]string{"RENAME TABLE `xs1`.`xt1` TO `xs2`.`xt2`"},
   153  	},
   154  	{
   155  		"rename table `t1` to `t2`, `s1`.`t1` to `t2`",
   156  		[]string{"RENAME TABLE `test`.`t1` TO `test`.`t2`", "RENAME TABLE `s1`.`t1` TO `test`.`t2`"},
   157  		[][]*filter.Table{{genTableName("test", "t1"), genTableName("test", "t2")}, {genTableName("s1", "t1"), genTableName("test", "t2")}},
   158  		[][]*filter.Table{{genTableName("xtest", "xt1"), genTableName("xtest", "xt2")}, {genTableName("xs1", "xt1"), genTableName("xtest", "xt2")}},
   159  		[]string{"RENAME TABLE `xtest`.`xt1` TO `xtest`.`xt2`", "RENAME TABLE `xs1`.`xt1` TO `xtest`.`xt2`"},
   160  	},
   161  	{
   162  		"drop index i1 on `s1`.`t1`",
   163  		[]string{"DROP INDEX /*T! IF EXISTS  */`i1` ON `s1`.`t1`"},
   164  		[][]*filter.Table{{genTableName("s1", "t1")}},
   165  		[][]*filter.Table{{genTableName("xs1", "xt1")}},
   166  		[]string{"DROP INDEX /*T! IF EXISTS  */`i1` ON `xs1`.`xt1`"},
   167  	},
   168  	{
   169  		"drop index i1 on `t1`",
   170  		[]string{"DROP INDEX /*T! IF EXISTS  */`i1` ON `test`.`t1`"},
   171  		[][]*filter.Table{{genTableName("test", "t1")}},
   172  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   173  		[]string{"DROP INDEX /*T! IF EXISTS  */`i1` ON `xtest`.`xt1`"},
   174  	},
   175  	{
   176  		"create index i1 on `t1`(`c1`)",
   177  		[]string{"CREATE INDEX `i1` ON `test`.`t1` (`c1`)"},
   178  		[][]*filter.Table{{genTableName("test", "t1")}},
   179  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   180  		[]string{"CREATE INDEX `i1` ON `xtest`.`xt1` (`c1`)"},
   181  	},
   182  	{
   183  		"create index i1 on `s1`.`t1`(`c1`)",
   184  		[]string{"CREATE INDEX `i1` ON `s1`.`t1` (`c1`)"},
   185  		[][]*filter.Table{{genTableName("s1", "t1")}},
   186  		[][]*filter.Table{{genTableName("xs1", "xt1")}},
   187  		[]string{"CREATE INDEX `i1` ON `xs1`.`xt1` (`c1`)"},
   188  	},
   189  	{
   190  		"alter table `t1` add column c1 int, drop column c2",
   191  		[]string{"ALTER TABLE `test`.`t1` ADD COLUMN `c1` INT", "ALTER TABLE `test`.`t1` DROP COLUMN `c2`"},
   192  		[][]*filter.Table{{genTableName("test", "t1")}, {genTableName("test", "t1")}},
   193  		[][]*filter.Table{{genTableName("xtest", "xt1")}, {genTableName("xtest", "xt1")}},
   194  		[]string{"ALTER TABLE `xtest`.`xt1` ADD COLUMN `c1` INT", "ALTER TABLE `xtest`.`xt1` DROP COLUMN `c2`"},
   195  	},
   196  	{
   197  		"alter table `s1`.`t1` add column c1 int, rename to `t2`, drop column c2",
   198  		[]string{"ALTER TABLE `s1`.`t1` ADD COLUMN `c1` INT", "ALTER TABLE `s1`.`t1` RENAME AS `test`.`t2`", "ALTER TABLE `test`.`t2` DROP COLUMN `c2`"},
   199  		[][]*filter.Table{{genTableName("s1", "t1")}, {genTableName("s1", "t1"), genTableName("test", "t2")}, {genTableName("test", "t2")}},
   200  		[][]*filter.Table{{genTableName("xs1", "xt1")}, {genTableName("xs1", "xt1"), genTableName("xtest", "xt2")}, {genTableName("xtest", "xt2")}},
   201  		[]string{"ALTER TABLE `xs1`.`xt1` ADD COLUMN `c1` INT", "ALTER TABLE `xs1`.`xt1` RENAME AS `xtest`.`xt2`", "ALTER TABLE `xtest`.`xt2` DROP COLUMN `c2`"},
   202  	},
   203  	{
   204  		"alter table `s1`.`t1` add column c1 int, rename to `xx`.`t2`, drop column c2",
   205  		[]string{"ALTER TABLE `s1`.`t1` ADD COLUMN `c1` INT", "ALTER TABLE `s1`.`t1` RENAME AS `xx`.`t2`", "ALTER TABLE `xx`.`t2` DROP COLUMN `c2`"},
   206  		[][]*filter.Table{{genTableName("s1", "t1")}, {genTableName("s1", "t1"), genTableName("xx", "t2")}, {genTableName("xx", "t2")}},
   207  		[][]*filter.Table{{genTableName("xs1", "xt1")}, {genTableName("xs1", "xt1"), genTableName("xxx", "xt2")}, {genTableName("xxx", "xt2")}},
   208  		[]string{"ALTER TABLE `xs1`.`xt1` ADD COLUMN `c1` INT", "ALTER TABLE `xs1`.`xt1` RENAME AS `xxx`.`xt2`", "ALTER TABLE `xxx`.`xt2` DROP COLUMN `c2`"},
   209  	},
   210  	{
   211  		"alter table `t1` add column if not exists c1 int",
   212  		[]string{"ALTER TABLE `test`.`t1` ADD COLUMN IF NOT EXISTS `c1` INT"},
   213  		[][]*filter.Table{{genTableName("test", "t1")}},
   214  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   215  		[]string{"ALTER TABLE `xtest`.`xt1` ADD COLUMN IF NOT EXISTS `c1` INT"},
   216  	},
   217  	{
   218  		"alter table `t1` add index if not exists (a) using btree comment 'a'",
   219  		[]string{"ALTER TABLE `test`.`t1` ADD INDEX IF NOT EXISTS(`a`) USING BTREE COMMENT 'a'"},
   220  		[][]*filter.Table{{genTableName("test", "t1")}},
   221  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   222  		[]string{"ALTER TABLE `xtest`.`xt1` ADD INDEX IF NOT EXISTS(`a`) USING BTREE COMMENT 'a'"},
   223  	},
   224  	{
   225  		"alter table `t1` add constraint fk_t2_id foreign key if not exists (t2_id) references t2(id)",
   226  		[]string{"ALTER TABLE `test`.`t1` ADD CONSTRAINT `fk_t2_id` FOREIGN KEY IF NOT EXISTS (`t2_id`) REFERENCES `t2`(`id`)"},
   227  		[][]*filter.Table{{genTableName("test", "t1")}},
   228  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   229  		[]string{"ALTER TABLE `xtest`.`xt1` ADD CONSTRAINT `fk_t2_id` FOREIGN KEY IF NOT EXISTS (`t2_id`) REFERENCES `t2`(`id`)"},
   230  	},
   231  	{
   232  		"create index if not exists i1 on `t1`(`c1`)",
   233  		[]string{"CREATE INDEX IF NOT EXISTS `i1` ON `test`.`t1` (`c1`)"},
   234  		[][]*filter.Table{{genTableName("test", "t1")}},
   235  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   236  		[]string{"CREATE INDEX IF NOT EXISTS `i1` ON `xtest`.`xt1` (`c1`)"},
   237  	},
   238  	{
   239  		"alter table `t1` add partition if not exists ( partition p2 values less than maxvalue)",
   240  		[]string{"ALTER TABLE `test`.`t1` ADD PARTITION IF NOT EXISTS (PARTITION `p2` VALUES LESS THAN (MAXVALUE))"},
   241  		[][]*filter.Table{{genTableName("test", "t1")}},
   242  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   243  		[]string{"ALTER TABLE `xtest`.`xt1` ADD PARTITION IF NOT EXISTS (PARTITION `p2` VALUES LESS THAN (MAXVALUE))"},
   244  	},
   245  	{
   246  		"alter table `t1` drop column if exists c2",
   247  		[]string{"ALTER TABLE `test`.`t1` DROP COLUMN IF EXISTS `c2`"},
   248  		[][]*filter.Table{{genTableName("test", "t1")}},
   249  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   250  		[]string{"ALTER TABLE `xtest`.`xt1` DROP COLUMN IF EXISTS `c2`"},
   251  	},
   252  	{
   253  		"alter table `t1` change column if exists a b varchar(255)",
   254  		[]string{"ALTER TABLE `test`.`t1` CHANGE COLUMN IF EXISTS `a` `b` VARCHAR(255)"},
   255  		[][]*filter.Table{{genTableName("test", "t1")}},
   256  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   257  		[]string{"ALTER TABLE `xtest`.`xt1` CHANGE COLUMN IF EXISTS `a` `b` VARCHAR(255)"},
   258  	},
   259  	{
   260  		"alter table `t1` modify column if exists a varchar(255)",
   261  		[]string{"ALTER TABLE `test`.`t1` MODIFY COLUMN IF EXISTS `a` VARCHAR(255)"},
   262  		[][]*filter.Table{{genTableName("test", "t1")}},
   263  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   264  		[]string{"ALTER TABLE `xtest`.`xt1` MODIFY COLUMN IF EXISTS `a` VARCHAR(255)"},
   265  	},
   266  	{
   267  		"alter table `t1` drop index if exists i1",
   268  		[]string{"ALTER TABLE `test`.`t1` DROP INDEX IF EXISTS `i1`"},
   269  		[][]*filter.Table{{genTableName("test", "t1")}},
   270  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   271  		[]string{"ALTER TABLE `xtest`.`xt1` DROP INDEX IF EXISTS `i1`"},
   272  	},
   273  	{
   274  		"alter table `t1` drop foreign key if exists fk_t2_id",
   275  		[]string{"ALTER TABLE `test`.`t1` DROP FOREIGN KEY IF EXISTS `fk_t2_id`"},
   276  		[][]*filter.Table{{genTableName("test", "t1")}},
   277  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   278  		[]string{"ALTER TABLE `xtest`.`xt1` DROP FOREIGN KEY IF EXISTS `fk_t2_id`"},
   279  	},
   280  	{
   281  		"alter table `t1` drop partition if exists p2",
   282  		[]string{"ALTER TABLE `test`.`t1` DROP PARTITION IF EXISTS `p2`"},
   283  		[][]*filter.Table{{genTableName("test", "t1")}},
   284  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   285  		[]string{"ALTER TABLE `xtest`.`xt1` DROP PARTITION IF EXISTS `p2`"},
   286  	},
   287  	{
   288  		"alter table `t1` partition by hash(a)",
   289  		[]string{"ALTER TABLE `test`.`t1` PARTITION BY HASH (`a`) PARTITIONS 1"},
   290  		[][]*filter.Table{{genTableName("test", "t1")}},
   291  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   292  		[]string{"ALTER TABLE `xtest`.`xt1` PARTITION BY HASH (`a`) PARTITIONS 1"},
   293  	},
   294  	{
   295  		"alter table `t1` partition by key(a)",
   296  		[]string{"ALTER TABLE `test`.`t1` PARTITION BY KEY (`a`) PARTITIONS 1"},
   297  		[][]*filter.Table{{genTableName("test", "t1")}},
   298  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   299  		[]string{"ALTER TABLE `xtest`.`xt1` PARTITION BY KEY (`a`) PARTITIONS 1"},
   300  	},
   301  	{
   302  		"alter table `t1` partition by range(a) (partition x values less than (75))",
   303  		[]string{"ALTER TABLE `test`.`t1` PARTITION BY RANGE (`a`) (PARTITION `x` VALUES LESS THAN (75))"},
   304  		[][]*filter.Table{{genTableName("test", "t1")}},
   305  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   306  		[]string{"ALTER TABLE `xtest`.`xt1` PARTITION BY RANGE (`a`) (PARTITION `x` VALUES LESS THAN (75))"},
   307  	},
   308  	{
   309  		"alter table `t1` partition by list columns (a, b) (partition x values in ((10, 20)))",
   310  		[]string{"ALTER TABLE `test`.`t1` PARTITION BY LIST COLUMNS (`a`,`b`) (PARTITION `x` VALUES IN ((10, 20)))"},
   311  		[][]*filter.Table{{genTableName("test", "t1")}},
   312  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   313  		[]string{"ALTER TABLE `xtest`.`xt1` PARTITION BY LIST COLUMNS (`a`,`b`) (PARTITION `x` VALUES IN ((10, 20)))"},
   314  	},
   315  	{
   316  		"alter table `t1` partition by list (a) (partition x default)",
   317  		[]string{"ALTER TABLE `test`.`t1` PARTITION BY LIST (`a`) (PARTITION `x` DEFAULT)"},
   318  		[][]*filter.Table{{genTableName("test", "t1")}},
   319  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   320  		[]string{"ALTER TABLE `xtest`.`xt1` PARTITION BY LIST (`a`) (PARTITION `x` DEFAULT)"},
   321  	},
   322  	{
   323  		"alter table `t1` partition by system_time (partition x history, partition y current)",
   324  		[]string{"ALTER TABLE `test`.`t1` PARTITION BY SYSTEM_TIME (PARTITION `x` HISTORY,PARTITION `y` CURRENT)"},
   325  		[][]*filter.Table{{genTableName("test", "t1")}},
   326  		[][]*filter.Table{{genTableName("xtest", "xt1")}},
   327  		[]string{"ALTER TABLE `xtest`.`xt1` PARTITION BY SYSTEM_TIME (PARTITION `x` HISTORY,PARTITION `y` CURRENT)"},
   328  	},
   329  	{
   330  		"alter database `test` charset utf8mb4",
   331  		[]string{"ALTER DATABASE `test` CHARACTER SET = utf8mb4"},
   332  		[][]*filter.Table{{genTableName("test", "")}},
   333  		[][]*filter.Table{{genTableName("xtest", "")}},
   334  		[]string{"ALTER DATABASE `xtest` CHARACTER SET = utf8mb4"},
   335  	},
   336  	{
   337  		"alter table `t1` add column (c1 int, c2 int)",
   338  		[]string{"ALTER TABLE `test`.`t1` ADD COLUMN `c1` INT", "ALTER TABLE `test`.`t1` ADD COLUMN `c2` INT"},
   339  		[][]*filter.Table{{genTableName("test", "t1")}, {genTableName("test", "t1")}},
   340  		[][]*filter.Table{{genTableName("xtest", "t1")}, {genTableName("xtest", "t1")}},
   341  		[]string{"ALTER TABLE `xtest`.`t1` ADD COLUMN `c1` INT", "ALTER TABLE `xtest`.`t1` ADD COLUMN `c2` INT"},
   342  	},
   343  }
   344  
   345  var nonDDLs = []string{
   346  	"GRANT CREATE TABLESPACE ON *.* TO `root`@`%` WITH GRANT OPTION",
   347  }
   348  
   349  func TestParser(t *testing.T) {
   350  	t.Parallel()
   351  	p := parser.New()
   352  
   353  	for _, ca := range testCases {
   354  		sql := ca.sql
   355  		stmts, err := Parse(p, sql, "", "")
   356  		require.NoError(t, err)
   357  		require.Len(t, stmts, 1)
   358  	}
   359  
   360  	for _, sql := range nonDDLs {
   361  		stmts, err := Parse(p, sql, "", "")
   362  		require.NoError(t, err)
   363  		require.Len(t, stmts, 1)
   364  	}
   365  
   366  	unsupportedSQLs := []string{
   367  		"alter table bar ADD SPATIAL INDEX (`g`)",
   368  	}
   369  
   370  	for _, sql := range unsupportedSQLs {
   371  		_, err := Parse(p, sql, "", "")
   372  		require.NotNil(t, err)
   373  	}
   374  }
   375  
   376  func TestError(t *testing.T) {
   377  	t.Parallel()
   378  	p := parser.New()
   379  
   380  	// DML will report ErrUnknownTypeDDL
   381  	dml := "INSERT INTO `t1` VALUES (1)"
   382  
   383  	stmts, err := Parse(p, dml, "", "")
   384  	require.NoError(t, err)
   385  	_, err = FetchDDLTables("test", stmts[0], conn.LCTableNamesInsensitive)
   386  	require.True(t, terror.ErrUnknownTypeDDL.Equal(err))
   387  
   388  	_, err = RenameDDLTable(stmts[0], nil)
   389  	require.True(t, terror.ErrUnknownTypeDDL.Equal(err))
   390  
   391  	// tableRenameVisitor with less `targetNames` won't panic
   392  	ddl := "create table `s1`.`t1` (id int)"
   393  	stmts, err = Parse(p, ddl, "", "")
   394  	require.NoError(t, err)
   395  	_, err = RenameDDLTable(stmts[0], nil)
   396  	require.True(t, terror.ErrRewriteSQL.Equal(err))
   397  }
   398  
   399  func TestResolveDDL(t *testing.T) {
   400  	t.Parallel()
   401  	p := parser.New()
   402  
   403  	for _, ca := range testCases {
   404  		stmts, err := Parse(p, ca.sql, "", "")
   405  		require.NoError(t, err)
   406  		require.Len(t, stmts, 1)
   407  
   408  		statements, err := SplitDDL(stmts[0], "test")
   409  		require.NoError(t, err)
   410  		require.Equal(t, ca.expectedSQLs, statements)
   411  
   412  		tbs := ca.expectedTableNames
   413  		for j, statement := range statements {
   414  			s, err := Parse(p, statement, "", "")
   415  			require.NoError(t, err)
   416  			require.Len(t, s, 1)
   417  
   418  			tableNames, err := FetchDDLTables("test", s[0], conn.LCTableNamesSensitive)
   419  			require.NoError(t, err)
   420  			require.Equal(t, tbs[j], tableNames)
   421  
   422  			targetSQL, err := RenameDDLTable(s[0], ca.targetTableNames[j])
   423  			require.NoError(t, err)
   424  			require.Equal(t, ca.targetSQLs[j], targetSQL)
   425  		}
   426  	}
   427  }
   428  
   429  func TestCheckIsDDL(t *testing.T) {
   430  	t.Parallel()
   431  	var (
   432  		cases = []struct {
   433  			sql   string
   434  			isDDL bool
   435  		}{
   436  			{
   437  				sql:   "CREATE DATABASE test_is_ddl",
   438  				isDDL: true,
   439  			},
   440  			{
   441  				sql:   "BEGIN",
   442  				isDDL: false,
   443  			},
   444  			{
   445  				sql:   "INSERT INTO test_is_ddl.test_is_ddl_table VALUES (1)",
   446  				isDDL: false,
   447  			},
   448  			{
   449  				sql:   "INVAID SQL STATEMENT",
   450  				isDDL: false,
   451  			},
   452  		}
   453  		parser2 = parser.New()
   454  	)
   455  
   456  	for _, cs := range cases {
   457  		require.Equal(t, cs.isDDL, CheckIsDDL(cs.sql, parser2))
   458  	}
   459  }