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