github.com/XiaoMi/Gaea@v1.2.5/parser/ast/misc.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  	"bytes"
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/pingcap/errors"
    22  
    23  	"github.com/XiaoMi/Gaea/mysql"
    24  	"github.com/XiaoMi/Gaea/parser/auth"
    25  	"github.com/XiaoMi/Gaea/parser/format"
    26  	"github.com/XiaoMi/Gaea/parser/model"
    27  )
    28  
    29  var (
    30  	_ StmtNode = &AdminStmt{}
    31  	_ StmtNode = &AlterUserStmt{}
    32  	_ StmtNode = &BeginStmt{}
    33  	_ StmtNode = &BinlogStmt{}
    34  	_ StmtNode = &CommitStmt{}
    35  	_ StmtNode = &CreateUserStmt{}
    36  	_ StmtNode = &DeallocateStmt{}
    37  	_ StmtNode = &DoStmt{}
    38  	_ StmtNode = &ExecuteStmt{}
    39  	_ StmtNode = &ExplainStmt{}
    40  	_ StmtNode = &GrantStmt{}
    41  	_ StmtNode = &PrepareStmt{}
    42  	_ StmtNode = &RollbackStmt{}
    43  	_ StmtNode = &SetPwdStmt{}
    44  	_ StmtNode = &SetStmt{}
    45  	_ StmtNode = &UseStmt{}
    46  	_ StmtNode = &FlushStmt{}
    47  	_ StmtNode = &KillStmt{}
    48  	_ StmtNode = &CreateBindingStmt{}
    49  	_ StmtNode = &DropBindingStmt{}
    50  	_ StmtNode = &SavepointStmt{}
    51  
    52  	_ Node = &PrivElem{}
    53  	_ Node = &VariableAssignment{}
    54  )
    55  
    56  // Isolation level constants.
    57  const (
    58  	ReadCommitted   = "READ-COMMITTED"
    59  	ReadUncommitted = "READ-UNCOMMITTED"
    60  	Serializable    = "SERIALIZABLE"
    61  	RepeatableRead  = "REPEATABLE-READ"
    62  
    63  	// Valid formats for explain statement.
    64  	ExplainFormatROW = "row"
    65  	ExplainFormatDOT = "dot"
    66  )
    67  
    68  var (
    69  	// ExplainFormats stores the valid formats for explain statement, used by validator.
    70  	ExplainFormats = []string{
    71  		ExplainFormatROW,
    72  		ExplainFormatDOT,
    73  	}
    74  )
    75  
    76  // TypeOpt is used for parsing data type option from SQL.
    77  type TypeOpt struct {
    78  	IsUnsigned bool
    79  	IsZerofill bool
    80  }
    81  
    82  // FloatOpt is used for parsing floating-point type option from SQL.
    83  // See http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html
    84  type FloatOpt struct {
    85  	Flen    int
    86  	Decimal int
    87  }
    88  
    89  // AuthOption is used for parsing create use statement.
    90  type AuthOption struct {
    91  	// ByAuthString set as true, if AuthString is used for authorization. Otherwise, authorization is done by HashString.
    92  	ByAuthString bool
    93  	AuthString   string
    94  	HashString   string
    95  	// TODO: support auth_plugin
    96  }
    97  
    98  // Restore implements Node interface.
    99  func (n *AuthOption) Restore(ctx *format.RestoreCtx) error {
   100  	ctx.WriteKeyWord("IDENTIFIED BY ")
   101  	if n.ByAuthString {
   102  		ctx.WriteString(n.AuthString)
   103  	} else {
   104  		ctx.WriteKeyWord("PASSWORD ")
   105  		ctx.WriteString(n.HashString)
   106  	}
   107  	return nil
   108  }
   109  
   110  // TraceStmt is a statement to trace what sql actually does at background.
   111  type TraceStmt struct {
   112  	stmtNode
   113  
   114  	Stmt   StmtNode
   115  	Format string
   116  }
   117  
   118  // Restore implements Node interface.
   119  func (n *TraceStmt) Restore(ctx *format.RestoreCtx) error {
   120  	ctx.WriteKeyWord("TRACE ")
   121  	if n.Format != "json" {
   122  		ctx.WriteKeyWord("FORMAT")
   123  		ctx.WritePlain(" = ")
   124  		ctx.WriteString(n.Format)
   125  		ctx.WritePlain(" ")
   126  	}
   127  	if err := n.Stmt.Restore(ctx); err != nil {
   128  		return errors.Annotate(err, "An error occurred while restore TraceStmt.Stmt")
   129  	}
   130  	return nil
   131  }
   132  
   133  // Accept implements Node Accept interface.
   134  func (n *TraceStmt) Accept(v Visitor) (Node, bool) {
   135  	newNode, skipChildren := v.Enter(n)
   136  	if skipChildren {
   137  		return v.Leave(newNode)
   138  	}
   139  	n = newNode.(*TraceStmt)
   140  	node, ok := n.Stmt.Accept(v)
   141  	if !ok {
   142  		return n, false
   143  	}
   144  	n.Stmt = node.(DMLNode)
   145  	return v.Leave(n)
   146  }
   147  
   148  // ExplainStmt is a statement to provide information about how is SQL statement executed
   149  // or get columns information in a table.
   150  // See https://dev.mysql.com/doc/refman/5.7/en/explain.html
   151  type ExplainStmt struct {
   152  	stmtNode
   153  
   154  	Stmt    StmtNode
   155  	Format  string
   156  	Analyze bool
   157  }
   158  
   159  // Restore implements Node interface.
   160  func (n *ExplainStmt) Restore(ctx *format.RestoreCtx) error {
   161  	if showStmt, ok := n.Stmt.(*ShowStmt); ok {
   162  		ctx.WriteKeyWord("DESC ")
   163  		if err := showStmt.Table.Restore(ctx); err != nil {
   164  			return errors.Annotate(err, "An error occurred while restore ExplainStmt.ShowStmt.Table")
   165  		}
   166  		if showStmt.Column != nil {
   167  			ctx.WritePlain(" ")
   168  			if err := showStmt.Column.Restore(ctx); err != nil {
   169  				return errors.Annotate(err, "An error occurred while restore ExplainStmt.ShowStmt.Column")
   170  			}
   171  		}
   172  		return nil
   173  	}
   174  	ctx.WriteKeyWord("EXPLAIN ")
   175  	if n.Analyze {
   176  		ctx.WriteKeyWord("ANALYZE ")
   177  	} else {
   178  		ctx.WriteKeyWord("FORMAT ")
   179  		ctx.WritePlain("= ")
   180  		ctx.WriteString(n.Format)
   181  		ctx.WritePlain(" ")
   182  	}
   183  	if err := n.Stmt.Restore(ctx); err != nil {
   184  		return errors.Annotate(err, "An error occurred while restore ExplainStmt.Stmt")
   185  	}
   186  	return nil
   187  }
   188  
   189  // Accept implements Node Accept interface.
   190  func (n *ExplainStmt) Accept(v Visitor) (Node, bool) {
   191  	newNode, skipChildren := v.Enter(n)
   192  	if skipChildren {
   193  		return v.Leave(newNode)
   194  	}
   195  	n = newNode.(*ExplainStmt)
   196  	node, ok := n.Stmt.Accept(v)
   197  	if !ok {
   198  		return n, false
   199  	}
   200  	n.Stmt = node.(DMLNode)
   201  	return v.Leave(n)
   202  }
   203  
   204  // PrepareStmt is a statement to prepares a SQL statement which contains placeholders,
   205  // and it is executed with ExecuteStmt and released with DeallocateStmt.
   206  // See https://dev.mysql.com/doc/refman/5.7/en/prepare.html
   207  type PrepareStmt struct {
   208  	stmtNode
   209  
   210  	Name    string
   211  	SQLText string
   212  	SQLVar  *VariableExpr
   213  }
   214  
   215  // Restore implements Node interface.
   216  func (n *PrepareStmt) Restore(ctx *format.RestoreCtx) error {
   217  	ctx.WriteKeyWord("PREPARE ")
   218  	ctx.WriteName(n.Name)
   219  	ctx.WriteKeyWord(" FROM ")
   220  	if n.SQLText != "" {
   221  		ctx.WriteString(n.SQLText)
   222  		return nil
   223  	}
   224  	if n.SQLVar != nil {
   225  		if err := n.SQLVar.Restore(ctx); err != nil {
   226  			return errors.Annotate(err, "An error occurred while restore PrepareStmt.SQLVar")
   227  		}
   228  		return nil
   229  	}
   230  	return errors.New("An error occurred while restore PrepareStmt")
   231  }
   232  
   233  // Accept implements Node Accept interface.
   234  func (n *PrepareStmt) Accept(v Visitor) (Node, bool) {
   235  	newNode, skipChildren := v.Enter(n)
   236  	if skipChildren {
   237  		return v.Leave(newNode)
   238  	}
   239  	n = newNode.(*PrepareStmt)
   240  	if n.SQLVar != nil {
   241  		node, ok := n.SQLVar.Accept(v)
   242  		if !ok {
   243  			return n, false
   244  		}
   245  		n.SQLVar = node.(*VariableExpr)
   246  	}
   247  	return v.Leave(n)
   248  }
   249  
   250  // DeallocateStmt is a statement to release PreparedStmt.
   251  // See https://dev.mysql.com/doc/refman/5.7/en/deallocate-prepare.html
   252  type DeallocateStmt struct {
   253  	stmtNode
   254  
   255  	Name string
   256  }
   257  
   258  // Restore implements Node interface.
   259  func (n *DeallocateStmt) Restore(ctx *format.RestoreCtx) error {
   260  	ctx.WriteKeyWord("DEALLOCATE PREPARE ")
   261  	ctx.WriteName(n.Name)
   262  	return nil
   263  }
   264  
   265  // Accept implements Node Accept interface.
   266  func (n *DeallocateStmt) Accept(v Visitor) (Node, bool) {
   267  	newNode, skipChildren := v.Enter(n)
   268  	if skipChildren {
   269  		return v.Leave(newNode)
   270  	}
   271  	n = newNode.(*DeallocateStmt)
   272  	return v.Leave(n)
   273  }
   274  
   275  // Prepared represents a prepared statement.
   276  type Prepared struct {
   277  	Stmt          StmtNode
   278  	Params        []ParamMarkerExpr
   279  	SchemaVersion int64
   280  	UseCache      bool
   281  }
   282  
   283  // ExecuteStmt is a statement to execute PreparedStmt.
   284  // See https://dev.mysql.com/doc/refman/5.7/en/execute.html
   285  type ExecuteStmt struct {
   286  	stmtNode
   287  
   288  	Name      string
   289  	UsingVars []ExprNode
   290  	ExecID    uint32
   291  }
   292  
   293  // Restore implements Node interface.
   294  func (n *ExecuteStmt) Restore(ctx *format.RestoreCtx) error {
   295  	ctx.WriteKeyWord("EXECUTE ")
   296  	ctx.WriteName(n.Name)
   297  	if len(n.UsingVars) > 0 {
   298  		ctx.WriteKeyWord(" USING ")
   299  		for i, val := range n.UsingVars {
   300  			if i != 0 {
   301  				ctx.WritePlain(",")
   302  			}
   303  			if err := val.Restore(ctx); err != nil {
   304  				return errors.Annotatef(err, "An error occurred while restore ExecuteStmt.UsingVars index %d", i)
   305  			}
   306  		}
   307  	}
   308  	return nil
   309  }
   310  
   311  // Accept implements Node Accept interface.
   312  func (n *ExecuteStmt) Accept(v Visitor) (Node, bool) {
   313  	newNode, skipChildren := v.Enter(n)
   314  	if skipChildren {
   315  		return v.Leave(newNode)
   316  	}
   317  	n = newNode.(*ExecuteStmt)
   318  	for i, val := range n.UsingVars {
   319  		node, ok := val.Accept(v)
   320  		if !ok {
   321  			return n, false
   322  		}
   323  		n.UsingVars[i] = node.(ExprNode)
   324  	}
   325  	return v.Leave(n)
   326  }
   327  
   328  // BeginStmt is a statement to start a new transaction.
   329  // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
   330  type BeginStmt struct {
   331  	stmtNode
   332  }
   333  
   334  // Restore implements Node interface.
   335  func (n *BeginStmt) Restore(ctx *format.RestoreCtx) error {
   336  	ctx.WriteKeyWord("START TRANSACTION")
   337  	return nil
   338  }
   339  
   340  // Accept implements Node Accept interface.
   341  func (n *BeginStmt) Accept(v Visitor) (Node, bool) {
   342  	newNode, skipChildren := v.Enter(n)
   343  	if skipChildren {
   344  		return v.Leave(newNode)
   345  	}
   346  	n = newNode.(*BeginStmt)
   347  	return v.Leave(n)
   348  }
   349  
   350  // BinlogStmt is an internal-use statement.
   351  // We just parse and ignore it.
   352  // See http://dev.mysql.com/doc/refman/5.7/en/binlog.html
   353  type BinlogStmt struct {
   354  	stmtNode
   355  	Str string
   356  }
   357  
   358  // Restore implements Node interface.
   359  func (n *BinlogStmt) Restore(ctx *format.RestoreCtx) error {
   360  	ctx.WriteKeyWord("BINLOG ")
   361  	ctx.WriteString(n.Str)
   362  	return nil
   363  }
   364  
   365  // Accept implements Node Accept interface.
   366  func (n *BinlogStmt) Accept(v Visitor) (Node, bool) {
   367  	newNode, skipChildren := v.Enter(n)
   368  	if skipChildren {
   369  		return v.Leave(newNode)
   370  	}
   371  	n = newNode.(*BinlogStmt)
   372  	return v.Leave(n)
   373  }
   374  
   375  // CommitStmt is a statement to commit the current transaction.
   376  // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
   377  type CommitStmt struct {
   378  	stmtNode
   379  }
   380  
   381  // Restore implements Node interface.
   382  func (n *CommitStmt) Restore(ctx *format.RestoreCtx) error {
   383  	ctx.WriteKeyWord("COMMIT")
   384  	return nil
   385  }
   386  
   387  // Accept implements Node Accept interface.
   388  func (n *CommitStmt) Accept(v Visitor) (Node, bool) {
   389  	newNode, skipChildren := v.Enter(n)
   390  	if skipChildren {
   391  		return v.Leave(newNode)
   392  	}
   393  	n = newNode.(*CommitStmt)
   394  	return v.Leave(n)
   395  }
   396  
   397  // RollbackStmt is a statement to roll back the current transaction.
   398  // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
   399  type RollbackStmt struct {
   400  	stmtNode
   401  	Savepoint string
   402  }
   403  
   404  // Restore implements Node interface.
   405  func (n *RollbackStmt) Restore(ctx *format.RestoreCtx) error {
   406  	ctx.WriteKeyWord("ROLLBACK")
   407  	if n.Savepoint != "" {
   408  		ctx.WriteKeyWord(" TO SAVEPOINT ")
   409  		ctx.WritePlain(n.Savepoint)
   410  	}
   411  	return nil
   412  }
   413  
   414  // Accept implements Node Accept interface.
   415  func (n *RollbackStmt) Accept(v Visitor) (Node, bool) {
   416  	newNode, skipChildren := v.Enter(n)
   417  	if skipChildren {
   418  		return v.Leave(newNode)
   419  	}
   420  	n = newNode.(*RollbackStmt)
   421  	return v.Leave(n)
   422  }
   423  
   424  type SavepointStmt struct {
   425  	stmtNode
   426  	Savepoint string
   427  	Release   bool
   428  }
   429  
   430  // Restore implements Node interface.
   431  func (n *SavepointStmt) Restore(ctx *format.RestoreCtx) error {
   432  	if n.Release {
   433  		ctx.WriteKeyWord("RELEASE ")
   434  	}
   435  	ctx.WriteKeyWord("SAVEPOINT ")
   436  	ctx.WritePlain(n.Savepoint)
   437  	return nil
   438  }
   439  
   440  // Accept implements Node Accept interface.
   441  func (n *SavepointStmt) Accept(v Visitor) (Node, bool) {
   442  	newNode, skipChildren := v.Enter(n)
   443  	if skipChildren {
   444  		return v.Leave(newNode)
   445  	}
   446  	n = newNode.(*SavepointStmt)
   447  	return v.Leave(n)
   448  }
   449  
   450  // UseStmt is a statement to use the DBName database as the current database.
   451  // See https://dev.mysql.com/doc/refman/5.7/en/use.html
   452  type UseStmt struct {
   453  	stmtNode
   454  
   455  	DBName string
   456  }
   457  
   458  // Restore implements Node interface.
   459  func (n *UseStmt) Restore(ctx *format.RestoreCtx) error {
   460  	ctx.WriteKeyWord("USE ")
   461  	ctx.WriteName(n.DBName)
   462  	return nil
   463  }
   464  
   465  // Accept implements Node Accept interface.
   466  func (n *UseStmt) Accept(v Visitor) (Node, bool) {
   467  	newNode, skipChildren := v.Enter(n)
   468  	if skipChildren {
   469  		return v.Leave(newNode)
   470  	}
   471  	n = newNode.(*UseStmt)
   472  	return v.Leave(n)
   473  }
   474  
   475  const (
   476  	// SetNames is the const for set names/charset stmt.
   477  	// If VariableAssignment.Name == Names, it should be set names/charset stmt.
   478  	SetNames = "SetNAMES"
   479  )
   480  
   481  // VariableAssignment is a variable assignment struct.
   482  type VariableAssignment struct {
   483  	node
   484  	Name     string
   485  	Value    ExprNode
   486  	IsGlobal bool
   487  	IsSystem bool
   488  
   489  	// ExtendValue is a way to store extended info.
   490  	// VariableAssignment should be able to store information for SetCharset/SetPWD Stmt.
   491  	// For SetCharsetStmt, Value is charset, ExtendValue is collation.
   492  	// TODO: Use SetStmt to implement set password statement.
   493  	ExtendValue ValueExpr
   494  }
   495  
   496  // Restore implements Node interface.
   497  func (n *VariableAssignment) Restore(ctx *format.RestoreCtx) error {
   498  	if n.IsSystem {
   499  		ctx.WritePlain("@@")
   500  		if n.IsGlobal {
   501  			ctx.WriteKeyWord("GLOBAL")
   502  		} else {
   503  			ctx.WriteKeyWord("SESSION")
   504  		}
   505  		ctx.WritePlain(".")
   506  	} else if n.Name != SetNames {
   507  		ctx.WriteKeyWord("@")
   508  	}
   509  	if n.Name == SetNames {
   510  		ctx.WriteKeyWord("NAMES ")
   511  	} else {
   512  		ctx.WriteName(n.Name)
   513  		ctx.WritePlain("=")
   514  	}
   515  	if err := n.Value.Restore(ctx); err != nil {
   516  		return errors.Annotate(err, "An error occurred while restore VariableAssignment.Value")
   517  	}
   518  	if n.ExtendValue != nil {
   519  		ctx.WriteKeyWord(" COLLATE ")
   520  		if err := n.ExtendValue.Restore(ctx); err != nil {
   521  			return errors.Annotate(err, "An error occurred while restore VariableAssignment.ExtendValue")
   522  		}
   523  	}
   524  	return nil
   525  }
   526  
   527  // Accept implements Node interface.
   528  func (n *VariableAssignment) Accept(v Visitor) (Node, bool) {
   529  	newNode, skipChildren := v.Enter(n)
   530  	if skipChildren {
   531  		return v.Leave(newNode)
   532  	}
   533  	n = newNode.(*VariableAssignment)
   534  	node, ok := n.Value.Accept(v)
   535  	if !ok {
   536  		return n, false
   537  	}
   538  	n.Value = node.(ExprNode)
   539  	return v.Leave(n)
   540  }
   541  
   542  // FlushStmtType is the type for FLUSH statement.
   543  type FlushStmtType int
   544  
   545  // Flush statement types.
   546  const (
   547  	FlushNone FlushStmtType = iota
   548  	FlushTables
   549  	FlushPrivileges
   550  	FlushStatus
   551  	FlushTiDBPlugin
   552  )
   553  
   554  // FlushStmt is a statement to flush tables/privileges/optimizer costs and so on.
   555  type FlushStmt struct {
   556  	stmtNode
   557  
   558  	Tp              FlushStmtType // Privileges/Tables/...
   559  	NoWriteToBinLog bool
   560  	Tables          []*TableName // For FlushTableStmt, if Tables is empty, it means flush all tables.
   561  	ReadLock        bool
   562  	Plugins         []string
   563  }
   564  
   565  // Restore implements Node interface.
   566  func (n *FlushStmt) Restore(ctx *format.RestoreCtx) error {
   567  	ctx.WriteKeyWord("FLUSH ")
   568  	if n.NoWriteToBinLog {
   569  		ctx.WriteKeyWord("NO_WRITE_TO_BINLOG ")
   570  	}
   571  	switch n.Tp {
   572  	case FlushTables:
   573  		ctx.WriteKeyWord("TABLES")
   574  		for i, v := range n.Tables {
   575  			if i == 0 {
   576  				ctx.WritePlain(" ")
   577  			} else {
   578  				ctx.WritePlain(", ")
   579  			}
   580  			if err := v.Restore(ctx); err != nil {
   581  				return errors.Annotatef(err, "An error occurred while restore FlushStmt.Tables[%d]", i)
   582  			}
   583  		}
   584  		if n.ReadLock {
   585  			ctx.WriteKeyWord(" WITH READ LOCK")
   586  		}
   587  	case FlushPrivileges:
   588  		ctx.WriteKeyWord("PRIVILEGES")
   589  	case FlushStatus:
   590  		ctx.WriteKeyWord("STATUS")
   591  	case FlushTiDBPlugin:
   592  		ctx.WriteKeyWord("TIDB PLUGINS")
   593  		for i, v := range n.Plugins {
   594  			if i == 0 {
   595  				ctx.WritePlain(" ")
   596  			} else {
   597  				ctx.WritePlain(", ")
   598  			}
   599  			ctx.WritePlain(v)
   600  		}
   601  	default:
   602  		return errors.New("Unsupported type of FlushTables")
   603  	}
   604  	return nil
   605  }
   606  
   607  // Accept implements Node Accept interface.
   608  func (n *FlushStmt) Accept(v Visitor) (Node, bool) {
   609  	newNode, skipChildren := v.Enter(n)
   610  	if skipChildren {
   611  		return v.Leave(newNode)
   612  	}
   613  	n = newNode.(*FlushStmt)
   614  	return v.Leave(n)
   615  }
   616  
   617  // KillStmt is a statement to kill a query or connection.
   618  type KillStmt struct {
   619  	stmtNode
   620  
   621  	// Query indicates whether terminate a single query on this connection or the whole connection.
   622  	// If Query is true, terminates the statement the connection is currently executing, but leaves the connection itself intact.
   623  	// If Query is false, terminates the connection associated with the given ConnectionID, after terminating any statement the connection is executing.
   624  	Query        bool
   625  	ConnectionID uint64
   626  	// TiDBExtension is used to indicate whether the user knows he is sending kill statement to the right tidb-server.
   627  	// When the SQL grammar is "KILL TIDB [CONNECTION | QUERY] connectionID", TiDBExtension will be set.
   628  	// It's a special grammar extension in TiDB. This extension exists because, when the connection is:
   629  	// client -> LVS proxy -> TiDB, and type Ctrl+C in client, the following action will be executed:
   630  	// new a connection; kill xxx;
   631  	// kill command may send to the wrong TiDB, because the exists of LVS proxy, and kill the wrong session.
   632  	// So, "KILL TIDB" grammar is introduced, and it REQUIRES DIRECT client -> TiDB TOPOLOGY.
   633  	// TODO: The standard KILL grammar will be supported once we have global connectionID.
   634  	TiDBExtension bool
   635  }
   636  
   637  // Restore implements Node interface.
   638  func (n *KillStmt) Restore(ctx *format.RestoreCtx) error {
   639  	ctx.WriteKeyWord("KILL")
   640  	if n.TiDBExtension {
   641  		ctx.WriteKeyWord(" TIDB")
   642  	}
   643  	if n.Query {
   644  		ctx.WriteKeyWord(" QUERY")
   645  	}
   646  	ctx.WritePlainf(" %d", n.ConnectionID)
   647  	return nil
   648  }
   649  
   650  // Accept implements Node Accept interface.
   651  func (n *KillStmt) Accept(v Visitor) (Node, bool) {
   652  	newNode, skipChildren := v.Enter(n)
   653  	if skipChildren {
   654  		return v.Leave(newNode)
   655  	}
   656  	n = newNode.(*KillStmt)
   657  	return v.Leave(n)
   658  }
   659  
   660  // SetStmt is the statement to set variables.
   661  type SetStmt struct {
   662  	stmtNode
   663  	// Variables is the list of variable assignment.
   664  	Variables []*VariableAssignment
   665  }
   666  
   667  // Restore implements Node interface.
   668  func (n *SetStmt) Restore(ctx *format.RestoreCtx) error {
   669  	ctx.WriteKeyWord("SET ")
   670  	for i, v := range n.Variables {
   671  		if i != 0 {
   672  			ctx.WritePlain(", ")
   673  		}
   674  		if err := v.Restore(ctx); err != nil {
   675  			return errors.Annotatef(err, "An error occurred while restore SetStmt.Variables[%d]", i)
   676  		}
   677  	}
   678  	return nil
   679  }
   680  
   681  // Accept implements Node Accept interface.
   682  func (n *SetStmt) Accept(v Visitor) (Node, bool) {
   683  	newNode, skipChildren := v.Enter(n)
   684  	if skipChildren {
   685  		return v.Leave(newNode)
   686  	}
   687  	n = newNode.(*SetStmt)
   688  	for i, val := range n.Variables {
   689  		node, ok := val.Accept(v)
   690  		if !ok {
   691  			return n, false
   692  		}
   693  		n.Variables[i] = node.(*VariableAssignment)
   694  	}
   695  	return v.Leave(n)
   696  }
   697  
   698  /*
   699  // SetCharsetStmt is a statement to assign values to character and collation variables.
   700  // See https://dev.mysql.com/doc/refman/5.7/en/set-statement.html
   701  type SetCharsetStmt struct {
   702  	stmtNode
   703  
   704  	Charset string
   705  	Collate string
   706  }
   707  
   708  // Accept implements Node Accept interface.
   709  func (n *SetCharsetStmt) Accept(v Visitor) (Node, bool) {
   710  	newNode, skipChildren := v.Enter(n)
   711  	if skipChildren {
   712  		return v.Leave(newNode)
   713  	}
   714  	n = newNode.(*SetCharsetStmt)
   715  	return v.Leave(n)
   716  }
   717  */
   718  
   719  // SetPwdStmt is a statement to assign a password to user account.
   720  // See https://dev.mysql.com/doc/refman/5.7/en/set-password.html
   721  type SetPwdStmt struct {
   722  	stmtNode
   723  
   724  	User     *auth.UserIdentity
   725  	Password string
   726  }
   727  
   728  // Restore implements Node interface.
   729  func (n *SetPwdStmt) Restore(ctx *format.RestoreCtx) error {
   730  	ctx.WriteKeyWord("SET PASSWORD")
   731  	if n.User != nil {
   732  		ctx.WriteKeyWord(" FOR ")
   733  		if err := n.User.Restore(ctx); err != nil {
   734  			return errors.Annotate(err, "An error occurred while restore SetPwdStmt.User")
   735  		}
   736  	}
   737  	ctx.WritePlain("=")
   738  	ctx.WriteString(n.Password)
   739  	return nil
   740  }
   741  
   742  // SecureText implements SensitiveStatement interface.
   743  func (n *SetPwdStmt) SecureText() string {
   744  	return fmt.Sprintf("set password for user %s", n.User)
   745  }
   746  
   747  // Accept implements Node Accept interface.
   748  func (n *SetPwdStmt) Accept(v Visitor) (Node, bool) {
   749  	newNode, skipChildren := v.Enter(n)
   750  	if skipChildren {
   751  		return v.Leave(newNode)
   752  	}
   753  	n = newNode.(*SetPwdStmt)
   754  	return v.Leave(n)
   755  }
   756  
   757  // UserSpec is used for parsing create user statement.
   758  type UserSpec struct {
   759  	User    *auth.UserIdentity
   760  	AuthOpt *AuthOption
   761  	IsRole  bool
   762  }
   763  
   764  // Restore implements Node interface.
   765  func (n *UserSpec) Restore(ctx *format.RestoreCtx) error {
   766  	if err := n.User.Restore(ctx); err != nil {
   767  		return errors.Annotate(err, "An error occurred while restore UserSpec.User")
   768  	}
   769  	if n.AuthOpt != nil {
   770  		ctx.WritePlain(" ")
   771  		if err := n.AuthOpt.Restore(ctx); err != nil {
   772  			return errors.Annotate(err, "An error occurred while restore UserSpec.AuthOpt")
   773  		}
   774  	}
   775  	return nil
   776  }
   777  
   778  // SecurityString formats the UserSpec without password information.
   779  func (n *UserSpec) SecurityString() string {
   780  	withPassword := false
   781  	if opt := n.AuthOpt; opt != nil {
   782  		if len(opt.AuthString) > 0 || len(opt.HashString) > 0 {
   783  			withPassword = true
   784  		}
   785  	}
   786  	if withPassword {
   787  		return fmt.Sprintf("{%s password = ***}", n.User)
   788  	}
   789  	return n.User.String()
   790  }
   791  
   792  // EncodedPassword returns the encoded password (which is the real data mysql.user).
   793  // The boolean value indicates input's password format is legal or not.
   794  func (n *UserSpec) EncodedPassword() (string, bool) {
   795  	if n.AuthOpt == nil {
   796  		return "", true
   797  	}
   798  
   799  	opt := n.AuthOpt
   800  	if opt.ByAuthString {
   801  		return auth.EncodePassword(opt.AuthString), true
   802  	}
   803  
   804  	// Not a legal password string.
   805  	if len(opt.HashString) != 41 || !strings.HasPrefix(opt.HashString, "*") {
   806  		return "", false
   807  	}
   808  	return opt.HashString, true
   809  }
   810  
   811  // CreateUserStmt creates user account.
   812  // See https://dev.mysql.com/doc/refman/5.7/en/create-user.html
   813  type CreateUserStmt struct {
   814  	stmtNode
   815  
   816  	IsCreateRole bool
   817  	IfNotExists  bool
   818  	Specs        []*UserSpec
   819  }
   820  
   821  // Restore implements Node interface.
   822  func (n *CreateUserStmt) Restore(ctx *format.RestoreCtx) error {
   823  	if n.IsCreateRole {
   824  		ctx.WriteKeyWord("CREATE ROLE ")
   825  	} else {
   826  		ctx.WriteKeyWord("CREATE USER ")
   827  	}
   828  	if n.IfNotExists {
   829  		ctx.WriteKeyWord("IF NOT EXISTS ")
   830  	}
   831  	for i, v := range n.Specs {
   832  		if i != 0 {
   833  			ctx.WritePlain(", ")
   834  		}
   835  		if err := v.Restore(ctx); err != nil {
   836  			return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.Specs[%d]", i)
   837  		}
   838  	}
   839  	return nil
   840  }
   841  
   842  // Accept implements Node Accept interface.
   843  func (n *CreateUserStmt) Accept(v Visitor) (Node, bool) {
   844  	newNode, skipChildren := v.Enter(n)
   845  	if skipChildren {
   846  		return v.Leave(newNode)
   847  	}
   848  	n = newNode.(*CreateUserStmt)
   849  	return v.Leave(n)
   850  }
   851  
   852  // SecureText implements SensitiveStatement interface.
   853  func (n *CreateUserStmt) SecureText() string {
   854  	var buf bytes.Buffer
   855  	buf.WriteString("create user")
   856  	for _, user := range n.Specs {
   857  		buf.WriteString(" ")
   858  		buf.WriteString(user.SecurityString())
   859  	}
   860  	return buf.String()
   861  }
   862  
   863  // AlterUserStmt modifies user account.
   864  // See https://dev.mysql.com/doc/refman/5.7/en/alter-user.html
   865  type AlterUserStmt struct {
   866  	stmtNode
   867  
   868  	IfExists    bool
   869  	CurrentAuth *AuthOption
   870  	Specs       []*UserSpec
   871  }
   872  
   873  // Restore implements Node interface.
   874  func (n *AlterUserStmt) Restore(ctx *format.RestoreCtx) error {
   875  	ctx.WriteKeyWord("ALTER USER ")
   876  	if n.IfExists {
   877  		ctx.WriteKeyWord("IF EXISTS ")
   878  	}
   879  	if n.CurrentAuth != nil {
   880  		ctx.WriteKeyWord("USER")
   881  		ctx.WritePlain("() ")
   882  		if err := n.CurrentAuth.Restore(ctx); err != nil {
   883  			return errors.Annotate(err, "An error occurred while restore AlterUserStmt.CurrentAuth")
   884  		}
   885  	}
   886  	for i, v := range n.Specs {
   887  		if i != 0 {
   888  			ctx.WritePlain(", ")
   889  		}
   890  		if err := v.Restore(ctx); err != nil {
   891  			return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.Specs[%d]", i)
   892  		}
   893  	}
   894  	return nil
   895  }
   896  
   897  // SecureText implements SensitiveStatement interface.
   898  func (n *AlterUserStmt) SecureText() string {
   899  	var buf bytes.Buffer
   900  	buf.WriteString("alter user")
   901  	for _, user := range n.Specs {
   902  		buf.WriteString(" ")
   903  		buf.WriteString(user.SecurityString())
   904  	}
   905  	return buf.String()
   906  }
   907  
   908  // Accept implements Node Accept interface.
   909  func (n *AlterUserStmt) Accept(v Visitor) (Node, bool) {
   910  	newNode, skipChildren := v.Enter(n)
   911  	if skipChildren {
   912  		return v.Leave(newNode)
   913  	}
   914  	n = newNode.(*AlterUserStmt)
   915  	return v.Leave(n)
   916  }
   917  
   918  // DropUserStmt creates user account.
   919  // See http://dev.mysql.com/doc/refman/5.7/en/drop-user.html
   920  type DropUserStmt struct {
   921  	stmtNode
   922  
   923  	IfExists bool
   924  	UserList []*auth.UserIdentity
   925  }
   926  
   927  // Restore implements Node interface.
   928  func (n *DropUserStmt) Restore(ctx *format.RestoreCtx) error {
   929  	ctx.WriteKeyWord("DROP USER ")
   930  	if n.IfExists {
   931  		ctx.WriteKeyWord("IF EXISTS ")
   932  	}
   933  	for i, v := range n.UserList {
   934  		if i != 0 {
   935  			ctx.WritePlain(", ")
   936  		}
   937  		if err := v.Restore(ctx); err != nil {
   938  			return errors.Annotatef(err, "An error occurred while restore DropUserStmt.UserList[%d]", i)
   939  		}
   940  	}
   941  	return nil
   942  }
   943  
   944  // Accept implements Node Accept interface.
   945  func (n *DropUserStmt) Accept(v Visitor) (Node, bool) {
   946  	newNode, skipChildren := v.Enter(n)
   947  	if skipChildren {
   948  		return v.Leave(newNode)
   949  	}
   950  	n = newNode.(*DropUserStmt)
   951  	return v.Leave(n)
   952  }
   953  
   954  // CreateBindingStmt creates sql binding hint.
   955  type CreateBindingStmt struct {
   956  	stmtNode
   957  
   958  	GlobalScope bool
   959  	OriginSel   StmtNode
   960  	HintedSel   StmtNode
   961  }
   962  
   963  // Restore CreateBindingStmt restore
   964  func (n *CreateBindingStmt) Restore(ctx *format.RestoreCtx) error {
   965  	ctx.WriteKeyWord("CREATE ")
   966  	if n.GlobalScope {
   967  		ctx.WriteKeyWord("GLOBAL ")
   968  	} else {
   969  		ctx.WriteKeyWord("SESSION ")
   970  	}
   971  	ctx.WriteKeyWord("BINDING FOR ")
   972  	if err := n.OriginSel.Restore(ctx); err != nil {
   973  		return errors.Trace(err)
   974  	}
   975  	ctx.WriteKeyWord(" USING ")
   976  	if err := n.HintedSel.Restore(ctx); err != nil {
   977  		return errors.Trace(err)
   978  	}
   979  	return nil
   980  }
   981  
   982  // Accept for visit CreateBindingStmt
   983  func (n *CreateBindingStmt) Accept(v Visitor) (Node, bool) {
   984  	newNode, skipChildren := v.Enter(n)
   985  	if skipChildren {
   986  		return v.Leave(newNode)
   987  	}
   988  	n = newNode.(*CreateBindingStmt)
   989  	selnode, ok := n.OriginSel.Accept(v)
   990  	if !ok {
   991  		return n, false
   992  	}
   993  	n.OriginSel = selnode.(*SelectStmt)
   994  	hintedSelnode, ok := n.HintedSel.Accept(v)
   995  	if !ok {
   996  		return n, false
   997  	}
   998  	n.HintedSel = hintedSelnode.(*SelectStmt)
   999  	return v.Leave(n)
  1000  }
  1001  
  1002  // DropBindingStmt deletes sql binding hint.
  1003  type DropBindingStmt struct {
  1004  	stmtNode
  1005  
  1006  	GlobalScope bool
  1007  	OriginSel   StmtNode
  1008  }
  1009  
  1010  // Restore restore DropBindingStmt
  1011  func (n *DropBindingStmt) Restore(ctx *format.RestoreCtx) error {
  1012  	return errors.New("Not implemented")
  1013  }
  1014  
  1015  // Accept DropBindingStmt for visit DropBindingStmt
  1016  func (n *DropBindingStmt) Accept(v Visitor) (Node, bool) {
  1017  	newNode, skipChildren := v.Enter(n)
  1018  	if skipChildren {
  1019  		return v.Leave(newNode)
  1020  	}
  1021  	n = newNode.(*DropBindingStmt)
  1022  	selnode, ok := n.OriginSel.Accept(v)
  1023  	if !ok {
  1024  		return n, false
  1025  	}
  1026  	n.OriginSel = selnode.(*SelectStmt)
  1027  	return v.Leave(n)
  1028  }
  1029  
  1030  // DoStmt is the struct for DO statement.
  1031  type DoStmt struct {
  1032  	stmtNode
  1033  
  1034  	Exprs []ExprNode
  1035  }
  1036  
  1037  // Restore implements Node interface.
  1038  func (n *DoStmt) Restore(ctx *format.RestoreCtx) error {
  1039  	ctx.WriteKeyWord("DO ")
  1040  	for i, v := range n.Exprs {
  1041  		if i != 0 {
  1042  			ctx.WritePlain(", ")
  1043  		}
  1044  		if err := v.Restore(ctx); err != nil {
  1045  			return errors.Annotatef(err, "An error occurred while restore DoStmt.Exprs[%d]", i)
  1046  		}
  1047  	}
  1048  	return nil
  1049  }
  1050  
  1051  // Accept implements Node Accept interface.
  1052  func (n *DoStmt) Accept(v Visitor) (Node, bool) {
  1053  	newNode, skipChildren := v.Enter(n)
  1054  	if skipChildren {
  1055  		return v.Leave(newNode)
  1056  	}
  1057  	n = newNode.(*DoStmt)
  1058  	for i, val := range n.Exprs {
  1059  		node, ok := val.Accept(v)
  1060  		if !ok {
  1061  			return n, false
  1062  		}
  1063  		n.Exprs[i] = node.(ExprNode)
  1064  	}
  1065  	return v.Leave(n)
  1066  }
  1067  
  1068  // AdminStmtType is the type for admin statement.
  1069  type AdminStmtType int
  1070  
  1071  // Admin statement types.
  1072  const (
  1073  	AdminShowDDL = iota + 1
  1074  	AdminCheckTable
  1075  	AdminShowDDLJobs
  1076  	AdminCancelDDLJobs
  1077  	AdminCheckIndex
  1078  	AdminRecoverIndex
  1079  	AdminCleanupIndex
  1080  	AdminCheckIndexRange
  1081  	AdminShowDDLJobQueries
  1082  	AdminChecksumTable
  1083  	AdminShowSlow
  1084  	AdminShowNextRowID
  1085  	AdminRestoreTable
  1086  )
  1087  
  1088  // HandleRange represents a range where handle value >= Begin and < End.
  1089  type HandleRange struct {
  1090  	Begin int64
  1091  	End   int64
  1092  }
  1093  
  1094  // ShowSlowType defines the type for SlowSlow statement.
  1095  type ShowSlowType int
  1096  
  1097  const (
  1098  	// ShowSlowTop is a ShowSlowType constant.
  1099  	ShowSlowTop ShowSlowType = iota
  1100  	// ShowSlowRecent is a ShowSlowType constant.
  1101  	ShowSlowRecent
  1102  )
  1103  
  1104  // ShowSlowKind defines the kind for SlowSlow statement when the type is ShowSlowTop.
  1105  type ShowSlowKind int
  1106  
  1107  const (
  1108  	// ShowSlowKindDefault is a ShowSlowKind constant.
  1109  	ShowSlowKindDefault ShowSlowKind = iota
  1110  	// ShowSlowKindInternal is a ShowSlowKind constant.
  1111  	ShowSlowKindInternal
  1112  	// ShowSlowKindAll is a ShowSlowKind constant.
  1113  	ShowSlowKindAll
  1114  )
  1115  
  1116  // ShowSlow is used for the following command:
  1117  //	admin show slow top [ internal | all] N
  1118  //	admin show slow recent N
  1119  type ShowSlow struct {
  1120  	Tp    ShowSlowType
  1121  	Count uint64
  1122  	Kind  ShowSlowKind
  1123  }
  1124  
  1125  // Restore implements Node interface.
  1126  func (n *ShowSlow) Restore(ctx *format.RestoreCtx) error {
  1127  	switch n.Tp {
  1128  	case ShowSlowRecent:
  1129  		ctx.WriteKeyWord("RECENT ")
  1130  	case ShowSlowTop:
  1131  		ctx.WriteKeyWord("TOP ")
  1132  		switch n.Kind {
  1133  		case ShowSlowKindDefault:
  1134  			// do nothing
  1135  		case ShowSlowKindInternal:
  1136  			ctx.WriteKeyWord("INTERNAL ")
  1137  		case ShowSlowKindAll:
  1138  			ctx.WriteKeyWord("ALL ")
  1139  		default:
  1140  			return errors.New("Unsupported kind of ShowSlowTop")
  1141  		}
  1142  	default:
  1143  		return errors.New("Unsupported type of ShowSlow")
  1144  	}
  1145  	ctx.WritePlainf("%d", n.Count)
  1146  	return nil
  1147  }
  1148  
  1149  // AdminStmt is the struct for Admin statement.
  1150  type AdminStmt struct {
  1151  	stmtNode
  1152  
  1153  	Tp        AdminStmtType
  1154  	Index     string
  1155  	Tables    []*TableName
  1156  	JobIDs    []int64
  1157  	JobNumber int64
  1158  
  1159  	HandleRanges []HandleRange
  1160  	ShowSlow     *ShowSlow
  1161  }
  1162  
  1163  // Restore implements Node interface.
  1164  func (n *AdminStmt) Restore(ctx *format.RestoreCtx) error {
  1165  	restoreTables := func() error {
  1166  		for i, v := range n.Tables {
  1167  			if i != 0 {
  1168  				ctx.WritePlain(", ")
  1169  			}
  1170  			if err := v.Restore(ctx); err != nil {
  1171  				return errors.Annotatef(err, "An error occurred while restore AdminStmt.Tables[%d]", i)
  1172  			}
  1173  		}
  1174  		return nil
  1175  	}
  1176  	restoreJobIDs := func() {
  1177  		for i, v := range n.JobIDs {
  1178  			if i != 0 {
  1179  				ctx.WritePlain(", ")
  1180  			}
  1181  			ctx.WritePlainf("%d", v)
  1182  		}
  1183  	}
  1184  
  1185  	ctx.WriteKeyWord("ADMIN ")
  1186  	switch n.Tp {
  1187  	case AdminShowDDL:
  1188  		ctx.WriteKeyWord("SHOW DDL")
  1189  	case AdminShowDDLJobs:
  1190  		ctx.WriteKeyWord("SHOW DDL JOBS")
  1191  		if n.JobNumber != 0 {
  1192  			ctx.WritePlainf(" %d", n.JobNumber)
  1193  		}
  1194  	case AdminShowNextRowID:
  1195  		ctx.WriteKeyWord("SHOW ")
  1196  		if err := restoreTables(); err != nil {
  1197  			return err
  1198  		}
  1199  		ctx.WriteKeyWord(" NEXT_ROW_ID")
  1200  	case AdminCheckTable:
  1201  		ctx.WriteKeyWord("CHECK TABLE ")
  1202  		if err := restoreTables(); err != nil {
  1203  			return err
  1204  		}
  1205  	case AdminCheckIndex:
  1206  		ctx.WriteKeyWord("CHECK INDEX ")
  1207  		if err := restoreTables(); err != nil {
  1208  			return err
  1209  		}
  1210  		ctx.WritePlainf(" %s", n.Index)
  1211  	case AdminRecoverIndex:
  1212  		ctx.WriteKeyWord("RECOVER INDEX ")
  1213  		if err := restoreTables(); err != nil {
  1214  			return err
  1215  		}
  1216  		ctx.WritePlainf(" %s", n.Index)
  1217  	case AdminRestoreTable:
  1218  		ctx.WriteKeyWord("RESTORE TABLE ")
  1219  		if n.JobIDs != nil {
  1220  			ctx.WriteKeyWord("BY JOB ")
  1221  			restoreJobIDs()
  1222  		} else {
  1223  			if err := restoreTables(); err != nil {
  1224  				return err
  1225  			}
  1226  			if n.JobNumber != 0 {
  1227  				ctx.WritePlainf(" %d", n.JobNumber)
  1228  			}
  1229  		}
  1230  	case AdminCleanupIndex:
  1231  		ctx.WriteKeyWord("CLEANUP INDEX ")
  1232  		if err := restoreTables(); err != nil {
  1233  			return err
  1234  		}
  1235  		ctx.WritePlainf(" %s", n.Index)
  1236  	case AdminCheckIndexRange:
  1237  		ctx.WriteKeyWord("CHECK INDEX ")
  1238  		if err := restoreTables(); err != nil {
  1239  			return err
  1240  		}
  1241  		ctx.WritePlainf(" %s", n.Index)
  1242  		if n.HandleRanges != nil {
  1243  			ctx.WritePlain(" ")
  1244  			for i, v := range n.HandleRanges {
  1245  				if i != 0 {
  1246  					ctx.WritePlain(", ")
  1247  				}
  1248  				ctx.WritePlainf("(%d,%d)", v.Begin, v.End)
  1249  			}
  1250  		}
  1251  	case AdminChecksumTable:
  1252  		ctx.WriteKeyWord("CHECKSUM TABLE ")
  1253  		if err := restoreTables(); err != nil {
  1254  			return err
  1255  		}
  1256  	case AdminCancelDDLJobs:
  1257  		ctx.WriteKeyWord("CANCEL DDL JOBS ")
  1258  		restoreJobIDs()
  1259  	case AdminShowDDLJobQueries:
  1260  		ctx.WriteKeyWord("SHOW DDL JOB QUERIES ")
  1261  		restoreJobIDs()
  1262  	case AdminShowSlow:
  1263  		ctx.WriteKeyWord("SHOW SLOW ")
  1264  		if err := n.ShowSlow.Restore(ctx); err != nil {
  1265  			return errors.Annotate(err, "An error occurred while restore AdminStmt.ShowSlow")
  1266  		}
  1267  	default:
  1268  		return errors.New("Unsupported AdminStmt type")
  1269  	}
  1270  	return nil
  1271  }
  1272  
  1273  // Accept implements Node Accept interface.
  1274  func (n *AdminStmt) Accept(v Visitor) (Node, bool) {
  1275  	newNode, skipChildren := v.Enter(n)
  1276  	if skipChildren {
  1277  		return v.Leave(newNode)
  1278  	}
  1279  
  1280  	n = newNode.(*AdminStmt)
  1281  	for i, val := range n.Tables {
  1282  		node, ok := val.Accept(v)
  1283  		if !ok {
  1284  			return n, false
  1285  		}
  1286  		n.Tables[i] = node.(*TableName)
  1287  	}
  1288  
  1289  	return v.Leave(n)
  1290  }
  1291  
  1292  // PrivElem is the privilege type and optional column list.
  1293  type PrivElem struct {
  1294  	node
  1295  
  1296  	Priv mysql.PrivilegeType
  1297  	Cols []*ColumnName
  1298  }
  1299  
  1300  // Restore implements Node interface.
  1301  func (n *PrivElem) Restore(ctx *format.RestoreCtx) error {
  1302  	switch n.Priv {
  1303  	case 0:
  1304  		ctx.WritePlain("/* UNSUPPORTED TYPE */")
  1305  	case mysql.AllPriv:
  1306  		ctx.WriteKeyWord("ALL")
  1307  	case mysql.AlterPriv:
  1308  		ctx.WriteKeyWord("ALTER")
  1309  	case mysql.CreatePriv:
  1310  		ctx.WriteKeyWord("CREATE")
  1311  	case mysql.CreateUserPriv:
  1312  		ctx.WriteKeyWord("CREATE USER")
  1313  	case mysql.CreateRolePriv:
  1314  		ctx.WriteKeyWord("CREATE ROLE")
  1315  	case mysql.TriggerPriv:
  1316  		ctx.WriteKeyWord("TRIGGER")
  1317  	case mysql.DeletePriv:
  1318  		ctx.WriteKeyWord("DELETE")
  1319  	case mysql.DropPriv:
  1320  		ctx.WriteKeyWord("DROP")
  1321  	case mysql.ProcessPriv:
  1322  		ctx.WriteKeyWord("PROCESS")
  1323  	case mysql.ExecutePriv:
  1324  		ctx.WriteKeyWord("EXECUTE")
  1325  	case mysql.IndexPriv:
  1326  		ctx.WriteKeyWord("INDEX")
  1327  	case mysql.InsertPriv:
  1328  		ctx.WriteKeyWord("INSERT")
  1329  	case mysql.SelectPriv:
  1330  		ctx.WriteKeyWord("SELECT")
  1331  	case mysql.SuperPriv:
  1332  		ctx.WriteKeyWord("SUPER")
  1333  	case mysql.ShowDBPriv:
  1334  		ctx.WriteKeyWord("SHOW DATABASES")
  1335  	case mysql.UpdatePriv:
  1336  		ctx.WriteKeyWord("UPDATE")
  1337  	case mysql.GrantPriv:
  1338  		ctx.WriteKeyWord("GRANT OPTION")
  1339  	case mysql.ReferencesPriv:
  1340  		ctx.WriteKeyWord("REFERENCES")
  1341  	case mysql.CreateViewPriv:
  1342  		ctx.WriteKeyWord("CREATE VIEW")
  1343  	case mysql.ShowViewPriv:
  1344  		ctx.WriteKeyWord("SHOW VIEW")
  1345  	default:
  1346  		return errors.New("Undefined privilege type")
  1347  	}
  1348  	if n.Cols != nil {
  1349  		ctx.WritePlain(" (")
  1350  		for i, v := range n.Cols {
  1351  			if i != 0 {
  1352  				ctx.WritePlain(",")
  1353  			}
  1354  			if err := v.Restore(ctx); err != nil {
  1355  				return errors.Annotatef(err, "An error occurred while restore PrivElem.Cols[%d]", i)
  1356  			}
  1357  		}
  1358  		ctx.WritePlain(")")
  1359  	}
  1360  	return nil
  1361  }
  1362  
  1363  // Accept implements Node Accept interface.
  1364  func (n *PrivElem) Accept(v Visitor) (Node, bool) {
  1365  	newNode, skipChildren := v.Enter(n)
  1366  	if skipChildren {
  1367  		return v.Leave(newNode)
  1368  	}
  1369  	n = newNode.(*PrivElem)
  1370  	for i, val := range n.Cols {
  1371  		node, ok := val.Accept(v)
  1372  		if !ok {
  1373  			return n, false
  1374  		}
  1375  		n.Cols[i] = node.(*ColumnName)
  1376  	}
  1377  	return v.Leave(n)
  1378  }
  1379  
  1380  // ObjectTypeType is the type for object type.
  1381  type ObjectTypeType int
  1382  
  1383  const (
  1384  	// ObjectTypeNone is for empty object type.
  1385  	ObjectTypeNone ObjectTypeType = iota + 1
  1386  	// ObjectTypeTable means the following object is a table.
  1387  	ObjectTypeTable
  1388  )
  1389  
  1390  // Restore implements Node interface.
  1391  func (n ObjectTypeType) Restore(ctx *format.RestoreCtx) error {
  1392  	switch n {
  1393  	case ObjectTypeNone:
  1394  		// do nothing
  1395  	case ObjectTypeTable:
  1396  		ctx.WriteKeyWord("TABLE")
  1397  	default:
  1398  		return errors.New("Unsupported object type")
  1399  	}
  1400  	return nil
  1401  }
  1402  
  1403  // GrantLevelType is the type for grant level.
  1404  type GrantLevelType int
  1405  
  1406  const (
  1407  	// GrantLevelNone is the dummy const for default value.
  1408  	GrantLevelNone GrantLevelType = iota + 1
  1409  	// GrantLevelGlobal means the privileges are administrative or apply to all databases on a given server.
  1410  	GrantLevelGlobal
  1411  	// GrantLevelDB means the privileges apply to all objects in a given database.
  1412  	GrantLevelDB
  1413  	// GrantLevelTable means the privileges apply to all columns in a given table.
  1414  	GrantLevelTable
  1415  )
  1416  
  1417  // GrantLevel is used for store the privilege scope.
  1418  type GrantLevel struct {
  1419  	Level     GrantLevelType
  1420  	DBName    string
  1421  	TableName string
  1422  }
  1423  
  1424  // Restore implements Node interface.
  1425  func (n *GrantLevel) Restore(ctx *format.RestoreCtx) error {
  1426  	switch n.Level {
  1427  	case GrantLevelDB:
  1428  		if n.DBName == "" {
  1429  			ctx.WritePlain("*")
  1430  		} else {
  1431  			ctx.WriteName(n.DBName)
  1432  			ctx.WritePlain(".*")
  1433  		}
  1434  	case GrantLevelGlobal:
  1435  		ctx.WritePlain("*.*")
  1436  	case GrantLevelTable:
  1437  		if n.DBName != "" {
  1438  			ctx.WriteName(n.DBName)
  1439  			ctx.WritePlain(".")
  1440  		}
  1441  		ctx.WriteName(n.TableName)
  1442  	}
  1443  	return nil
  1444  }
  1445  
  1446  // RevokeStmt is the struct for REVOKE statement.
  1447  type RevokeStmt struct {
  1448  	stmtNode
  1449  
  1450  	Privs      []*PrivElem
  1451  	ObjectType ObjectTypeType
  1452  	Level      *GrantLevel
  1453  	Users      []*UserSpec
  1454  }
  1455  
  1456  // Restore implements Node interface.
  1457  func (n *RevokeStmt) Restore(ctx *format.RestoreCtx) error {
  1458  	ctx.WriteKeyWord("REVOKE ")
  1459  	for i, v := range n.Privs {
  1460  		if i != 0 {
  1461  			ctx.WritePlain(", ")
  1462  		}
  1463  		if err := v.Restore(ctx); err != nil {
  1464  			return errors.Annotatef(err, "An error occurred while restore RevokeStmt.Privs[%d]", i)
  1465  		}
  1466  	}
  1467  	ctx.WriteKeyWord(" ON ")
  1468  	if n.ObjectType != ObjectTypeNone {
  1469  		if err := n.ObjectType.Restore(ctx); err != nil {
  1470  			return errors.Annotate(err, "An error occurred while restore RevokeStmt.ObjectType")
  1471  		}
  1472  		ctx.WritePlain(" ")
  1473  	}
  1474  	if err := n.Level.Restore(ctx); err != nil {
  1475  		return errors.Annotate(err, "An error occurred while restore RevokeStmt.Level")
  1476  	}
  1477  	ctx.WriteKeyWord(" FROM ")
  1478  	for i, v := range n.Users {
  1479  		if i != 0 {
  1480  			ctx.WritePlain(", ")
  1481  		}
  1482  		if err := v.Restore(ctx); err != nil {
  1483  			return errors.Annotatef(err, "An error occurred while restore RevokeStmt.Users[%d]", i)
  1484  		}
  1485  	}
  1486  	return nil
  1487  }
  1488  
  1489  // Accept implements Node Accept interface.
  1490  func (n *RevokeStmt) Accept(v Visitor) (Node, bool) {
  1491  	newNode, skipChildren := v.Enter(n)
  1492  	if skipChildren {
  1493  		return v.Leave(newNode)
  1494  	}
  1495  	n = newNode.(*RevokeStmt)
  1496  	for i, val := range n.Privs {
  1497  		node, ok := val.Accept(v)
  1498  		if !ok {
  1499  			return n, false
  1500  		}
  1501  		n.Privs[i] = node.(*PrivElem)
  1502  	}
  1503  	return v.Leave(n)
  1504  }
  1505  
  1506  // GrantStmt is the struct for GRANT statement.
  1507  type GrantStmt struct {
  1508  	stmtNode
  1509  
  1510  	Privs      []*PrivElem
  1511  	ObjectType ObjectTypeType
  1512  	Level      *GrantLevel
  1513  	Users      []*UserSpec
  1514  	WithGrant  bool
  1515  }
  1516  
  1517  // Restore implements Node interface.
  1518  func (n *GrantStmt) Restore(ctx *format.RestoreCtx) error {
  1519  	ctx.WriteKeyWord("GRANT ")
  1520  	for i, v := range n.Privs {
  1521  		if i != 0 && v.Priv != 0 {
  1522  			ctx.WritePlain(", ")
  1523  		} else if v.Priv == 0 {
  1524  			ctx.WritePlain(" ")
  1525  		}
  1526  		if err := v.Restore(ctx); err != nil {
  1527  			return errors.Annotatef(err, "An error occurred while restore GrantStmt.Privs[%d]", i)
  1528  		}
  1529  	}
  1530  	ctx.WriteKeyWord(" ON ")
  1531  	if n.ObjectType != ObjectTypeNone {
  1532  		if err := n.ObjectType.Restore(ctx); err != nil {
  1533  			return errors.Annotate(err, "An error occurred while restore GrantStmt.ObjectType")
  1534  		}
  1535  		ctx.WritePlain(" ")
  1536  	}
  1537  	if err := n.Level.Restore(ctx); err != nil {
  1538  		return errors.Annotate(err, "An error occurred while restore GrantStmt.Level")
  1539  	}
  1540  	ctx.WriteKeyWord(" TO ")
  1541  	for i, v := range n.Users {
  1542  		if i != 0 {
  1543  			ctx.WritePlain(", ")
  1544  		}
  1545  		if err := v.Restore(ctx); err != nil {
  1546  			return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i)
  1547  		}
  1548  	}
  1549  	if n.WithGrant {
  1550  		ctx.WriteKeyWord(" WITH GRANT OPTION")
  1551  	}
  1552  	return nil
  1553  }
  1554  
  1555  // SecureText implements SensitiveStatement interface.
  1556  func (n *GrantStmt) SecureText() string {
  1557  	text := n.text
  1558  	// Filter "identified by xxx" because it would expose password information.
  1559  	idx := strings.Index(strings.ToLower(text), "identified")
  1560  	if idx > 0 {
  1561  		text = text[:idx]
  1562  	}
  1563  	return text
  1564  }
  1565  
  1566  // Accept implements Node Accept interface.
  1567  func (n *GrantStmt) Accept(v Visitor) (Node, bool) {
  1568  	newNode, skipChildren := v.Enter(n)
  1569  	if skipChildren {
  1570  		return v.Leave(newNode)
  1571  	}
  1572  	n = newNode.(*GrantStmt)
  1573  	for i, val := range n.Privs {
  1574  		node, ok := val.Accept(v)
  1575  		if !ok {
  1576  			return n, false
  1577  		}
  1578  		n.Privs[i] = node.(*PrivElem)
  1579  	}
  1580  	return v.Leave(n)
  1581  }
  1582  
  1583  // Ident is the table identifier composed of schema name and table name.
  1584  type Ident struct {
  1585  	Schema model.CIStr
  1586  	Name   model.CIStr
  1587  }
  1588  
  1589  // String implements fmt.Stringer interface.
  1590  func (i Ident) String() string {
  1591  	if i.Schema.O == "" {
  1592  		return i.Name.O
  1593  	}
  1594  	return fmt.Sprintf("%s.%s", i.Schema, i.Name)
  1595  }
  1596  
  1597  // SelectStmtOpts wrap around select hints and switches
  1598  type SelectStmtOpts struct {
  1599  	Distinct      bool
  1600  	SQLCache      bool
  1601  	CalcFoundRows bool
  1602  	StraightJoin  bool
  1603  	Priority      mysql.PriorityEnum
  1604  	TableHints    []*TableOptimizerHint
  1605  }
  1606  
  1607  // TableOptimizerHint is Table level optimizer hint
  1608  type TableOptimizerHint struct {
  1609  	node
  1610  	// HintName is the name or alias of the table(s) which the hint will affect.
  1611  	// Table hints has no schema info
  1612  	// It allows only table name or alias (if table has an alias)
  1613  	HintName model.CIStr
  1614  	Tables   []model.CIStr
  1615  	// Statement Execution Time Optimizer Hints
  1616  	// See https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html#optimizer-hints-execution-time
  1617  	MaxExecutionTime uint64
  1618  }
  1619  
  1620  // Restore implements Node interface.
  1621  func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error {
  1622  	ctx.WriteKeyWord(n.HintName.String())
  1623  	ctx.WritePlain("(")
  1624  	if n.HintName.L == "max_execution_time" {
  1625  		ctx.WritePlainf("%d", n.MaxExecutionTime)
  1626  	} else {
  1627  		for i, table := range n.Tables {
  1628  			if i != 0 {
  1629  				ctx.WritePlain(", ")
  1630  			}
  1631  			ctx.WriteName(table.String())
  1632  		}
  1633  	}
  1634  	ctx.WritePlain(")")
  1635  	return nil
  1636  }
  1637  
  1638  // Accept implements Node Accept interface.
  1639  func (n *TableOptimizerHint) Accept(v Visitor) (Node, bool) {
  1640  	newNode, skipChildren := v.Enter(n)
  1641  	if skipChildren {
  1642  		return v.Leave(newNode)
  1643  	}
  1644  	n = newNode.(*TableOptimizerHint)
  1645  	return v.Leave(n)
  1646  }
  1647  
  1648  // NewDecimal creates a types.Decimal value, it's provided by parser driver.
  1649  var NewDecimal func(string) (interface{}, error)
  1650  
  1651  // NewHexLiteral creates a types.HexLiteral value, it's provided by parser driver.
  1652  var NewHexLiteral func(string) (interface{}, error)
  1653  
  1654  // NewBitLiteral creates a types.BitLiteral value, it's provided by parser driver.
  1655  var NewBitLiteral func(string) (interface{}, error)