github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/sqlparse/tidbparser/ast/ddl.go (about)

     1  // Copyright 2015 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
    15  
    16  import (
    17  	"github.com/bingoohuang/gg/pkg/sqlparse/tidbparser/dependency/model"
    18  	"github.com/bingoohuang/gg/pkg/sqlparse/tidbparser/dependency/types"
    19  )
    20  
    21  var (
    22  	_ DDLNode = &AlterTableStmt{}
    23  	_ DDLNode = &CreateDatabaseStmt{}
    24  	_ DDLNode = &CreateIndexStmt{}
    25  	_ DDLNode = &CreateTableStmt{}
    26  	_ DDLNode = &CreateViewStmt{}
    27  	_ DDLNode = &DropDatabaseStmt{}
    28  	_ DDLNode = &DropIndexStmt{}
    29  	_ DDLNode = &DropTableStmt{}
    30  	_ DDLNode = &RenameTableStmt{}
    31  	_ DDLNode = &TruncateTableStmt{}
    32  
    33  	_ Node = &AlterTableSpec{}
    34  	_ Node = &ColumnDef{}
    35  	_ Node = &ColumnOption{}
    36  	_ Node = &ColumnPosition{}
    37  	_ Node = &Constraint{}
    38  	_ Node = &IndexColName{}
    39  	_ Node = &ReferenceDef{}
    40  )
    41  
    42  // CharsetOpt is used for parsing charset option from SQL.
    43  type CharsetOpt struct {
    44  	Chs string
    45  	Col string
    46  }
    47  
    48  // DatabaseOptionType is the type for database options.
    49  type DatabaseOptionType int
    50  
    51  // Database option types.
    52  const (
    53  	DatabaseOptionNone DatabaseOptionType = iota
    54  	DatabaseOptionCharset
    55  	DatabaseOptionCollate
    56  )
    57  
    58  // DatabaseOption represents database option.
    59  type DatabaseOption struct {
    60  	Tp    DatabaseOptionType
    61  	Value string
    62  }
    63  
    64  // CreateDatabaseStmt is a statement to create a database.
    65  // See https://dev.mysql.com/doc/refman/5.7/en/create-database.html
    66  type CreateDatabaseStmt struct {
    67  	ddlNode
    68  
    69  	IfNotExists bool
    70  	Name        string
    71  	Options     []*DatabaseOption
    72  }
    73  
    74  // Accept implements Node Accept interface.
    75  func (n *CreateDatabaseStmt) Accept(v Visitor) (Node, bool) {
    76  	newNode, skipChildren := v.Enter(n)
    77  	if skipChildren {
    78  		return v.Leave(newNode)
    79  	}
    80  	n = newNode.(*CreateDatabaseStmt)
    81  	return v.Leave(n)
    82  }
    83  
    84  // DropDatabaseStmt is a statement to drop a database and all tables in the database.
    85  // See https://dev.mysql.com/doc/refman/5.7/en/drop-database.html
    86  type DropDatabaseStmt struct {
    87  	ddlNode
    88  
    89  	IfExists bool
    90  	Name     string
    91  }
    92  
    93  // Accept implements Node Accept interface.
    94  func (n *DropDatabaseStmt) Accept(v Visitor) (Node, bool) {
    95  	newNode, skipChildren := v.Enter(n)
    96  	if skipChildren {
    97  		return v.Leave(newNode)
    98  	}
    99  	n = newNode.(*DropDatabaseStmt)
   100  	return v.Leave(n)
   101  }
   102  
   103  // IndexColName is used for parsing index column name from SQL.
   104  type IndexColName struct {
   105  	node
   106  
   107  	Column *ColumnName
   108  	Length int
   109  }
   110  
   111  // Accept implements Node Accept interface.
   112  func (n *IndexColName) Accept(v Visitor) (Node, bool) {
   113  	newNode, skipChildren := v.Enter(n)
   114  	if skipChildren {
   115  		return v.Leave(newNode)
   116  	}
   117  	n = newNode.(*IndexColName)
   118  	node, ok := n.Column.Accept(v)
   119  	if !ok {
   120  		return n, false
   121  	}
   122  	n.Column = node.(*ColumnName)
   123  	return v.Leave(n)
   124  }
   125  
   126  // ReferenceDef is used for parsing foreign key reference option from SQL.
   127  // See http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html
   128  type ReferenceDef struct {
   129  	node
   130  
   131  	Table         *TableName
   132  	IndexColNames []*IndexColName
   133  	OnDelete      *OnDeleteOpt
   134  	OnUpdate      *OnUpdateOpt
   135  }
   136  
   137  // Accept implements Node Accept interface.
   138  func (n *ReferenceDef) Accept(v Visitor) (Node, bool) {
   139  	newNode, skipChildren := v.Enter(n)
   140  	if skipChildren {
   141  		return v.Leave(newNode)
   142  	}
   143  	n = newNode.(*ReferenceDef)
   144  	node, ok := n.Table.Accept(v)
   145  	if !ok {
   146  		return n, false
   147  	}
   148  	n.Table = node.(*TableName)
   149  	for i, val := range n.IndexColNames {
   150  		node, ok = val.Accept(v)
   151  		if !ok {
   152  			return n, false
   153  		}
   154  		n.IndexColNames[i] = node.(*IndexColName)
   155  	}
   156  	onDelete, ok := n.OnDelete.Accept(v)
   157  	if !ok {
   158  		return n, false
   159  	}
   160  	n.OnDelete = onDelete.(*OnDeleteOpt)
   161  	onUpdate, ok := n.OnUpdate.Accept(v)
   162  	if !ok {
   163  		return n, false
   164  	}
   165  	n.OnUpdate = onUpdate.(*OnUpdateOpt)
   166  	return v.Leave(n)
   167  }
   168  
   169  // ReferOptionType is the type for refer options.
   170  type ReferOptionType int
   171  
   172  // Refer option types.
   173  const (
   174  	ReferOptionNoOption ReferOptionType = iota
   175  	ReferOptionRestrict
   176  	ReferOptionCascade
   177  	ReferOptionSetNull
   178  	ReferOptionNoAction
   179  )
   180  
   181  // String implements fmt.Stringer interface.
   182  func (r ReferOptionType) String() string {
   183  	switch r {
   184  	case ReferOptionRestrict:
   185  		return "RESTRICT"
   186  	case ReferOptionCascade:
   187  		return "CASCADE"
   188  	case ReferOptionSetNull:
   189  		return "SET NULL"
   190  	case ReferOptionNoAction:
   191  		return "NO ACTION"
   192  	}
   193  	return ""
   194  }
   195  
   196  // OnDeleteOpt is used for optional on delete clause.
   197  type OnDeleteOpt struct {
   198  	node
   199  	ReferOpt ReferOptionType
   200  }
   201  
   202  // Accept implements Node Accept interface.
   203  func (n *OnDeleteOpt) Accept(v Visitor) (Node, bool) {
   204  	newNode, skipChildren := v.Enter(n)
   205  	if skipChildren {
   206  		return v.Leave(newNode)
   207  	}
   208  	n = newNode.(*OnDeleteOpt)
   209  	return v.Leave(n)
   210  }
   211  
   212  // OnUpdateOpt is used for optional on update clause.
   213  type OnUpdateOpt struct {
   214  	node
   215  	ReferOpt ReferOptionType
   216  }
   217  
   218  // Accept implements Node Accept interface.
   219  func (n *OnUpdateOpt) Accept(v Visitor) (Node, bool) {
   220  	newNode, skipChildren := v.Enter(n)
   221  	if skipChildren {
   222  		return v.Leave(newNode)
   223  	}
   224  	n = newNode.(*OnUpdateOpt)
   225  	return v.Leave(n)
   226  }
   227  
   228  // ColumnOptionType is the type for ColumnOption.
   229  type ColumnOptionType int
   230  
   231  // ColumnOption types.
   232  const (
   233  	ColumnOptionNoOption ColumnOptionType = iota
   234  	ColumnOptionPrimaryKey
   235  	ColumnOptionNotNull
   236  	ColumnOptionAutoIncrement
   237  	ColumnOptionDefaultValue
   238  	ColumnOptionUniqKey
   239  	ColumnOptionNull
   240  	ColumnOptionOnUpdate // For Timestamp and Datetime only.
   241  	ColumnOptionFulltext
   242  	ColumnOptionComment
   243  	ColumnOptionGenerated
   244  	ColumnOptionReference
   245  )
   246  
   247  // ColumnOption is used for parsing column constraint info from SQL.
   248  type ColumnOption struct {
   249  	node
   250  
   251  	Tp ColumnOptionType
   252  	// For ColumnOptionDefaultValue or ColumnOptionOnUpdate, it's the target value.
   253  	// For ColumnOptionGenerated, it's the target expression.
   254  	Expr ExprNode
   255  	// Stored is only for ColumnOptionGenerated, default is false.
   256  	Stored bool
   257  	// Refer is used for foreign key.
   258  	Refer *ReferenceDef
   259  }
   260  
   261  // Accept implements Node Accept interface.
   262  func (n *ColumnOption) Accept(v Visitor) (Node, bool) {
   263  	newNode, skipChildren := v.Enter(n)
   264  	if skipChildren {
   265  		return v.Leave(newNode)
   266  	}
   267  	n = newNode.(*ColumnOption)
   268  	if n.Expr != nil {
   269  		node, ok := n.Expr.Accept(v)
   270  		if !ok {
   271  			return n, false
   272  		}
   273  		n.Expr = node.(ExprNode)
   274  	}
   275  	return v.Leave(n)
   276  }
   277  
   278  // IndexOption is the index options.
   279  //
   280  //	  KEY_BLOCK_SIZE [=] value
   281  //	| index_type
   282  //	| WITH PARSER parser_name
   283  //	| COMMENT 'string'
   284  //
   285  // See http://dev.mysql.com/doc/refman/5.7/en/create-table.html
   286  type IndexOption struct {
   287  	node
   288  
   289  	KeyBlockSize uint64
   290  	Tp           model.IndexType
   291  	Comment      string
   292  }
   293  
   294  // Accept implements Node Accept interface.
   295  func (n *IndexOption) Accept(v Visitor) (Node, bool) {
   296  	newNode, skipChildren := v.Enter(n)
   297  	if skipChildren {
   298  		return v.Leave(newNode)
   299  	}
   300  	n = newNode.(*IndexOption)
   301  	return v.Leave(n)
   302  }
   303  
   304  // ConstraintType is the type for Constraint.
   305  type ConstraintType int
   306  
   307  // ConstraintTypes
   308  const (
   309  	ConstraintNoConstraint ConstraintType = iota
   310  	ConstraintPrimaryKey
   311  	ConstraintKey
   312  	ConstraintIndex
   313  	ConstraintUniq
   314  	ConstraintUniqKey
   315  	ConstraintUniqIndex
   316  	ConstraintForeignKey
   317  	ConstraintFulltext
   318  )
   319  
   320  // Constraint is constraint for table definition.
   321  type Constraint struct {
   322  	node
   323  
   324  	Tp   ConstraintType
   325  	Name string
   326  
   327  	Keys []*IndexColName // Used for PRIMARY KEY, UNIQUE, ......
   328  
   329  	Refer *ReferenceDef // Used for foreign key.
   330  
   331  	Option *IndexOption // Index Options
   332  }
   333  
   334  // Accept implements Node Accept interface.
   335  func (n *Constraint) Accept(v Visitor) (Node, bool) {
   336  	newNode, skipChildren := v.Enter(n)
   337  	if skipChildren {
   338  		return v.Leave(newNode)
   339  	}
   340  	n = newNode.(*Constraint)
   341  	for i, val := range n.Keys {
   342  		node, ok := val.Accept(v)
   343  		if !ok {
   344  			return n, false
   345  		}
   346  		n.Keys[i] = node.(*IndexColName)
   347  	}
   348  	if n.Refer != nil {
   349  		node, ok := n.Refer.Accept(v)
   350  		if !ok {
   351  			return n, false
   352  		}
   353  		n.Refer = node.(*ReferenceDef)
   354  	}
   355  	if n.Option != nil {
   356  		node, ok := n.Option.Accept(v)
   357  		if !ok {
   358  			return n, false
   359  		}
   360  		n.Option = node.(*IndexOption)
   361  	}
   362  	return v.Leave(n)
   363  }
   364  
   365  // ColumnDef is used for parsing column definition from SQL.
   366  type ColumnDef struct {
   367  	node
   368  
   369  	Name    *ColumnName
   370  	Tp      *types.FieldType
   371  	Options []*ColumnOption
   372  }
   373  
   374  // Accept implements Node Accept interface.
   375  func (n *ColumnDef) Accept(v Visitor) (Node, bool) {
   376  	newNode, skipChildren := v.Enter(n)
   377  	if skipChildren {
   378  		return v.Leave(newNode)
   379  	}
   380  	n = newNode.(*ColumnDef)
   381  	node, ok := n.Name.Accept(v)
   382  	if !ok {
   383  		return n, false
   384  	}
   385  	n.Name = node.(*ColumnName)
   386  	for i, val := range n.Options {
   387  		node, ok := val.Accept(v)
   388  		if !ok {
   389  			return n, false
   390  		}
   391  		n.Options[i] = node.(*ColumnOption)
   392  	}
   393  	return v.Leave(n)
   394  }
   395  
   396  // CreateTableStmt is a statement to create a table.
   397  // See https://dev.mysql.com/doc/refman/5.7/en/create-table.html
   398  type CreateTableStmt struct {
   399  	ddlNode
   400  
   401  	IfNotExists bool
   402  	Table       *TableName
   403  	ReferTable  *TableName
   404  	Cols        []*ColumnDef
   405  	Constraints []*Constraint
   406  	Options     []*TableOption
   407  }
   408  
   409  // Accept implements Node Accept interface.
   410  func (n *CreateTableStmt) Accept(v Visitor) (Node, bool) {
   411  	newNode, skipChildren := v.Enter(n)
   412  	if skipChildren {
   413  		return v.Leave(newNode)
   414  	}
   415  	n = newNode.(*CreateTableStmt)
   416  	node, ok := n.Table.Accept(v)
   417  	if !ok {
   418  		return n, false
   419  	}
   420  	n.Table = node.(*TableName)
   421  	if n.ReferTable != nil {
   422  		node, ok = n.ReferTable.Accept(v)
   423  		if !ok {
   424  			return n, false
   425  		}
   426  		n.ReferTable = node.(*TableName)
   427  	}
   428  	for i, val := range n.Cols {
   429  		node, ok = val.Accept(v)
   430  		if !ok {
   431  			return n, false
   432  		}
   433  		n.Cols[i] = node.(*ColumnDef)
   434  	}
   435  	for i, val := range n.Constraints {
   436  		node, ok = val.Accept(v)
   437  		if !ok {
   438  			return n, false
   439  		}
   440  		n.Constraints[i] = node.(*Constraint)
   441  	}
   442  	return v.Leave(n)
   443  }
   444  
   445  // DropTableStmt is a statement to drop one or more tables.
   446  // See https://dev.mysql.com/doc/refman/5.7/en/drop-table.html
   447  type DropTableStmt struct {
   448  	ddlNode
   449  
   450  	IfExists bool
   451  	Tables   []*TableName
   452  }
   453  
   454  // Accept implements Node Accept interface.
   455  func (n *DropTableStmt) Accept(v Visitor) (Node, bool) {
   456  	newNode, skipChildren := v.Enter(n)
   457  	if skipChildren {
   458  		return v.Leave(newNode)
   459  	}
   460  	n = newNode.(*DropTableStmt)
   461  	for i, val := range n.Tables {
   462  		node, ok := val.Accept(v)
   463  		if !ok {
   464  			return n, false
   465  		}
   466  		n.Tables[i] = node.(*TableName)
   467  	}
   468  	return v.Leave(n)
   469  }
   470  
   471  // RenameTableStmt is a statement to rename a table.
   472  // See http://dev.mysql.com/doc/refman/5.7/en/rename-table.html
   473  type RenameTableStmt struct {
   474  	ddlNode
   475  
   476  	OldTable *TableName
   477  	NewTable *TableName
   478  	// TODO: Refactor this when you are going to add full support for multiple schema changes.
   479  	// Currently it is only useful for syncer which depends heavily on tidb parser to do some dirty work.
   480  	TableToTables []*TableToTable
   481  }
   482  
   483  // Accept implements Node Accept interface.
   484  func (n *RenameTableStmt) Accept(v Visitor) (Node, bool) {
   485  	newNode, skipChildren := v.Enter(n)
   486  	if skipChildren {
   487  		return v.Leave(newNode)
   488  	}
   489  	n = newNode.(*RenameTableStmt)
   490  	node, ok := n.OldTable.Accept(v)
   491  	if !ok {
   492  		return n, false
   493  	}
   494  	n.OldTable = node.(*TableName)
   495  	node, ok = n.NewTable.Accept(v)
   496  	if !ok {
   497  		return n, false
   498  	}
   499  	n.NewTable = node.(*TableName)
   500  
   501  	for i, t := range n.TableToTables {
   502  		node, ok := t.Accept(v)
   503  		if !ok {
   504  			return n, false
   505  		}
   506  		n.TableToTables[i] = node.(*TableToTable)
   507  	}
   508  
   509  	return v.Leave(n)
   510  }
   511  
   512  // TableToTable represents renaming old table to new table used in RenameTableStmt.
   513  type TableToTable struct {
   514  	node
   515  	OldTable *TableName
   516  	NewTable *TableName
   517  }
   518  
   519  // Accept implements Node Accept interface.
   520  func (n *TableToTable) Accept(v Visitor) (Node, bool) {
   521  	newNode, skipChildren := v.Enter(n)
   522  	if skipChildren {
   523  		return v.Leave(newNode)
   524  	}
   525  	n = newNode.(*TableToTable)
   526  	node, ok := n.OldTable.Accept(v)
   527  	if !ok {
   528  		return n, false
   529  	}
   530  	n.OldTable = node.(*TableName)
   531  	node, ok = n.NewTable.Accept(v)
   532  	if !ok {
   533  		return n, false
   534  	}
   535  	n.NewTable = node.(*TableName)
   536  	return v.Leave(n)
   537  }
   538  
   539  // CreateViewStmt is a statement to create a View.
   540  // See https://dev.mysql.com/doc/refman/5.7/en/create-view.html
   541  type CreateViewStmt struct {
   542  	ddlNode
   543  
   544  	OrReplace bool
   545  	ViewName  *TableName
   546  	Cols      []model.CIStr
   547  	Select    StmtNode
   548  }
   549  
   550  // Accept implements Node Accept interface.
   551  func (n *CreateViewStmt) Accept(v Visitor) (Node, bool) {
   552  	// TODO: implement the details.
   553  	return n, true
   554  }
   555  
   556  // CreateIndexStmt is a statement to create an index.
   557  // See https://dev.mysql.com/doc/refman/5.7/en/create-index.html
   558  type CreateIndexStmt struct {
   559  	ddlNode
   560  
   561  	IndexName     string
   562  	Table         *TableName
   563  	Unique        bool
   564  	IndexColNames []*IndexColName
   565  	IndexOption   *IndexOption
   566  }
   567  
   568  // Accept implements Node Accept interface.
   569  func (n *CreateIndexStmt) Accept(v Visitor) (Node, bool) {
   570  	newNode, skipChildren := v.Enter(n)
   571  	if skipChildren {
   572  		return v.Leave(newNode)
   573  	}
   574  	n = newNode.(*CreateIndexStmt)
   575  	node, ok := n.Table.Accept(v)
   576  	if !ok {
   577  		return n, false
   578  	}
   579  	n.Table = node.(*TableName)
   580  	for i, val := range n.IndexColNames {
   581  		node, ok = val.Accept(v)
   582  		if !ok {
   583  			return n, false
   584  		}
   585  		n.IndexColNames[i] = node.(*IndexColName)
   586  	}
   587  	if n.IndexOption != nil {
   588  		node, ok := n.IndexOption.Accept(v)
   589  		if !ok {
   590  			return n, false
   591  		}
   592  		n.IndexOption = node.(*IndexOption)
   593  	}
   594  	return v.Leave(n)
   595  }
   596  
   597  // DropIndexStmt is a statement to drop the index.
   598  // See https://dev.mysql.com/doc/refman/5.7/en/drop-index.html
   599  type DropIndexStmt struct {
   600  	ddlNode
   601  
   602  	IfExists  bool
   603  	IndexName string
   604  	Table     *TableName
   605  }
   606  
   607  // Accept implements Node Accept interface.
   608  func (n *DropIndexStmt) Accept(v Visitor) (Node, bool) {
   609  	newNode, skipChildren := v.Enter(n)
   610  	if skipChildren {
   611  		return v.Leave(newNode)
   612  	}
   613  	n = newNode.(*DropIndexStmt)
   614  	node, ok := n.Table.Accept(v)
   615  	if !ok {
   616  		return n, false
   617  	}
   618  	n.Table = node.(*TableName)
   619  	return v.Leave(n)
   620  }
   621  
   622  // TableOptionType is the type for TableOption
   623  type TableOptionType int
   624  
   625  // TableOption types.
   626  const (
   627  	TableOptionNone TableOptionType = iota
   628  	TableOptionEngine
   629  	TableOptionCharset
   630  	TableOptionCollate
   631  	TableOptionAutoIncrement
   632  	TableOptionComment
   633  	TableOptionAvgRowLength
   634  	TableOptionCheckSum
   635  	TableOptionCompression
   636  	TableOptionConnection
   637  	TableOptionPassword
   638  	TableOptionKeyBlockSize
   639  	TableOptionMaxRows
   640  	TableOptionMinRows
   641  	TableOptionDelayKeyWrite
   642  	TableOptionRowFormat
   643  	TableOptionStatsPersistent
   644  	TableOptionShardRowID
   645  	TableOptionPackKeys
   646  )
   647  
   648  // RowFormat types
   649  const (
   650  	RowFormatDefault uint64 = iota + 1
   651  	RowFormatDynamic
   652  	RowFormatFixed
   653  	RowFormatCompressed
   654  	RowFormatRedundant
   655  	RowFormatCompact
   656  )
   657  
   658  // TableOption is used for parsing table option from SQL.
   659  type TableOption struct {
   660  	Tp        TableOptionType
   661  	StrValue  string
   662  	UintValue uint64
   663  }
   664  
   665  // ColumnPositionType is the type for ColumnPosition.
   666  type ColumnPositionType int
   667  
   668  // ColumnPosition Types
   669  const (
   670  	ColumnPositionNone ColumnPositionType = iota
   671  	ColumnPositionFirst
   672  	ColumnPositionAfter
   673  )
   674  
   675  // ColumnPosition represent the position of the newly added column
   676  type ColumnPosition struct {
   677  	node
   678  	// Tp is either ColumnPositionNone, ColumnPositionFirst or ColumnPositionAfter.
   679  	Tp ColumnPositionType
   680  	// RelativeColumn is the column the newly added column after if type is ColumnPositionAfter
   681  	RelativeColumn *ColumnName
   682  }
   683  
   684  // Accept implements Node Accept interface.
   685  func (n *ColumnPosition) Accept(v Visitor) (Node, bool) {
   686  	newNode, skipChildren := v.Enter(n)
   687  	if skipChildren {
   688  		return v.Leave(newNode)
   689  	}
   690  	n = newNode.(*ColumnPosition)
   691  	if n.RelativeColumn != nil {
   692  		node, ok := n.RelativeColumn.Accept(v)
   693  		if !ok {
   694  			return n, false
   695  		}
   696  		n.RelativeColumn = node.(*ColumnName)
   697  	}
   698  	return v.Leave(n)
   699  }
   700  
   701  // AlterTableType is the type for AlterTableSpec.
   702  type AlterTableType int
   703  
   704  // AlterTable types.
   705  const (
   706  	AlterTableOption AlterTableType = iota + 1
   707  	AlterTableAddColumns
   708  	AlterTableAddConstraint
   709  	AlterTableDropColumn
   710  	AlterTableDropPrimaryKey
   711  	AlterTableDropIndex
   712  	AlterTableDropForeignKey
   713  	AlterTableModifyColumn
   714  	AlterTableChangeColumn
   715  	AlterTableRenameTable
   716  	AlterTableAlterColumn
   717  	AlterTableLock
   718  
   719  // TODO: Add more actions
   720  )
   721  
   722  // LockType is the type for AlterTableSpec.
   723  // See https://dev.mysql.com/doc/refman/5.7/en/alter-table.html#alter-table-concurrency
   724  type LockType byte
   725  
   726  // Lock Types.
   727  const (
   728  	LockTypeNone LockType = iota + 1
   729  	LockTypeDefault
   730  	LockTypeShared
   731  	LockTypeExclusive
   732  )
   733  
   734  // AlterTableSpec represents alter table specification.
   735  type AlterTableSpec struct {
   736  	node
   737  
   738  	Tp            AlterTableType
   739  	Name          string
   740  	Constraint    *Constraint
   741  	Options       []*TableOption
   742  	NewTable      *TableName
   743  	NewColumns    []*ColumnDef
   744  	OldColumnName *ColumnName
   745  	Position      *ColumnPosition
   746  	LockType      LockType
   747  }
   748  
   749  // Accept implements Node Accept interface.
   750  func (n *AlterTableSpec) Accept(v Visitor) (Node, bool) {
   751  	newNode, skipChildren := v.Enter(n)
   752  	if skipChildren {
   753  		return v.Leave(newNode)
   754  	}
   755  	n = newNode.(*AlterTableSpec)
   756  	if n.Constraint != nil {
   757  		node, ok := n.Constraint.Accept(v)
   758  		if !ok {
   759  			return n, false
   760  		}
   761  		n.Constraint = node.(*Constraint)
   762  	}
   763  	if n.NewTable != nil {
   764  		node, ok := n.NewTable.Accept(v)
   765  		if !ok {
   766  			return n, false
   767  		}
   768  		n.NewTable = node.(*TableName)
   769  	}
   770  	for _, col := range n.NewColumns {
   771  		node, ok := col.Accept(v)
   772  		if !ok {
   773  			return n, false
   774  		}
   775  		col = node.(*ColumnDef)
   776  	}
   777  	if n.OldColumnName != nil {
   778  		node, ok := n.OldColumnName.Accept(v)
   779  		if !ok {
   780  			return n, false
   781  		}
   782  		n.OldColumnName = node.(*ColumnName)
   783  	}
   784  	if n.Position != nil {
   785  		node, ok := n.Position.Accept(v)
   786  		if !ok {
   787  			return n, false
   788  		}
   789  		n.Position = node.(*ColumnPosition)
   790  	}
   791  	return v.Leave(n)
   792  }
   793  
   794  // AlterTableStmt is a statement to change the structure of a table.
   795  // See https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
   796  type AlterTableStmt struct {
   797  	ddlNode
   798  
   799  	Table *TableName
   800  	Specs []*AlterTableSpec
   801  }
   802  
   803  // Accept implements Node Accept interface.
   804  func (n *AlterTableStmt) Accept(v Visitor) (Node, bool) {
   805  	newNode, skipChildren := v.Enter(n)
   806  	if skipChildren {
   807  		return v.Leave(newNode)
   808  	}
   809  	n = newNode.(*AlterTableStmt)
   810  	node, ok := n.Table.Accept(v)
   811  	if !ok {
   812  		return n, false
   813  	}
   814  	n.Table = node.(*TableName)
   815  	for i, val := range n.Specs {
   816  		node, ok = val.Accept(v)
   817  		if !ok {
   818  			return n, false
   819  		}
   820  		n.Specs[i] = node.(*AlterTableSpec)
   821  	}
   822  	return v.Leave(n)
   823  }
   824  
   825  // TruncateTableStmt is a statement to empty a table completely.
   826  // See https://dev.mysql.com/doc/refman/5.7/en/truncate-table.html
   827  type TruncateTableStmt struct {
   828  	ddlNode
   829  
   830  	Table *TableName
   831  }
   832  
   833  // Accept implements Node Accept interface.
   834  func (n *TruncateTableStmt) Accept(v Visitor) (Node, bool) {
   835  	newNode, skipChildren := v.Enter(n)
   836  	if skipChildren {
   837  		return v.Leave(newNode)
   838  	}
   839  	n = newNode.(*TruncateTableStmt)
   840  	node, ok := n.Table.Accept(v)
   841  	if !ok {
   842  		return n, false
   843  	}
   844  	n.Table = node.(*TableName)
   845  	return v.Leave(n)
   846  }