github.com/pingcap/tidb/parser@v0.0.0-20231013125129-93a834a6bf8d/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  	"net/url"
    20  	"strconv"
    21  	"strings"
    22  
    23  	"github.com/pingcap/errors"
    24  	"github.com/pingcap/failpoint"
    25  	"github.com/pingcap/tidb/parser/auth"
    26  	"github.com/pingcap/tidb/parser/format"
    27  	"github.com/pingcap/tidb/parser/model"
    28  	"github.com/pingcap/tidb/parser/mysql"
    29  )
    30  
    31  var (
    32  	_ StmtNode = &AdminStmt{}
    33  	_ StmtNode = &AlterUserStmt{}
    34  	_ StmtNode = &AlterRangeStmt{}
    35  	_ StmtNode = &BeginStmt{}
    36  	_ StmtNode = &BinlogStmt{}
    37  	_ StmtNode = &CommitStmt{}
    38  	_ StmtNode = &CreateUserStmt{}
    39  	_ StmtNode = &DeallocateStmt{}
    40  	_ StmtNode = &DoStmt{}
    41  	_ StmtNode = &ExecuteStmt{}
    42  	_ StmtNode = &ExplainStmt{}
    43  	_ StmtNode = &GrantStmt{}
    44  	_ StmtNode = &PrepareStmt{}
    45  	_ StmtNode = &RollbackStmt{}
    46  	_ StmtNode = &SetPwdStmt{}
    47  	_ StmtNode = &SetRoleStmt{}
    48  	_ StmtNode = &SetDefaultRoleStmt{}
    49  	_ StmtNode = &SetStmt{}
    50  	_ StmtNode = &SetSessionStatesStmt{}
    51  	_ StmtNode = &UseStmt{}
    52  	_ StmtNode = &FlushStmt{}
    53  	_ StmtNode = &KillStmt{}
    54  	_ StmtNode = &CreateBindingStmt{}
    55  	_ StmtNode = &DropBindingStmt{}
    56  	_ StmtNode = &SetBindingStmt{}
    57  	_ StmtNode = &ShutdownStmt{}
    58  	_ StmtNode = &RestartStmt{}
    59  	_ StmtNode = &RenameUserStmt{}
    60  	_ StmtNode = &HelpStmt{}
    61  	_ StmtNode = &PlanReplayerStmt{}
    62  	_ StmtNode = &CompactTableStmt{}
    63  	_ StmtNode = &SetResourceGroupStmt{}
    64  
    65  	_ Node = &PrivElem{}
    66  	_ Node = &VariableAssignment{}
    67  )
    68  
    69  // Isolation level constants.
    70  const (
    71  	ReadCommitted   = "READ-COMMITTED"
    72  	ReadUncommitted = "READ-UNCOMMITTED"
    73  	Serializable    = "SERIALIZABLE"
    74  	RepeatableRead  = "REPEATABLE-READ"
    75  
    76  	PumpType    = "PUMP"
    77  	DrainerType = "DRAINER"
    78  )
    79  
    80  // Transaction mode constants.
    81  const (
    82  	Optimistic  = "OPTIMISTIC"
    83  	Pessimistic = "PESSIMISTIC"
    84  )
    85  
    86  // TypeOpt is used for parsing data type option from SQL.
    87  type TypeOpt struct {
    88  	IsUnsigned bool
    89  	IsZerofill bool
    90  }
    91  
    92  // FloatOpt is used for parsing floating-point type option from SQL.
    93  // See http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html
    94  type FloatOpt struct {
    95  	Flen    int
    96  	Decimal int
    97  }
    98  
    99  // AuthOption is used for parsing create use statement.
   100  type AuthOption struct {
   101  	// ByAuthString set as true, if AuthString is used for authorization. Otherwise, authorization is done by HashString.
   102  	ByAuthString bool
   103  	AuthString   string
   104  	ByHashString bool
   105  	HashString   string
   106  	AuthPlugin   string
   107  }
   108  
   109  // Restore implements Node interface.
   110  func (n *AuthOption) Restore(ctx *format.RestoreCtx) error {
   111  	ctx.WriteKeyWord("IDENTIFIED")
   112  	if n.AuthPlugin != "" {
   113  		ctx.WriteKeyWord(" WITH ")
   114  		ctx.WriteString(n.AuthPlugin)
   115  	}
   116  	if n.ByAuthString {
   117  		ctx.WriteKeyWord(" BY ")
   118  		ctx.WriteString(n.AuthString)
   119  	} else if n.ByHashString {
   120  		ctx.WriteKeyWord(" AS ")
   121  		ctx.WriteString(n.HashString)
   122  	}
   123  	return nil
   124  }
   125  
   126  // TraceStmt is a statement to trace what sql actually does at background.
   127  type TraceStmt struct {
   128  	stmtNode
   129  
   130  	Stmt   StmtNode
   131  	Format string
   132  
   133  	TracePlan       bool
   134  	TracePlanTarget string
   135  }
   136  
   137  // Restore implements Node interface.
   138  func (n *TraceStmt) Restore(ctx *format.RestoreCtx) error {
   139  	ctx.WriteKeyWord("TRACE ")
   140  	if n.TracePlan {
   141  		ctx.WriteKeyWord("PLAN ")
   142  		if n.TracePlanTarget != "" {
   143  			ctx.WriteKeyWord("TARGET")
   144  			ctx.WritePlain(" = ")
   145  			ctx.WriteString(n.TracePlanTarget)
   146  			ctx.WritePlain(" ")
   147  		}
   148  	} else if n.Format != "row" {
   149  		ctx.WriteKeyWord("FORMAT")
   150  		ctx.WritePlain(" = ")
   151  		ctx.WriteString(n.Format)
   152  		ctx.WritePlain(" ")
   153  	}
   154  	if err := n.Stmt.Restore(ctx); err != nil {
   155  		return errors.Annotate(err, "An error occurred while restore TraceStmt.Stmt")
   156  	}
   157  	return nil
   158  }
   159  
   160  // Accept implements Node Accept interface.
   161  func (n *TraceStmt) Accept(v Visitor) (Node, bool) {
   162  	newNode, skipChildren := v.Enter(n)
   163  	if skipChildren {
   164  		return v.Leave(newNode)
   165  	}
   166  	n = newNode.(*TraceStmt)
   167  	node, ok := n.Stmt.Accept(v)
   168  	if !ok {
   169  		return n, false
   170  	}
   171  	n.Stmt = node.(StmtNode)
   172  	return v.Leave(n)
   173  }
   174  
   175  // ExplainForStmt is a statement to provite information about how is SQL statement executeing
   176  // in connection #ConnectionID
   177  // See https://dev.mysql.com/doc/refman/5.7/en/explain.html
   178  type ExplainForStmt struct {
   179  	stmtNode
   180  
   181  	Format       string
   182  	ConnectionID uint64
   183  }
   184  
   185  // Restore implements Node interface.
   186  func (n *ExplainForStmt) Restore(ctx *format.RestoreCtx) error {
   187  	ctx.WriteKeyWord("EXPLAIN ")
   188  	ctx.WriteKeyWord("FORMAT ")
   189  	ctx.WritePlain("= ")
   190  	ctx.WriteString(n.Format)
   191  	ctx.WritePlain(" ")
   192  	ctx.WriteKeyWord("FOR ")
   193  	ctx.WriteKeyWord("CONNECTION ")
   194  	ctx.WritePlain(strconv.FormatUint(n.ConnectionID, 10))
   195  	return nil
   196  }
   197  
   198  // Accept implements Node Accept interface.
   199  func (n *ExplainForStmt) Accept(v Visitor) (Node, bool) {
   200  	newNode, skipChildren := v.Enter(n)
   201  	if skipChildren {
   202  		return v.Leave(newNode)
   203  	}
   204  	n = newNode.(*ExplainForStmt)
   205  	return v.Leave(n)
   206  }
   207  
   208  // ExplainStmt is a statement to provide information about how is SQL statement executed
   209  // or get columns information in a table.
   210  // See https://dev.mysql.com/doc/refman/5.7/en/explain.html
   211  type ExplainStmt struct {
   212  	stmtNode
   213  
   214  	Stmt    StmtNode
   215  	Format  string
   216  	Analyze bool
   217  }
   218  
   219  // Restore implements Node interface.
   220  func (n *ExplainStmt) Restore(ctx *format.RestoreCtx) error {
   221  	if showStmt, ok := n.Stmt.(*ShowStmt); ok {
   222  		ctx.WriteKeyWord("DESC ")
   223  		if err := showStmt.Table.Restore(ctx); err != nil {
   224  			return errors.Annotate(err, "An error occurred while restore ExplainStmt.ShowStmt.Table")
   225  		}
   226  		if showStmt.Column != nil {
   227  			ctx.WritePlain(" ")
   228  			if err := showStmt.Column.Restore(ctx); err != nil {
   229  				return errors.Annotate(err, "An error occurred while restore ExplainStmt.ShowStmt.Column")
   230  			}
   231  		}
   232  		return nil
   233  	}
   234  	ctx.WriteKeyWord("EXPLAIN ")
   235  	if n.Analyze {
   236  		ctx.WriteKeyWord("ANALYZE ")
   237  	}
   238  	if !n.Analyze || strings.ToLower(n.Format) != "row" {
   239  		ctx.WriteKeyWord("FORMAT ")
   240  		ctx.WritePlain("= ")
   241  		ctx.WriteString(n.Format)
   242  		ctx.WritePlain(" ")
   243  	}
   244  	if err := n.Stmt.Restore(ctx); err != nil {
   245  		return errors.Annotate(err, "An error occurred while restore ExplainStmt.Stmt")
   246  	}
   247  	return nil
   248  }
   249  
   250  // Accept implements Node Accept interface.
   251  func (n *ExplainStmt) Accept(v Visitor) (Node, bool) {
   252  	newNode, skipChildren := v.Enter(n)
   253  	if skipChildren {
   254  		return v.Leave(newNode)
   255  	}
   256  	n = newNode.(*ExplainStmt)
   257  	node, ok := n.Stmt.Accept(v)
   258  	if !ok {
   259  		return n, false
   260  	}
   261  	n.Stmt = node.(StmtNode)
   262  	return v.Leave(n)
   263  }
   264  
   265  // PlanReplayerStmt is a statement to dump or load information for recreating plans
   266  type PlanReplayerStmt struct {
   267  	stmtNode
   268  
   269  	Stmt                StmtNode
   270  	Analyze             bool
   271  	Load                bool
   272  	HistoricalStatsInfo *AsOfClause
   273  
   274  	// Capture indicates 'plan replayer capture <sql_digest> <plan_digest>'
   275  	Capture bool
   276  	// Remove indicates `plan replayer capture remove <sql_digest> <plan_digest>
   277  	Remove bool
   278  
   279  	SQLDigest  string
   280  	PlanDigest string
   281  
   282  	// File is used to store 2 cases:
   283  	// 1. plan replayer load 'file';
   284  	// 2. plan replayer dump explain <analyze> 'file'
   285  	File string
   286  
   287  	// Fields below are currently useless.
   288  
   289  	// Where is the where clause in select statement.
   290  	Where ExprNode
   291  	// OrderBy is the ordering expression list.
   292  	OrderBy *OrderByClause
   293  	// Limit is the limit clause.
   294  	Limit *Limit
   295  }
   296  
   297  // Restore implements Node interface.
   298  func (n *PlanReplayerStmt) Restore(ctx *format.RestoreCtx) error {
   299  	if n.Load {
   300  		ctx.WriteKeyWord("PLAN REPLAYER LOAD ")
   301  		ctx.WriteString(n.File)
   302  		return nil
   303  	}
   304  	if n.Capture {
   305  		ctx.WriteKeyWord("PLAN REPLAYER CAPTURE ")
   306  		ctx.WriteString(n.SQLDigest)
   307  		ctx.WriteKeyWord(" ")
   308  		ctx.WriteString(n.PlanDigest)
   309  		return nil
   310  	}
   311  	if n.Remove {
   312  		ctx.WriteKeyWord("PLAN REPLAYER CAPTURE REMOVE ")
   313  		ctx.WriteString(n.SQLDigest)
   314  		ctx.WriteKeyWord(" ")
   315  		ctx.WriteString(n.PlanDigest)
   316  		return nil
   317  	}
   318  
   319  	ctx.WriteKeyWord("PLAN REPLAYER DUMP ")
   320  
   321  	if n.HistoricalStatsInfo != nil {
   322  		ctx.WriteKeyWord("WITH STATS ")
   323  		if err := n.HistoricalStatsInfo.Restore(ctx); err != nil {
   324  			return errors.Annotate(err, "An error occurred while restore PlanReplayerStmt.HistoricalStatsInfo")
   325  		}
   326  		ctx.WriteKeyWord(" ")
   327  	}
   328  	if n.Analyze {
   329  		ctx.WriteKeyWord("EXPLAIN ANALYZE ")
   330  	} else {
   331  		ctx.WriteKeyWord("EXPLAIN ")
   332  	}
   333  	if n.Stmt == nil {
   334  		if len(n.File) > 0 {
   335  			ctx.WriteString(n.File)
   336  			return nil
   337  		}
   338  		ctx.WriteKeyWord("SLOW QUERY")
   339  		if n.Where != nil {
   340  			ctx.WriteKeyWord(" WHERE ")
   341  			if err := n.Where.Restore(ctx); err != nil {
   342  				return errors.Annotate(err, "An error occurred while restore PlanReplayerStmt.Where")
   343  			}
   344  		}
   345  		if n.OrderBy != nil {
   346  			ctx.WriteKeyWord(" ")
   347  			if err := n.OrderBy.Restore(ctx); err != nil {
   348  				return errors.Annotate(err, "An error occurred while restore PlanReplayerStmt.OrderBy")
   349  			}
   350  		}
   351  		if n.Limit != nil {
   352  			ctx.WriteKeyWord(" ")
   353  			if err := n.Limit.Restore(ctx); err != nil {
   354  				return errors.Annotate(err, "An error occurred while restore PlanReplayerStmt.Limit")
   355  			}
   356  		}
   357  		return nil
   358  	}
   359  	if err := n.Stmt.Restore(ctx); err != nil {
   360  		return errors.Annotate(err, "An error occurred while restore PlanReplayerStmt.Stmt")
   361  	}
   362  	return nil
   363  }
   364  
   365  // Accept implements Node Accept interface.
   366  func (n *PlanReplayerStmt) Accept(v Visitor) (Node, bool) {
   367  	newNode, skipChildren := v.Enter(n)
   368  	if skipChildren {
   369  		return v.Leave(newNode)
   370  	}
   371  
   372  	n = newNode.(*PlanReplayerStmt)
   373  
   374  	if n.Load {
   375  		return v.Leave(n)
   376  	}
   377  
   378  	if n.HistoricalStatsInfo != nil {
   379  		info, ok := n.HistoricalStatsInfo.Accept(v)
   380  		if !ok {
   381  			return n, false
   382  		}
   383  		n.HistoricalStatsInfo = info.(*AsOfClause)
   384  	}
   385  
   386  	if n.Stmt == nil {
   387  		if n.Where != nil {
   388  			node, ok := n.Where.Accept(v)
   389  			if !ok {
   390  				return n, false
   391  			}
   392  			n.Where = node.(ExprNode)
   393  		}
   394  
   395  		if n.OrderBy != nil {
   396  			node, ok := n.OrderBy.Accept(v)
   397  			if !ok {
   398  				return n, false
   399  			}
   400  			n.OrderBy = node.(*OrderByClause)
   401  		}
   402  
   403  		if n.Limit != nil {
   404  			node, ok := n.Limit.Accept(v)
   405  			if !ok {
   406  				return n, false
   407  			}
   408  			n.Limit = node.(*Limit)
   409  		}
   410  		return v.Leave(n)
   411  	}
   412  
   413  	node, ok := n.Stmt.Accept(v)
   414  	if !ok {
   415  		return n, false
   416  	}
   417  	n.Stmt = node.(StmtNode)
   418  	return v.Leave(n)
   419  }
   420  
   421  type CompactReplicaKind string
   422  
   423  const (
   424  	// CompactReplicaKindAll means compacting both TiKV and TiFlash replicas.
   425  	CompactReplicaKindAll = "ALL"
   426  
   427  	// CompactReplicaKindTiFlash means compacting TiFlash replicas.
   428  	CompactReplicaKindTiFlash = "TIFLASH"
   429  
   430  	// CompactReplicaKindTiKV means compacting TiKV replicas.
   431  	CompactReplicaKindTiKV = "TIKV"
   432  )
   433  
   434  // CompactTableStmt is a statement to manually compact a table.
   435  type CompactTableStmt struct {
   436  	stmtNode
   437  
   438  	Table          *TableName
   439  	PartitionNames []model.CIStr
   440  	ReplicaKind    CompactReplicaKind
   441  }
   442  
   443  // Restore implements Node interface.
   444  func (n *CompactTableStmt) Restore(ctx *format.RestoreCtx) error {
   445  	ctx.WriteKeyWord("ALTER TABLE ")
   446  	n.Table.restoreName(ctx)
   447  
   448  	ctx.WriteKeyWord(" COMPACT")
   449  	if len(n.PartitionNames) != 0 {
   450  		ctx.WriteKeyWord(" PARTITION ")
   451  		for i, partition := range n.PartitionNames {
   452  			if i != 0 {
   453  				ctx.WritePlain(",")
   454  			}
   455  			ctx.WriteName(partition.O)
   456  		}
   457  	}
   458  	if n.ReplicaKind != CompactReplicaKindAll {
   459  		ctx.WriteKeyWord(" ")
   460  		// Note: There is only TiFlash replica available now. TiKV will be added later.
   461  		ctx.WriteKeyWord(string(n.ReplicaKind))
   462  		ctx.WriteKeyWord(" REPLICA")
   463  	}
   464  	return nil
   465  }
   466  
   467  // Accept implements Node Accept interface.
   468  func (n *CompactTableStmt) Accept(v Visitor) (Node, bool) {
   469  	newNode, skipChildren := v.Enter(n)
   470  	if skipChildren {
   471  		return v.Leave(newNode)
   472  	}
   473  	n = newNode.(*CompactTableStmt)
   474  	node, ok := n.Table.Accept(v)
   475  	if !ok {
   476  		return n, false
   477  	}
   478  	n.Table = node.(*TableName)
   479  	return v.Leave(n)
   480  }
   481  
   482  // PrepareStmt is a statement to prepares a SQL statement which contains placeholders,
   483  // and it is executed with ExecuteStmt and released with DeallocateStmt.
   484  // See https://dev.mysql.com/doc/refman/5.7/en/prepare.html
   485  type PrepareStmt struct {
   486  	stmtNode
   487  
   488  	Name    string
   489  	SQLText string
   490  	SQLVar  *VariableExpr
   491  }
   492  
   493  // Restore implements Node interface.
   494  func (n *PrepareStmt) Restore(ctx *format.RestoreCtx) error {
   495  	ctx.WriteKeyWord("PREPARE ")
   496  	ctx.WriteName(n.Name)
   497  	ctx.WriteKeyWord(" FROM ")
   498  	if n.SQLText != "" {
   499  		ctx.WriteString(n.SQLText)
   500  		return nil
   501  	}
   502  	if n.SQLVar != nil {
   503  		if err := n.SQLVar.Restore(ctx); err != nil {
   504  			return errors.Annotate(err, "An error occurred while restore PrepareStmt.SQLVar")
   505  		}
   506  		return nil
   507  	}
   508  	return errors.New("An error occurred while restore PrepareStmt")
   509  }
   510  
   511  // Accept implements Node Accept interface.
   512  func (n *PrepareStmt) Accept(v Visitor) (Node, bool) {
   513  	newNode, skipChildren := v.Enter(n)
   514  	if skipChildren {
   515  		return v.Leave(newNode)
   516  	}
   517  	n = newNode.(*PrepareStmt)
   518  	if n.SQLVar != nil {
   519  		node, ok := n.SQLVar.Accept(v)
   520  		if !ok {
   521  			return n, false
   522  		}
   523  		n.SQLVar = node.(*VariableExpr)
   524  	}
   525  	return v.Leave(n)
   526  }
   527  
   528  // DeallocateStmt is a statement to release PreparedStmt.
   529  // See https://dev.mysql.com/doc/refman/5.7/en/deallocate-prepare.html
   530  type DeallocateStmt struct {
   531  	stmtNode
   532  
   533  	Name string
   534  }
   535  
   536  // Restore implements Node interface.
   537  func (n *DeallocateStmt) Restore(ctx *format.RestoreCtx) error {
   538  	ctx.WriteKeyWord("DEALLOCATE PREPARE ")
   539  	ctx.WriteName(n.Name)
   540  	return nil
   541  }
   542  
   543  // Accept implements Node Accept interface.
   544  func (n *DeallocateStmt) Accept(v Visitor) (Node, bool) {
   545  	newNode, skipChildren := v.Enter(n)
   546  	if skipChildren {
   547  		return v.Leave(newNode)
   548  	}
   549  	n = newNode.(*DeallocateStmt)
   550  	return v.Leave(n)
   551  }
   552  
   553  // Prepared represents a prepared statement.
   554  type Prepared struct {
   555  	Stmt          StmtNode
   556  	StmtType      string
   557  	Params        []ParamMarkerExpr
   558  	SchemaVersion int64
   559  	CachedPlan    interface{}
   560  	CachedNames   interface{}
   561  }
   562  
   563  // ExecuteStmt is a statement to execute PreparedStmt.
   564  // See https://dev.mysql.com/doc/refman/5.7/en/execute.html
   565  type ExecuteStmt struct {
   566  	stmtNode
   567  
   568  	Name       string
   569  	UsingVars  []ExprNode
   570  	BinaryArgs interface{}
   571  	PrepStmt   interface{} // the corresponding prepared statement
   572  	IdxInMulti int
   573  
   574  	// FromGeneralStmt indicates whether this execute-stmt is converted from a general query.
   575  	// e.g. select * from t where a>2 --> execute 'select * from t where a>?' using 2
   576  	FromGeneralStmt bool
   577  }
   578  
   579  // Restore implements Node interface.
   580  func (n *ExecuteStmt) Restore(ctx *format.RestoreCtx) error {
   581  	ctx.WriteKeyWord("EXECUTE ")
   582  	ctx.WriteName(n.Name)
   583  	if len(n.UsingVars) > 0 {
   584  		ctx.WriteKeyWord(" USING ")
   585  		for i, val := range n.UsingVars {
   586  			if i != 0 {
   587  				ctx.WritePlain(",")
   588  			}
   589  			if err := val.Restore(ctx); err != nil {
   590  				return errors.Annotatef(err, "An error occurred while restore ExecuteStmt.UsingVars index %d", i)
   591  			}
   592  		}
   593  	}
   594  	return nil
   595  }
   596  
   597  // Accept implements Node Accept interface.
   598  func (n *ExecuteStmt) Accept(v Visitor) (Node, bool) {
   599  	newNode, skipChildren := v.Enter(n)
   600  	if skipChildren {
   601  		return v.Leave(newNode)
   602  	}
   603  	n = newNode.(*ExecuteStmt)
   604  	for i, val := range n.UsingVars {
   605  		node, ok := val.Accept(v)
   606  		if !ok {
   607  			return n, false
   608  		}
   609  		n.UsingVars[i] = node.(ExprNode)
   610  	}
   611  	return v.Leave(n)
   612  }
   613  
   614  // BeginStmt is a statement to start a new transaction.
   615  // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
   616  type BeginStmt struct {
   617  	stmtNode
   618  	Mode                  string
   619  	CausalConsistencyOnly bool
   620  	ReadOnly              bool
   621  	// AS OF is used to read the data at a specific point of time.
   622  	// Should only be used when ReadOnly is true.
   623  	AsOf *AsOfClause
   624  }
   625  
   626  // Restore implements Node interface.
   627  func (n *BeginStmt) Restore(ctx *format.RestoreCtx) error {
   628  	if n.Mode == "" {
   629  		if n.ReadOnly {
   630  			ctx.WriteKeyWord("START TRANSACTION READ ONLY")
   631  			if n.AsOf != nil {
   632  				ctx.WriteKeyWord(" ")
   633  				return n.AsOf.Restore(ctx)
   634  			}
   635  		} else if n.CausalConsistencyOnly {
   636  			ctx.WriteKeyWord("START TRANSACTION WITH CAUSAL CONSISTENCY ONLY")
   637  		} else {
   638  			ctx.WriteKeyWord("START TRANSACTION")
   639  		}
   640  	} else {
   641  		ctx.WriteKeyWord("BEGIN ")
   642  		ctx.WriteKeyWord(n.Mode)
   643  	}
   644  	return nil
   645  }
   646  
   647  // Accept implements Node Accept interface.
   648  func (n *BeginStmt) Accept(v Visitor) (Node, bool) {
   649  	newNode, skipChildren := v.Enter(n)
   650  	if skipChildren {
   651  		return v.Leave(newNode)
   652  	}
   653  
   654  	if n.AsOf != nil {
   655  		node, ok := n.AsOf.Accept(v)
   656  		if !ok {
   657  			return n, false
   658  		}
   659  		n.AsOf = node.(*AsOfClause)
   660  	}
   661  
   662  	n = newNode.(*BeginStmt)
   663  	return v.Leave(n)
   664  }
   665  
   666  // BinlogStmt is an internal-use statement.
   667  // We just parse and ignore it.
   668  // See http://dev.mysql.com/doc/refman/5.7/en/binlog.html
   669  type BinlogStmt struct {
   670  	stmtNode
   671  	Str string
   672  }
   673  
   674  // Restore implements Node interface.
   675  func (n *BinlogStmt) Restore(ctx *format.RestoreCtx) error {
   676  	ctx.WriteKeyWord("BINLOG ")
   677  	ctx.WriteString(n.Str)
   678  	return nil
   679  }
   680  
   681  // Accept implements Node Accept interface.
   682  func (n *BinlogStmt) Accept(v Visitor) (Node, bool) {
   683  	newNode, skipChildren := v.Enter(n)
   684  	if skipChildren {
   685  		return v.Leave(newNode)
   686  	}
   687  	n = newNode.(*BinlogStmt)
   688  	return v.Leave(n)
   689  }
   690  
   691  // CompletionType defines completion_type used in COMMIT and ROLLBACK statements
   692  type CompletionType int8
   693  
   694  const (
   695  	// CompletionTypeDefault refers to NO_CHAIN
   696  	CompletionTypeDefault CompletionType = iota
   697  	CompletionTypeChain
   698  	CompletionTypeRelease
   699  )
   700  
   701  func (n CompletionType) Restore(ctx *format.RestoreCtx) error {
   702  	switch n {
   703  	case CompletionTypeDefault:
   704  	case CompletionTypeChain:
   705  		ctx.WriteKeyWord(" AND CHAIN")
   706  	case CompletionTypeRelease:
   707  		ctx.WriteKeyWord(" RELEASE")
   708  	}
   709  	return nil
   710  }
   711  
   712  // CommitStmt is a statement to commit the current transaction.
   713  // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
   714  type CommitStmt struct {
   715  	stmtNode
   716  	// CompletionType overwrites system variable `completion_type` within transaction
   717  	CompletionType CompletionType
   718  }
   719  
   720  // Restore implements Node interface.
   721  func (n *CommitStmt) Restore(ctx *format.RestoreCtx) error {
   722  	ctx.WriteKeyWord("COMMIT")
   723  	if err := n.CompletionType.Restore(ctx); err != nil {
   724  		return errors.Annotate(err, "An error occurred while restore CommitStmt.CompletionType")
   725  	}
   726  	return nil
   727  }
   728  
   729  // Accept implements Node Accept interface.
   730  func (n *CommitStmt) Accept(v Visitor) (Node, bool) {
   731  	newNode, skipChildren := v.Enter(n)
   732  	if skipChildren {
   733  		return v.Leave(newNode)
   734  	}
   735  	n = newNode.(*CommitStmt)
   736  	return v.Leave(n)
   737  }
   738  
   739  // RollbackStmt is a statement to roll back the current transaction.
   740  // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
   741  type RollbackStmt struct {
   742  	stmtNode
   743  	// CompletionType overwrites system variable `completion_type` within transaction
   744  	CompletionType CompletionType
   745  	// SavepointName is the savepoint name.
   746  	SavepointName string
   747  }
   748  
   749  // Restore implements Node interface.
   750  func (n *RollbackStmt) Restore(ctx *format.RestoreCtx) error {
   751  	ctx.WriteKeyWord("ROLLBACK")
   752  	if n.SavepointName != "" {
   753  		ctx.WritePlain(" TO ")
   754  		ctx.WritePlain(n.SavepointName)
   755  	}
   756  	if err := n.CompletionType.Restore(ctx); err != nil {
   757  		return errors.Annotate(err, "An error occurred while restore RollbackStmt.CompletionType")
   758  	}
   759  	return nil
   760  }
   761  
   762  // Accept implements Node Accept interface.
   763  func (n *RollbackStmt) Accept(v Visitor) (Node, bool) {
   764  	newNode, skipChildren := v.Enter(n)
   765  	if skipChildren {
   766  		return v.Leave(newNode)
   767  	}
   768  	n = newNode.(*RollbackStmt)
   769  	return v.Leave(n)
   770  }
   771  
   772  // UseStmt is a statement to use the DBName database as the current database.
   773  // See https://dev.mysql.com/doc/refman/5.7/en/use.html
   774  type UseStmt struct {
   775  	stmtNode
   776  
   777  	DBName string
   778  }
   779  
   780  // Restore implements Node interface.
   781  func (n *UseStmt) Restore(ctx *format.RestoreCtx) error {
   782  	ctx.WriteKeyWord("USE ")
   783  	ctx.WriteName(n.DBName)
   784  	return nil
   785  }
   786  
   787  // Accept implements Node Accept interface.
   788  func (n *UseStmt) Accept(v Visitor) (Node, bool) {
   789  	newNode, skipChildren := v.Enter(n)
   790  	if skipChildren {
   791  		return v.Leave(newNode)
   792  	}
   793  	n = newNode.(*UseStmt)
   794  	return v.Leave(n)
   795  }
   796  
   797  const (
   798  	// SetNames is the const for set names stmt.
   799  	// If VariableAssignment.Name == Names, it should be set names stmt.
   800  	SetNames = "SetNAMES"
   801  	// SetCharset is the const for set charset stmt.
   802  	SetCharset = "SetCharset"
   803  )
   804  
   805  // VariableAssignment is a variable assignment struct.
   806  type VariableAssignment struct {
   807  	node
   808  	Name     string
   809  	Value    ExprNode
   810  	IsGlobal bool
   811  	IsSystem bool
   812  
   813  	// ExtendValue is a way to store extended info.
   814  	// VariableAssignment should be able to store information for SetCharset/SetPWD Stmt.
   815  	// For SetCharsetStmt, Value is charset, ExtendValue is collation.
   816  	// TODO: Use SetStmt to implement set password statement.
   817  	ExtendValue ValueExpr
   818  }
   819  
   820  // Restore implements Node interface.
   821  func (n *VariableAssignment) Restore(ctx *format.RestoreCtx) error {
   822  	if n.IsSystem {
   823  		ctx.WritePlain("@@")
   824  		if n.IsGlobal {
   825  			ctx.WriteKeyWord("GLOBAL")
   826  		} else {
   827  			ctx.WriteKeyWord("SESSION")
   828  		}
   829  		ctx.WritePlain(".")
   830  	} else if n.Name != SetNames && n.Name != SetCharset {
   831  		ctx.WriteKeyWord("@")
   832  	}
   833  	if n.Name == SetNames {
   834  		ctx.WriteKeyWord("NAMES ")
   835  	} else if n.Name == SetCharset {
   836  		ctx.WriteKeyWord("CHARSET ")
   837  	} else {
   838  		ctx.WriteName(n.Name)
   839  		ctx.WritePlain("=")
   840  	}
   841  	if err := n.Value.Restore(ctx); err != nil {
   842  		return errors.Annotate(err, "An error occurred while restore VariableAssignment.Value")
   843  	}
   844  	if n.ExtendValue != nil {
   845  		ctx.WriteKeyWord(" COLLATE ")
   846  		if err := n.ExtendValue.Restore(ctx); err != nil {
   847  			return errors.Annotate(err, "An error occurred while restore VariableAssignment.ExtendValue")
   848  		}
   849  	}
   850  	return nil
   851  }
   852  
   853  // Accept implements Node interface.
   854  func (n *VariableAssignment) Accept(v Visitor) (Node, bool) {
   855  	newNode, skipChildren := v.Enter(n)
   856  	if skipChildren {
   857  		return v.Leave(newNode)
   858  	}
   859  	n = newNode.(*VariableAssignment)
   860  	node, ok := n.Value.Accept(v)
   861  	if !ok {
   862  		return n, false
   863  	}
   864  	n.Value = node.(ExprNode)
   865  	return v.Leave(n)
   866  }
   867  
   868  // FlushStmtType is the type for FLUSH statement.
   869  type FlushStmtType int
   870  
   871  // Flush statement types.
   872  const (
   873  	FlushNone FlushStmtType = iota
   874  	FlushTables
   875  	FlushPrivileges
   876  	FlushStatus
   877  	FlushTiDBPlugin
   878  	FlushHosts
   879  	FlushLogs
   880  	FlushClientErrorsSummary
   881  )
   882  
   883  // LogType is the log type used in FLUSH statement.
   884  type LogType int8
   885  
   886  const (
   887  	LogTypeDefault LogType = iota
   888  	LogTypeBinary
   889  	LogTypeEngine
   890  	LogTypeError
   891  	LogTypeGeneral
   892  	LogTypeSlow
   893  )
   894  
   895  // FlushStmt is a statement to flush tables/privileges/optimizer costs and so on.
   896  type FlushStmt struct {
   897  	stmtNode
   898  
   899  	Tp              FlushStmtType // Privileges/Tables/...
   900  	NoWriteToBinLog bool
   901  	LogType         LogType
   902  	Tables          []*TableName // For FlushTableStmt, if Tables is empty, it means flush all tables.
   903  	ReadLock        bool
   904  	Plugins         []string
   905  }
   906  
   907  // Restore implements Node interface.
   908  func (n *FlushStmt) Restore(ctx *format.RestoreCtx) error {
   909  	ctx.WriteKeyWord("FLUSH ")
   910  	if n.NoWriteToBinLog {
   911  		ctx.WriteKeyWord("NO_WRITE_TO_BINLOG ")
   912  	}
   913  	switch n.Tp {
   914  	case FlushTables:
   915  		ctx.WriteKeyWord("TABLES")
   916  		for i, v := range n.Tables {
   917  			if i == 0 {
   918  				ctx.WritePlain(" ")
   919  			} else {
   920  				ctx.WritePlain(", ")
   921  			}
   922  			if err := v.Restore(ctx); err != nil {
   923  				return errors.Annotatef(err, "An error occurred while restore FlushStmt.Tables[%d]", i)
   924  			}
   925  		}
   926  		if n.ReadLock {
   927  			ctx.WriteKeyWord(" WITH READ LOCK")
   928  		}
   929  	case FlushPrivileges:
   930  		ctx.WriteKeyWord("PRIVILEGES")
   931  	case FlushStatus:
   932  		ctx.WriteKeyWord("STATUS")
   933  	case FlushTiDBPlugin:
   934  		ctx.WriteKeyWord("TIDB PLUGINS")
   935  		for i, v := range n.Plugins {
   936  			if i == 0 {
   937  				ctx.WritePlain(" ")
   938  			} else {
   939  				ctx.WritePlain(", ")
   940  			}
   941  			ctx.WritePlain(v)
   942  		}
   943  	case FlushHosts:
   944  		ctx.WriteKeyWord("HOSTS")
   945  	case FlushLogs:
   946  		var logType string
   947  		switch n.LogType {
   948  		case LogTypeDefault:
   949  			logType = "LOGS"
   950  		case LogTypeBinary:
   951  			logType = "BINARY LOGS"
   952  		case LogTypeEngine:
   953  			logType = "ENGINE LOGS"
   954  		case LogTypeError:
   955  			logType = "ERROR LOGS"
   956  		case LogTypeGeneral:
   957  			logType = "GENERAL LOGS"
   958  		case LogTypeSlow:
   959  			logType = "SLOW LOGS"
   960  		}
   961  		ctx.WriteKeyWord(logType)
   962  	case FlushClientErrorsSummary:
   963  		ctx.WriteKeyWord("CLIENT_ERRORS_SUMMARY")
   964  	default:
   965  		return errors.New("Unsupported type of FlushStmt")
   966  	}
   967  	return nil
   968  }
   969  
   970  // Accept implements Node Accept interface.
   971  func (n *FlushStmt) Accept(v Visitor) (Node, bool) {
   972  	newNode, skipChildren := v.Enter(n)
   973  	if skipChildren {
   974  		return v.Leave(newNode)
   975  	}
   976  	n = newNode.(*FlushStmt)
   977  	return v.Leave(n)
   978  }
   979  
   980  // KillStmt is a statement to kill a query or connection.
   981  type KillStmt struct {
   982  	stmtNode
   983  
   984  	// Query indicates whether terminate a single query on this connection or the whole connection.
   985  	// If Query is true, terminates the statement the connection is currently executing, but leaves the connection itself intact.
   986  	// If Query is false, terminates the connection associated with the given ConnectionID, after terminating any statement the connection is executing.
   987  	Query        bool
   988  	ConnectionID uint64
   989  	// TiDBExtension is used to indicate whether the user knows he is sending kill statement to the right tidb-server.
   990  	// When the SQL grammar is "KILL TIDB [CONNECTION | QUERY] connectionID", TiDBExtension will be set.
   991  	// It's a special grammar extension in TiDB. This extension exists because, when the connection is:
   992  	// client -> LVS proxy -> TiDB, and type Ctrl+C in client, the following action will be executed:
   993  	// new a connection; kill xxx;
   994  	// kill command may send to the wrong TiDB, because the exists of LVS proxy, and kill the wrong session.
   995  	// So, "KILL TIDB" grammar is introduced, and it REQUIRES DIRECT client -> TiDB TOPOLOGY.
   996  	// TODO: The standard KILL grammar will be supported once we have global connectionID.
   997  	TiDBExtension bool
   998  
   999  	Expr ExprNode
  1000  }
  1001  
  1002  // Restore implements Node interface.
  1003  func (n *KillStmt) Restore(ctx *format.RestoreCtx) error {
  1004  	ctx.WriteKeyWord("KILL")
  1005  	if n.TiDBExtension {
  1006  		ctx.WriteKeyWord(" TIDB")
  1007  	}
  1008  	if n.Query {
  1009  		ctx.WriteKeyWord(" QUERY")
  1010  	}
  1011  	if n.Expr != nil {
  1012  		ctx.WriteKeyWord(" ")
  1013  		if err := n.Expr.Restore(ctx); err != nil {
  1014  			return errors.Trace(err)
  1015  		}
  1016  	} else {
  1017  		ctx.WritePlainf(" %d", n.ConnectionID)
  1018  	}
  1019  	return nil
  1020  }
  1021  
  1022  // Accept implements Node Accept interface.
  1023  func (n *KillStmt) Accept(v Visitor) (Node, bool) {
  1024  	newNode, skipChildren := v.Enter(n)
  1025  	if skipChildren {
  1026  		return v.Leave(newNode)
  1027  	}
  1028  	n = newNode.(*KillStmt)
  1029  	return v.Leave(n)
  1030  }
  1031  
  1032  // SavepointStmt is the statement of SAVEPOINT.
  1033  type SavepointStmt struct {
  1034  	stmtNode
  1035  	// Name is the savepoint name.
  1036  	Name string
  1037  }
  1038  
  1039  // Restore implements Node interface.
  1040  func (n *SavepointStmt) Restore(ctx *format.RestoreCtx) error {
  1041  	ctx.WriteKeyWord("SAVEPOINT ")
  1042  	ctx.WritePlain(n.Name)
  1043  	return nil
  1044  }
  1045  
  1046  // Accept implements Node Accept interface.
  1047  func (n *SavepointStmt) Accept(v Visitor) (Node, bool) {
  1048  	newNode, _ := v.Enter(n)
  1049  	n = newNode.(*SavepointStmt)
  1050  	return v.Leave(n)
  1051  }
  1052  
  1053  // ReleaseSavepointStmt is the statement of RELEASE SAVEPOINT.
  1054  type ReleaseSavepointStmt struct {
  1055  	stmtNode
  1056  	// Name is the savepoint name.
  1057  	Name string
  1058  }
  1059  
  1060  // Restore implements Node interface.
  1061  func (n *ReleaseSavepointStmt) Restore(ctx *format.RestoreCtx) error {
  1062  	ctx.WriteKeyWord("RELEASE SAVEPOINT ")
  1063  	ctx.WritePlain(n.Name)
  1064  	return nil
  1065  }
  1066  
  1067  // Accept implements Node Accept interface.
  1068  func (n *ReleaseSavepointStmt) Accept(v Visitor) (Node, bool) {
  1069  	newNode, _ := v.Enter(n)
  1070  	n = newNode.(*ReleaseSavepointStmt)
  1071  	return v.Leave(n)
  1072  }
  1073  
  1074  // SetStmt is the statement to set variables.
  1075  type SetStmt struct {
  1076  	stmtNode
  1077  	// Variables is the list of variable assignment.
  1078  	Variables []*VariableAssignment
  1079  }
  1080  
  1081  // Restore implements Node interface.
  1082  func (n *SetStmt) Restore(ctx *format.RestoreCtx) error {
  1083  	ctx.WriteKeyWord("SET ")
  1084  	for i, v := range n.Variables {
  1085  		if i != 0 {
  1086  			ctx.WritePlain(", ")
  1087  		}
  1088  		if err := v.Restore(ctx); err != nil {
  1089  			return errors.Annotatef(err, "An error occurred while restore SetStmt.Variables[%d]", i)
  1090  		}
  1091  	}
  1092  	return nil
  1093  }
  1094  
  1095  // Accept implements Node Accept interface.
  1096  func (n *SetStmt) Accept(v Visitor) (Node, bool) {
  1097  	newNode, skipChildren := v.Enter(n)
  1098  	if skipChildren {
  1099  		return v.Leave(newNode)
  1100  	}
  1101  	n = newNode.(*SetStmt)
  1102  	for i, val := range n.Variables {
  1103  		node, ok := val.Accept(v)
  1104  		if !ok {
  1105  			return n, false
  1106  		}
  1107  		n.Variables[i] = node.(*VariableAssignment)
  1108  	}
  1109  	return v.Leave(n)
  1110  }
  1111  
  1112  // SetConfigStmt is the statement to set cluster configs.
  1113  type SetConfigStmt struct {
  1114  	stmtNode
  1115  
  1116  	Type     string // TiDB, TiKV, PD
  1117  	Instance string // '127.0.0.1:3306'
  1118  	Name     string // the variable name
  1119  	Value    ExprNode
  1120  }
  1121  
  1122  func (n *SetConfigStmt) Restore(ctx *format.RestoreCtx) error {
  1123  	ctx.WriteKeyWord("SET CONFIG ")
  1124  	if n.Type != "" {
  1125  		ctx.WriteKeyWord(n.Type)
  1126  	} else {
  1127  		ctx.WriteString(n.Instance)
  1128  	}
  1129  	ctx.WritePlain(" ")
  1130  	ctx.WriteKeyWord(n.Name)
  1131  	ctx.WritePlain(" = ")
  1132  	return n.Value.Restore(ctx)
  1133  }
  1134  
  1135  func (n *SetConfigStmt) Accept(v Visitor) (Node, bool) {
  1136  	newNode, skipChildren := v.Enter(n)
  1137  	if skipChildren {
  1138  		return v.Leave(newNode)
  1139  	}
  1140  	n = newNode.(*SetConfigStmt)
  1141  	node, ok := n.Value.Accept(v)
  1142  	if !ok {
  1143  		return n, false
  1144  	}
  1145  	n.Value = node.(ExprNode)
  1146  	return v.Leave(n)
  1147  }
  1148  
  1149  // SetSessionStatesStmt is a statement to restore session states.
  1150  type SetSessionStatesStmt struct {
  1151  	stmtNode
  1152  
  1153  	SessionStates string
  1154  }
  1155  
  1156  func (n *SetSessionStatesStmt) Restore(ctx *format.RestoreCtx) error {
  1157  	ctx.WriteKeyWord("SET SESSION_STATES ")
  1158  	ctx.WriteString(n.SessionStates)
  1159  	return nil
  1160  }
  1161  
  1162  func (n *SetSessionStatesStmt) Accept(v Visitor) (Node, bool) {
  1163  	newNode, skipChildren := v.Enter(n)
  1164  	if skipChildren {
  1165  		return v.Leave(newNode)
  1166  	}
  1167  	n = newNode.(*SetSessionStatesStmt)
  1168  	return v.Leave(n)
  1169  }
  1170  
  1171  /*
  1172  // SetCharsetStmt is a statement to assign values to character and collation variables.
  1173  // See https://dev.mysql.com/doc/refman/5.7/en/set-statement.html
  1174  type SetCharsetStmt struct {
  1175  	stmtNode
  1176  
  1177  	Charset string
  1178  	Collate string
  1179  }
  1180  
  1181  // Accept implements Node Accept interface.
  1182  func (n *SetCharsetStmt) Accept(v Visitor) (Node, bool) {
  1183  	newNode, skipChildren := v.Enter(n)
  1184  	if skipChildren {
  1185  		return v.Leave(newNode)
  1186  	}
  1187  	n = newNode.(*SetCharsetStmt)
  1188  	return v.Leave(n)
  1189  }
  1190  */
  1191  
  1192  // SetPwdStmt is a statement to assign a password to user account.
  1193  // See https://dev.mysql.com/doc/refman/5.7/en/set-password.html
  1194  type SetPwdStmt struct {
  1195  	stmtNode
  1196  
  1197  	User     *auth.UserIdentity
  1198  	Password string
  1199  }
  1200  
  1201  // Restore implements Node interface.
  1202  func (n *SetPwdStmt) Restore(ctx *format.RestoreCtx) error {
  1203  	ctx.WriteKeyWord("SET PASSWORD")
  1204  	if n.User != nil {
  1205  		ctx.WriteKeyWord(" FOR ")
  1206  		if err := n.User.Restore(ctx); err != nil {
  1207  			return errors.Annotate(err, "An error occurred while restore SetPwdStmt.User")
  1208  		}
  1209  	}
  1210  	ctx.WritePlain("=")
  1211  	ctx.WriteString(n.Password)
  1212  	return nil
  1213  }
  1214  
  1215  // SecureText implements SensitiveStatement interface.
  1216  func (n *SetPwdStmt) SecureText() string {
  1217  	return fmt.Sprintf("set password for user %s", n.User)
  1218  }
  1219  
  1220  // Accept implements Node Accept interface.
  1221  func (n *SetPwdStmt) Accept(v Visitor) (Node, bool) {
  1222  	newNode, skipChildren := v.Enter(n)
  1223  	if skipChildren {
  1224  		return v.Leave(newNode)
  1225  	}
  1226  	n = newNode.(*SetPwdStmt)
  1227  	return v.Leave(n)
  1228  }
  1229  
  1230  type ChangeStmt struct {
  1231  	stmtNode
  1232  
  1233  	NodeType string
  1234  	State    string
  1235  	NodeID   string
  1236  }
  1237  
  1238  // Restore implements Node interface.
  1239  func (n *ChangeStmt) Restore(ctx *format.RestoreCtx) error {
  1240  	ctx.WriteKeyWord("CHANGE ")
  1241  	ctx.WriteKeyWord(n.NodeType)
  1242  	ctx.WriteKeyWord(" TO NODE_STATE ")
  1243  	ctx.WritePlain("=")
  1244  	ctx.WriteString(n.State)
  1245  	ctx.WriteKeyWord(" FOR NODE_ID ")
  1246  	ctx.WriteString(n.NodeID)
  1247  	return nil
  1248  }
  1249  
  1250  // SecureText implements SensitiveStatement interface.
  1251  func (n *ChangeStmt) SecureText() string {
  1252  	return fmt.Sprintf("change %s to node_state='%s' for node_id '%s'", strings.ToLower(n.NodeType), n.State, n.NodeID)
  1253  }
  1254  
  1255  // Accept implements Node Accept interface.
  1256  func (n *ChangeStmt) Accept(v Visitor) (Node, bool) {
  1257  	newNode, skipChildren := v.Enter(n)
  1258  	if skipChildren {
  1259  		return v.Leave(newNode)
  1260  	}
  1261  	n = newNode.(*ChangeStmt)
  1262  	return v.Leave(n)
  1263  }
  1264  
  1265  // SetRoleStmtType is the type for FLUSH statement.
  1266  type SetRoleStmtType int
  1267  
  1268  // SetRole statement types.
  1269  const (
  1270  	SetRoleDefault SetRoleStmtType = iota
  1271  	SetRoleNone
  1272  	SetRoleAll
  1273  	SetRoleAllExcept
  1274  	SetRoleRegular
  1275  )
  1276  
  1277  type SetRoleStmt struct {
  1278  	stmtNode
  1279  
  1280  	SetRoleOpt SetRoleStmtType
  1281  	RoleList   []*auth.RoleIdentity
  1282  }
  1283  
  1284  func (n *SetRoleStmt) Restore(ctx *format.RestoreCtx) error {
  1285  	ctx.WriteKeyWord("SET ROLE")
  1286  	switch n.SetRoleOpt {
  1287  	case SetRoleDefault:
  1288  		ctx.WriteKeyWord(" DEFAULT")
  1289  	case SetRoleNone:
  1290  		ctx.WriteKeyWord(" NONE")
  1291  	case SetRoleAll:
  1292  		ctx.WriteKeyWord(" ALL")
  1293  	case SetRoleAllExcept:
  1294  		ctx.WriteKeyWord(" ALL EXCEPT")
  1295  	}
  1296  	for i, role := range n.RoleList {
  1297  		ctx.WritePlain(" ")
  1298  		err := role.Restore(ctx)
  1299  		if err != nil {
  1300  			return errors.Annotate(err, "An error occurred while restore SetRoleStmt.RoleList")
  1301  		}
  1302  		if i != len(n.RoleList)-1 {
  1303  			ctx.WritePlain(",")
  1304  		}
  1305  	}
  1306  	return nil
  1307  }
  1308  
  1309  // Accept implements Node Accept interface.
  1310  func (n *SetRoleStmt) Accept(v Visitor) (Node, bool) {
  1311  	newNode, skipChildren := v.Enter(n)
  1312  	if skipChildren {
  1313  		return v.Leave(newNode)
  1314  	}
  1315  	n = newNode.(*SetRoleStmt)
  1316  	return v.Leave(n)
  1317  }
  1318  
  1319  type SetDefaultRoleStmt struct {
  1320  	stmtNode
  1321  
  1322  	SetRoleOpt SetRoleStmtType
  1323  	RoleList   []*auth.RoleIdentity
  1324  	UserList   []*auth.UserIdentity
  1325  }
  1326  
  1327  func (n *SetDefaultRoleStmt) Restore(ctx *format.RestoreCtx) error {
  1328  	ctx.WriteKeyWord("SET DEFAULT ROLE")
  1329  	switch n.SetRoleOpt {
  1330  	case SetRoleNone:
  1331  		ctx.WriteKeyWord(" NONE")
  1332  	case SetRoleAll:
  1333  		ctx.WriteKeyWord(" ALL")
  1334  	default:
  1335  	}
  1336  	for i, role := range n.RoleList {
  1337  		ctx.WritePlain(" ")
  1338  		err := role.Restore(ctx)
  1339  		if err != nil {
  1340  			return errors.Annotate(err, "An error occurred while restore SetDefaultRoleStmt.RoleList")
  1341  		}
  1342  		if i != len(n.RoleList)-1 {
  1343  			ctx.WritePlain(",")
  1344  		}
  1345  	}
  1346  	ctx.WritePlain(" TO")
  1347  	for i, user := range n.UserList {
  1348  		ctx.WritePlain(" ")
  1349  		err := user.Restore(ctx)
  1350  		if err != nil {
  1351  			return errors.Annotate(err, "An error occurred while restore SetDefaultRoleStmt.UserList")
  1352  		}
  1353  		if i != len(n.UserList)-1 {
  1354  			ctx.WritePlain(",")
  1355  		}
  1356  	}
  1357  	return nil
  1358  }
  1359  
  1360  // Accept implements Node Accept interface.
  1361  func (n *SetDefaultRoleStmt) Accept(v Visitor) (Node, bool) {
  1362  	newNode, skipChildren := v.Enter(n)
  1363  	if skipChildren {
  1364  		return v.Leave(newNode)
  1365  	}
  1366  	n = newNode.(*SetDefaultRoleStmt)
  1367  	return v.Leave(n)
  1368  }
  1369  
  1370  // UserSpec is used for parsing create user statement.
  1371  type UserSpec struct {
  1372  	User    *auth.UserIdentity
  1373  	AuthOpt *AuthOption
  1374  	IsRole  bool
  1375  }
  1376  
  1377  // Restore implements Node interface.
  1378  func (n *UserSpec) Restore(ctx *format.RestoreCtx) error {
  1379  	if err := n.User.Restore(ctx); err != nil {
  1380  		return errors.Annotate(err, "An error occurred while restore UserSpec.User")
  1381  	}
  1382  	if n.AuthOpt != nil {
  1383  		ctx.WritePlain(" ")
  1384  		if err := n.AuthOpt.Restore(ctx); err != nil {
  1385  			return errors.Annotate(err, "An error occurred while restore UserSpec.AuthOpt")
  1386  		}
  1387  	}
  1388  	return nil
  1389  }
  1390  
  1391  // SecurityString formats the UserSpec without password information.
  1392  func (n *UserSpec) SecurityString() string {
  1393  	withPassword := false
  1394  	if opt := n.AuthOpt; opt != nil {
  1395  		if len(opt.AuthString) > 0 || len(opt.HashString) > 0 {
  1396  			withPassword = true
  1397  		}
  1398  	}
  1399  	if withPassword {
  1400  		return fmt.Sprintf("{%s password = ***}", n.User)
  1401  	}
  1402  	return n.User.String()
  1403  }
  1404  
  1405  // EncodedPassword returns the encoded password (which is the real data mysql.user).
  1406  // The boolean value indicates input's password format is legal or not.
  1407  func (n *UserSpec) EncodedPassword() (string, bool) {
  1408  	if n.AuthOpt == nil {
  1409  		return "", true
  1410  	}
  1411  
  1412  	opt := n.AuthOpt
  1413  	if opt.ByAuthString {
  1414  		switch opt.AuthPlugin {
  1415  		case mysql.AuthCachingSha2Password, mysql.AuthTiDBSM3Password:
  1416  			return auth.NewHashPassword(opt.AuthString, opt.AuthPlugin), true
  1417  		case mysql.AuthSocket:
  1418  			return "", true
  1419  		default:
  1420  			return auth.EncodePassword(opt.AuthString), true
  1421  		}
  1422  	}
  1423  
  1424  	// store the LDAP dn directly in the password field
  1425  	switch opt.AuthPlugin {
  1426  	case mysql.AuthLDAPSimple, mysql.AuthLDAPSASL:
  1427  		// TODO: validate the HashString to be a `dn` for LDAP
  1428  		// It seems fine to not validate here, and LDAP server will give an error when the client'll try to login this user.
  1429  		// The percona server implementation doesn't have a validation for this HashString.
  1430  		// However, returning an error for obvious wrong format is more friendly.
  1431  		return opt.HashString, true
  1432  	}
  1433  
  1434  	// In case we have 'IDENTIFIED WITH <plugin>' but no 'BY <password>' to set an empty password.
  1435  	if opt.HashString == "" {
  1436  		return opt.HashString, true
  1437  	}
  1438  
  1439  	// Not a legal password string.
  1440  	switch opt.AuthPlugin {
  1441  	case mysql.AuthCachingSha2Password:
  1442  		if len(opt.HashString) != mysql.SHAPWDHashLen {
  1443  			return "", false
  1444  		}
  1445  	case mysql.AuthTiDBSM3Password:
  1446  		if len(opt.HashString) != mysql.SM3PWDHashLen {
  1447  			return "", false
  1448  		}
  1449  	case "", mysql.AuthNativePassword:
  1450  		if len(opt.HashString) != (mysql.PWDHashLen+1) || !strings.HasPrefix(opt.HashString, "*") {
  1451  			return "", false
  1452  		}
  1453  	case mysql.AuthSocket:
  1454  	default:
  1455  		return "", false
  1456  	}
  1457  	return opt.HashString, true
  1458  }
  1459  
  1460  type AuthTokenOrTLSOption struct {
  1461  	Type  AuthTokenOrTLSOptionType
  1462  	Value string
  1463  }
  1464  
  1465  func (t *AuthTokenOrTLSOption) Restore(ctx *format.RestoreCtx) error {
  1466  	switch t.Type {
  1467  	case TlsNone:
  1468  		ctx.WriteKeyWord("NONE")
  1469  	case Ssl:
  1470  		ctx.WriteKeyWord("SSL")
  1471  	case X509:
  1472  		ctx.WriteKeyWord("X509")
  1473  	case Cipher:
  1474  		ctx.WriteKeyWord("CIPHER ")
  1475  		ctx.WriteString(t.Value)
  1476  	case Issuer:
  1477  		ctx.WriteKeyWord("ISSUER ")
  1478  		ctx.WriteString(t.Value)
  1479  	case Subject:
  1480  		ctx.WriteKeyWord("SUBJECT ")
  1481  		ctx.WriteString(t.Value)
  1482  	case SAN:
  1483  		ctx.WriteKeyWord("SAN ")
  1484  		ctx.WriteString(t.Value)
  1485  	case TokenIssuer:
  1486  		ctx.WriteKeyWord("TOKEN_ISSUER ")
  1487  		ctx.WriteString(t.Value)
  1488  	default:
  1489  		return errors.Errorf("Unsupported AuthTokenOrTLSOption.Type %d", t.Type)
  1490  	}
  1491  	return nil
  1492  }
  1493  
  1494  type AuthTokenOrTLSOptionType int
  1495  
  1496  const (
  1497  	TlsNone AuthTokenOrTLSOptionType = iota
  1498  	Ssl
  1499  	X509
  1500  	Cipher
  1501  	Issuer
  1502  	Subject
  1503  	SAN
  1504  	TokenIssuer
  1505  )
  1506  
  1507  func (t AuthTokenOrTLSOptionType) String() string {
  1508  	switch t {
  1509  	case TlsNone:
  1510  		return "NONE"
  1511  	case Ssl:
  1512  		return "SSL"
  1513  	case X509:
  1514  		return "X509"
  1515  	case Cipher:
  1516  		return "CIPHER"
  1517  	case Issuer:
  1518  		return "ISSUER"
  1519  	case Subject:
  1520  		return "SUBJECT"
  1521  	case SAN:
  1522  		return "SAN"
  1523  	case TokenIssuer:
  1524  		return "TOKEN_ISSUER"
  1525  	default:
  1526  		return "UNKNOWN"
  1527  	}
  1528  }
  1529  
  1530  const (
  1531  	MaxQueriesPerHour = iota + 1
  1532  	MaxUpdatesPerHour
  1533  	MaxConnectionsPerHour
  1534  	MaxUserConnections
  1535  )
  1536  
  1537  type ResourceOption struct {
  1538  	Type  int
  1539  	Count int64
  1540  }
  1541  
  1542  func (r *ResourceOption) Restore(ctx *format.RestoreCtx) error {
  1543  	switch r.Type {
  1544  	case MaxQueriesPerHour:
  1545  		ctx.WriteKeyWord("MAX_QUERIES_PER_HOUR ")
  1546  	case MaxUpdatesPerHour:
  1547  		ctx.WriteKeyWord("MAX_UPDATES_PER_HOUR ")
  1548  	case MaxConnectionsPerHour:
  1549  		ctx.WriteKeyWord("MAX_CONNECTIONS_PER_HOUR ")
  1550  	case MaxUserConnections:
  1551  		ctx.WriteKeyWord("MAX_USER_CONNECTIONS ")
  1552  	default:
  1553  		return errors.Errorf("Unsupported ResourceOption.Type %d", r.Type)
  1554  	}
  1555  	ctx.WritePlainf("%d", r.Count)
  1556  	return nil
  1557  }
  1558  
  1559  const (
  1560  	PasswordExpire = iota + 1
  1561  	PasswordExpireDefault
  1562  	PasswordExpireNever
  1563  	PasswordExpireInterval
  1564  	PasswordHistory
  1565  	PasswordHistoryDefault
  1566  	PasswordReuseInterval
  1567  	PasswordReuseDefault
  1568  	Lock
  1569  	Unlock
  1570  	FailedLoginAttempts
  1571  	PasswordLockTime
  1572  	PasswordLockTimeUnbounded
  1573  	UserCommentType
  1574  	UserAttributeType
  1575  
  1576  	UserResourceGroupName
  1577  )
  1578  
  1579  type PasswordOrLockOption struct {
  1580  	Type  int
  1581  	Count int64
  1582  }
  1583  
  1584  func (p *PasswordOrLockOption) Restore(ctx *format.RestoreCtx) error {
  1585  	switch p.Type {
  1586  	case PasswordExpire:
  1587  		ctx.WriteKeyWord("PASSWORD EXPIRE")
  1588  	case PasswordExpireDefault:
  1589  		ctx.WriteKeyWord("PASSWORD EXPIRE DEFAULT")
  1590  	case PasswordExpireNever:
  1591  		ctx.WriteKeyWord("PASSWORD EXPIRE NEVER")
  1592  	case PasswordExpireInterval:
  1593  		ctx.WriteKeyWord("PASSWORD EXPIRE INTERVAL")
  1594  		ctx.WritePlainf(" %d", p.Count)
  1595  		ctx.WriteKeyWord(" DAY")
  1596  	case Lock:
  1597  		ctx.WriteKeyWord("ACCOUNT LOCK")
  1598  	case Unlock:
  1599  		ctx.WriteKeyWord("ACCOUNT UNLOCK")
  1600  	case FailedLoginAttempts:
  1601  		ctx.WriteKeyWord("FAILED_LOGIN_ATTEMPTS")
  1602  		ctx.WritePlainf(" %d", p.Count)
  1603  	case PasswordLockTime:
  1604  		ctx.WriteKeyWord("PASSWORD_LOCK_TIME")
  1605  		ctx.WritePlainf(" %d", p.Count)
  1606  	case PasswordLockTimeUnbounded:
  1607  		ctx.WriteKeyWord("PASSWORD_LOCK_TIME UNBOUNDED")
  1608  	case PasswordHistory:
  1609  		ctx.WriteKeyWord("PASSWORD HISTORY")
  1610  		ctx.WritePlainf(" %d", p.Count)
  1611  	case PasswordHistoryDefault:
  1612  		ctx.WriteKeyWord("PASSWORD HISTORY DEFAULT")
  1613  	case PasswordReuseInterval:
  1614  		ctx.WriteKeyWord("PASSWORD REUSE INTERVAL")
  1615  		ctx.WritePlainf(" %d", p.Count)
  1616  		ctx.WriteKeyWord(" DAY")
  1617  	case PasswordReuseDefault:
  1618  		ctx.WriteKeyWord("PASSWORD REUSE INTERVAL DEFAULT")
  1619  	default:
  1620  		return errors.Errorf("Unsupported PasswordOrLockOption.Type %d", p.Type)
  1621  	}
  1622  	return nil
  1623  }
  1624  
  1625  type CommentOrAttributeOption struct {
  1626  	Type  int
  1627  	Value string
  1628  }
  1629  
  1630  func (c *CommentOrAttributeOption) Restore(ctx *format.RestoreCtx) error {
  1631  	if c.Type == UserCommentType {
  1632  		ctx.WriteKeyWord(" COMMENT ")
  1633  		ctx.WriteString(c.Value)
  1634  	} else if c.Type == UserAttributeType {
  1635  		ctx.WriteKeyWord(" ATTRIBUTE ")
  1636  		ctx.WriteString(c.Value)
  1637  	}
  1638  	return nil
  1639  }
  1640  
  1641  type ResourceGroupNameOption struct {
  1642  	Value string
  1643  }
  1644  
  1645  func (c *ResourceGroupNameOption) Restore(ctx *format.RestoreCtx) error {
  1646  	ctx.WriteKeyWord(" RESOURCE GROUP ")
  1647  	ctx.WriteName(c.Value)
  1648  	return nil
  1649  }
  1650  
  1651  // CreateUserStmt creates user account.
  1652  // See https://dev.mysql.com/doc/refman/8.0/en/create-user.html
  1653  type CreateUserStmt struct {
  1654  	stmtNode
  1655  
  1656  	IsCreateRole             bool
  1657  	IfNotExists              bool
  1658  	Specs                    []*UserSpec
  1659  	AuthTokenOrTLSOptions    []*AuthTokenOrTLSOption
  1660  	ResourceOptions          []*ResourceOption
  1661  	PasswordOrLockOptions    []*PasswordOrLockOption
  1662  	CommentOrAttributeOption *CommentOrAttributeOption
  1663  	ResourceGroupNameOption  *ResourceGroupNameOption
  1664  }
  1665  
  1666  // Restore implements Node interface.
  1667  func (n *CreateUserStmt) Restore(ctx *format.RestoreCtx) error {
  1668  	if n.IsCreateRole {
  1669  		ctx.WriteKeyWord("CREATE ROLE ")
  1670  	} else {
  1671  		ctx.WriteKeyWord("CREATE USER ")
  1672  	}
  1673  	if n.IfNotExists {
  1674  		ctx.WriteKeyWord("IF NOT EXISTS ")
  1675  	}
  1676  	for i, v := range n.Specs {
  1677  		if i != 0 {
  1678  			ctx.WritePlain(", ")
  1679  		}
  1680  		if err := v.Restore(ctx); err != nil {
  1681  			return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.Specs[%d]", i)
  1682  		}
  1683  	}
  1684  
  1685  	if len(n.AuthTokenOrTLSOptions) != 0 {
  1686  		ctx.WriteKeyWord(" REQUIRE ")
  1687  	}
  1688  
  1689  	for i, option := range n.AuthTokenOrTLSOptions {
  1690  		if i != 0 {
  1691  			ctx.WriteKeyWord(" AND ")
  1692  		}
  1693  		if err := option.Restore(ctx); err != nil {
  1694  			return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.AuthTokenOrTLSOptions[%d]", i)
  1695  		}
  1696  	}
  1697  
  1698  	if len(n.ResourceOptions) != 0 {
  1699  		ctx.WriteKeyWord(" WITH")
  1700  	}
  1701  
  1702  	for i, v := range n.ResourceOptions {
  1703  		ctx.WritePlain(" ")
  1704  		if err := v.Restore(ctx); err != nil {
  1705  			return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.ResourceOptions[%d]", i)
  1706  		}
  1707  	}
  1708  
  1709  	for i, v := range n.PasswordOrLockOptions {
  1710  		ctx.WritePlain(" ")
  1711  		if err := v.Restore(ctx); err != nil {
  1712  			return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.PasswordOrLockOptions[%d]", i)
  1713  		}
  1714  	}
  1715  
  1716  	if n.CommentOrAttributeOption != nil {
  1717  		if err := n.CommentOrAttributeOption.Restore(ctx); err != nil {
  1718  			return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.CommentOrAttributeOption")
  1719  		}
  1720  	}
  1721  
  1722  	if n.ResourceGroupNameOption != nil {
  1723  		if err := n.ResourceGroupNameOption.Restore(ctx); err != nil {
  1724  			return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.ResourceGroupNameOption")
  1725  		}
  1726  	}
  1727  
  1728  	return nil
  1729  }
  1730  
  1731  // Accept implements Node Accept interface.
  1732  func (n *CreateUserStmt) Accept(v Visitor) (Node, bool) {
  1733  	newNode, skipChildren := v.Enter(n)
  1734  	if skipChildren {
  1735  		return v.Leave(newNode)
  1736  	}
  1737  	n = newNode.(*CreateUserStmt)
  1738  	return v.Leave(n)
  1739  }
  1740  
  1741  // SecureText implements SensitiveStatement interface.
  1742  func (n *CreateUserStmt) SecureText() string {
  1743  	var buf bytes.Buffer
  1744  	buf.WriteString("create user")
  1745  	for _, user := range n.Specs {
  1746  		buf.WriteString(" ")
  1747  		buf.WriteString(user.SecurityString())
  1748  	}
  1749  	return buf.String()
  1750  }
  1751  
  1752  // AlterUserStmt modifies user account.
  1753  // See https://dev.mysql.com/doc/refman/8.0/en/alter-user.html
  1754  type AlterUserStmt struct {
  1755  	stmtNode
  1756  
  1757  	IfExists                 bool
  1758  	CurrentAuth              *AuthOption
  1759  	Specs                    []*UserSpec
  1760  	AuthTokenOrTLSOptions    []*AuthTokenOrTLSOption
  1761  	ResourceOptions          []*ResourceOption
  1762  	PasswordOrLockOptions    []*PasswordOrLockOption
  1763  	CommentOrAttributeOption *CommentOrAttributeOption
  1764  	ResourceGroupNameOption  *ResourceGroupNameOption
  1765  }
  1766  
  1767  // Restore implements Node interface.
  1768  func (n *AlterUserStmt) Restore(ctx *format.RestoreCtx) error {
  1769  	ctx.WriteKeyWord("ALTER USER ")
  1770  	if n.IfExists {
  1771  		ctx.WriteKeyWord("IF EXISTS ")
  1772  	}
  1773  	if n.CurrentAuth != nil {
  1774  		ctx.WriteKeyWord("USER")
  1775  		ctx.WritePlain("() ")
  1776  		if err := n.CurrentAuth.Restore(ctx); err != nil {
  1777  			return errors.Annotate(err, "An error occurred while restore AlterUserStmt.CurrentAuth")
  1778  		}
  1779  	}
  1780  	for i, v := range n.Specs {
  1781  		if i != 0 {
  1782  			ctx.WritePlain(", ")
  1783  		}
  1784  		if err := v.Restore(ctx); err != nil {
  1785  			return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.Specs[%d]", i)
  1786  		}
  1787  	}
  1788  
  1789  	if len(n.AuthTokenOrTLSOptions) != 0 {
  1790  		ctx.WriteKeyWord(" REQUIRE ")
  1791  	}
  1792  
  1793  	for i, option := range n.AuthTokenOrTLSOptions {
  1794  		if i != 0 {
  1795  			ctx.WriteKeyWord(" AND ")
  1796  		}
  1797  		if err := option.Restore(ctx); err != nil {
  1798  			return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.AuthTokenOrTLSOptions[%d]", i)
  1799  		}
  1800  	}
  1801  
  1802  	if len(n.ResourceOptions) != 0 {
  1803  		ctx.WriteKeyWord(" WITH")
  1804  	}
  1805  
  1806  	for i, v := range n.ResourceOptions {
  1807  		ctx.WritePlain(" ")
  1808  		if err := v.Restore(ctx); err != nil {
  1809  			return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.ResourceOptions[%d]", i)
  1810  		}
  1811  	}
  1812  
  1813  	for i, v := range n.PasswordOrLockOptions {
  1814  		ctx.WritePlain(" ")
  1815  		if err := v.Restore(ctx); err != nil {
  1816  			return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.PasswordOrLockOptions[%d]", i)
  1817  		}
  1818  	}
  1819  
  1820  	if n.CommentOrAttributeOption != nil {
  1821  		if err := n.CommentOrAttributeOption.Restore(ctx); err != nil {
  1822  			return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.CommentOrAttributeOption")
  1823  		}
  1824  	}
  1825  
  1826  	if n.ResourceGroupNameOption != nil {
  1827  		if err := n.ResourceGroupNameOption.Restore(ctx); err != nil {
  1828  			return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.ResourceGroupNameOption")
  1829  		}
  1830  	}
  1831  
  1832  	return nil
  1833  }
  1834  
  1835  // SecureText implements SensitiveStatement interface.
  1836  func (n *AlterUserStmt) SecureText() string {
  1837  	var buf bytes.Buffer
  1838  	buf.WriteString("alter user")
  1839  	for _, user := range n.Specs {
  1840  		buf.WriteString(" ")
  1841  		buf.WriteString(user.SecurityString())
  1842  	}
  1843  	return buf.String()
  1844  }
  1845  
  1846  // Accept implements Node Accept interface.
  1847  func (n *AlterUserStmt) Accept(v Visitor) (Node, bool) {
  1848  	newNode, skipChildren := v.Enter(n)
  1849  	if skipChildren {
  1850  		return v.Leave(newNode)
  1851  	}
  1852  	n = newNode.(*AlterUserStmt)
  1853  	return v.Leave(n)
  1854  }
  1855  
  1856  // AlterInstanceStmt modifies instance.
  1857  // See https://dev.mysql.com/doc/refman/8.0/en/alter-instance.html
  1858  type AlterInstanceStmt struct {
  1859  	stmtNode
  1860  
  1861  	ReloadTLS         bool
  1862  	NoRollbackOnError bool
  1863  }
  1864  
  1865  // Restore implements Node interface.
  1866  func (n *AlterInstanceStmt) Restore(ctx *format.RestoreCtx) error {
  1867  	ctx.WriteKeyWord("ALTER INSTANCE")
  1868  	if n.ReloadTLS {
  1869  		ctx.WriteKeyWord(" RELOAD TLS")
  1870  	}
  1871  	if n.NoRollbackOnError {
  1872  		ctx.WriteKeyWord(" NO ROLLBACK ON ERROR")
  1873  	}
  1874  	return nil
  1875  }
  1876  
  1877  // Accept implements Node Accept interface.
  1878  func (n *AlterInstanceStmt) Accept(v Visitor) (Node, bool) {
  1879  	newNode, skipChildren := v.Enter(n)
  1880  	if skipChildren {
  1881  		return v.Leave(newNode)
  1882  	}
  1883  	n = newNode.(*AlterInstanceStmt)
  1884  	return v.Leave(n)
  1885  }
  1886  
  1887  // AlterRangeStmt modifies range configuration.
  1888  type AlterRangeStmt struct {
  1889  	stmtNode
  1890  	RangeName       model.CIStr
  1891  	PlacementOption *PlacementOption
  1892  }
  1893  
  1894  // Restore implements Node interface.
  1895  func (n *AlterRangeStmt) Restore(ctx *format.RestoreCtx) error {
  1896  	ctx.WriteKeyWord("ALTER RANGE ")
  1897  	ctx.WriteName(n.RangeName.O)
  1898  	ctx.WritePlain(" ")
  1899  	if err := n.PlacementOption.Restore(ctx); err != nil {
  1900  		return errors.Annotate(err, "An error occurred while restore AlterRangeStmt.PlacementOption")
  1901  	}
  1902  	return nil
  1903  }
  1904  
  1905  // Accept implements Node Accept interface.
  1906  func (n *AlterRangeStmt) Accept(v Visitor) (Node, bool) {
  1907  	newNode, skipChildren := v.Enter(n)
  1908  	if skipChildren {
  1909  		return v.Leave(newNode)
  1910  	}
  1911  	n = newNode.(*AlterRangeStmt)
  1912  	return v.Leave(n)
  1913  }
  1914  
  1915  // DropUserStmt creates user account.
  1916  // See http://dev.mysql.com/doc/refman/5.7/en/drop-user.html
  1917  type DropUserStmt struct {
  1918  	stmtNode
  1919  
  1920  	IfExists   bool
  1921  	IsDropRole bool
  1922  	UserList   []*auth.UserIdentity
  1923  }
  1924  
  1925  // Restore implements Node interface.
  1926  func (n *DropUserStmt) Restore(ctx *format.RestoreCtx) error {
  1927  	if n.IsDropRole {
  1928  		ctx.WriteKeyWord("DROP ROLE ")
  1929  	} else {
  1930  		ctx.WriteKeyWord("DROP USER ")
  1931  	}
  1932  	if n.IfExists {
  1933  		ctx.WriteKeyWord("IF EXISTS ")
  1934  	}
  1935  	for i, v := range n.UserList {
  1936  		if i != 0 {
  1937  			ctx.WritePlain(", ")
  1938  		}
  1939  		if err := v.Restore(ctx); err != nil {
  1940  			return errors.Annotatef(err, "An error occurred while restore DropUserStmt.UserList[%d]", i)
  1941  		}
  1942  	}
  1943  	return nil
  1944  }
  1945  
  1946  // Accept implements Node Accept interface.
  1947  func (n *DropUserStmt) Accept(v Visitor) (Node, bool) {
  1948  	newNode, skipChildren := v.Enter(n)
  1949  	if skipChildren {
  1950  		return v.Leave(newNode)
  1951  	}
  1952  	n = newNode.(*DropUserStmt)
  1953  	return v.Leave(n)
  1954  }
  1955  
  1956  // CreateBindingStmt creates sql binding hint.
  1957  type CreateBindingStmt struct {
  1958  	stmtNode
  1959  
  1960  	GlobalScope bool
  1961  	OriginNode  StmtNode
  1962  	HintedNode  StmtNode
  1963  	PlanDigest  string
  1964  }
  1965  
  1966  func (n *CreateBindingStmt) Restore(ctx *format.RestoreCtx) error {
  1967  	ctx.WriteKeyWord("CREATE ")
  1968  	if n.GlobalScope {
  1969  		ctx.WriteKeyWord("GLOBAL ")
  1970  	} else {
  1971  		ctx.WriteKeyWord("SESSION ")
  1972  	}
  1973  	if n.OriginNode == nil {
  1974  		ctx.WriteKeyWord("BINDING FROM HISTORY USING PLAN DIGEST ")
  1975  		ctx.WriteString(n.PlanDigest)
  1976  	} else {
  1977  		ctx.WriteKeyWord("BINDING FOR ")
  1978  		if err := n.OriginNode.Restore(ctx); err != nil {
  1979  			return errors.Trace(err)
  1980  		}
  1981  		ctx.WriteKeyWord(" USING ")
  1982  		if err := n.HintedNode.Restore(ctx); err != nil {
  1983  			return errors.Trace(err)
  1984  		}
  1985  	}
  1986  	return nil
  1987  }
  1988  
  1989  func (n *CreateBindingStmt) Accept(v Visitor) (Node, bool) {
  1990  	newNode, skipChildren := v.Enter(n)
  1991  	if skipChildren {
  1992  		return v.Leave(newNode)
  1993  	}
  1994  	n = newNode.(*CreateBindingStmt)
  1995  	if n.OriginNode != nil {
  1996  		origNode, ok := n.OriginNode.Accept(v)
  1997  		if !ok {
  1998  			return n, false
  1999  		}
  2000  		n.OriginNode = origNode.(StmtNode)
  2001  		hintedNode, ok := n.HintedNode.Accept(v)
  2002  		if !ok {
  2003  			return n, false
  2004  		}
  2005  		n.HintedNode = hintedNode.(StmtNode)
  2006  	}
  2007  	return v.Leave(n)
  2008  }
  2009  
  2010  // DropBindingStmt deletes sql binding hint.
  2011  type DropBindingStmt struct {
  2012  	stmtNode
  2013  
  2014  	GlobalScope bool
  2015  	OriginNode  StmtNode
  2016  	HintedNode  StmtNode
  2017  	SQLDigest   string
  2018  }
  2019  
  2020  func (n *DropBindingStmt) Restore(ctx *format.RestoreCtx) error {
  2021  	ctx.WriteKeyWord("DROP ")
  2022  	if n.GlobalScope {
  2023  		ctx.WriteKeyWord("GLOBAL ")
  2024  	} else {
  2025  		ctx.WriteKeyWord("SESSION ")
  2026  	}
  2027  	ctx.WriteKeyWord("BINDING FOR ")
  2028  	if n.OriginNode == nil {
  2029  		ctx.WriteKeyWord("SQL DIGEST ")
  2030  		ctx.WriteString(n.SQLDigest)
  2031  	} else {
  2032  		if err := n.OriginNode.Restore(ctx); err != nil {
  2033  			return errors.Trace(err)
  2034  		}
  2035  		if n.HintedNode != nil {
  2036  			ctx.WriteKeyWord(" USING ")
  2037  			if err := n.HintedNode.Restore(ctx); err != nil {
  2038  				return errors.Trace(err)
  2039  			}
  2040  		}
  2041  	}
  2042  	return nil
  2043  }
  2044  
  2045  func (n *DropBindingStmt) Accept(v Visitor) (Node, bool) {
  2046  	newNode, skipChildren := v.Enter(n)
  2047  	if skipChildren {
  2048  		return v.Leave(newNode)
  2049  	}
  2050  	n = newNode.(*DropBindingStmt)
  2051  	if n.OriginNode != nil {
  2052  		//  OriginNode is nil means we build drop binding by sql digest
  2053  		origNode, ok := n.OriginNode.Accept(v)
  2054  		if !ok {
  2055  			return n, false
  2056  		}
  2057  		n.OriginNode = origNode.(StmtNode)
  2058  		if n.HintedNode != nil {
  2059  			hintedNode, ok := n.HintedNode.Accept(v)
  2060  			if !ok {
  2061  				return n, false
  2062  			}
  2063  			n.HintedNode = hintedNode.(StmtNode)
  2064  		}
  2065  	}
  2066  	return v.Leave(n)
  2067  }
  2068  
  2069  // BindingStatusType defines the status type for the binding
  2070  type BindingStatusType int8
  2071  
  2072  // Binding status types.
  2073  const (
  2074  	BindingStatusTypeEnabled BindingStatusType = iota
  2075  	BindingStatusTypeDisabled
  2076  )
  2077  
  2078  // SetBindingStmt sets sql binding status.
  2079  type SetBindingStmt struct {
  2080  	stmtNode
  2081  
  2082  	BindingStatusType BindingStatusType
  2083  	OriginNode        StmtNode
  2084  	HintedNode        StmtNode
  2085  	SQLDigest         string
  2086  }
  2087  
  2088  func (n *SetBindingStmt) Restore(ctx *format.RestoreCtx) error {
  2089  	ctx.WriteKeyWord("SET ")
  2090  	ctx.WriteKeyWord("BINDING ")
  2091  	switch n.BindingStatusType {
  2092  	case BindingStatusTypeEnabled:
  2093  		ctx.WriteKeyWord("ENABLED ")
  2094  	case BindingStatusTypeDisabled:
  2095  		ctx.WriteKeyWord("DISABLED ")
  2096  	}
  2097  	ctx.WriteKeyWord("FOR ")
  2098  	if n.OriginNode == nil {
  2099  		ctx.WriteKeyWord("SQL DIGEST ")
  2100  		ctx.WriteString(n.SQLDigest)
  2101  	} else {
  2102  		if err := n.OriginNode.Restore(ctx); err != nil {
  2103  			return errors.Trace(err)
  2104  		}
  2105  		if n.HintedNode != nil {
  2106  			ctx.WriteKeyWord(" USING ")
  2107  			if err := n.HintedNode.Restore(ctx); err != nil {
  2108  				return errors.Trace(err)
  2109  			}
  2110  		}
  2111  	}
  2112  	return nil
  2113  }
  2114  
  2115  func (n *SetBindingStmt) Accept(v Visitor) (Node, bool) {
  2116  	newNode, skipChildren := v.Enter(n)
  2117  	if skipChildren {
  2118  		return v.Leave(newNode)
  2119  	}
  2120  	n = newNode.(*SetBindingStmt)
  2121  	if n.OriginNode != nil {
  2122  		// OriginNode is nil means we set binding stmt by sql digest
  2123  		origNode, ok := n.OriginNode.Accept(v)
  2124  		if !ok {
  2125  			return n, false
  2126  		}
  2127  		n.OriginNode = origNode.(StmtNode)
  2128  		if n.HintedNode != nil {
  2129  			hintedNode, ok := n.HintedNode.Accept(v)
  2130  			if !ok {
  2131  				return n, false
  2132  			}
  2133  			n.HintedNode = hintedNode.(StmtNode)
  2134  		}
  2135  	}
  2136  	return v.Leave(n)
  2137  }
  2138  
  2139  // Extended statistics types.
  2140  const (
  2141  	StatsTypeCardinality uint8 = iota
  2142  	StatsTypeDependency
  2143  	StatsTypeCorrelation
  2144  )
  2145  
  2146  // StatisticsSpec is the specification for ADD /DROP STATISTICS.
  2147  type StatisticsSpec struct {
  2148  	StatsName string
  2149  	StatsType uint8
  2150  	Columns   []*ColumnName
  2151  }
  2152  
  2153  // CreateStatisticsStmt is a statement to create extended statistics.
  2154  // Examples:
  2155  //
  2156  //	CREATE STATISTICS stats1 (cardinality) ON t(a, b, c);
  2157  //	CREATE STATISTICS stats2 (dependency) ON t(a, b);
  2158  //	CREATE STATISTICS stats3 (correlation) ON t(a, b);
  2159  type CreateStatisticsStmt struct {
  2160  	stmtNode
  2161  
  2162  	IfNotExists bool
  2163  	StatsName   string
  2164  	StatsType   uint8
  2165  	Table       *TableName
  2166  	Columns     []*ColumnName
  2167  }
  2168  
  2169  // Restore implements Node interface.
  2170  func (n *CreateStatisticsStmt) Restore(ctx *format.RestoreCtx) error {
  2171  	ctx.WriteKeyWord("CREATE STATISTICS ")
  2172  	if n.IfNotExists {
  2173  		ctx.WriteKeyWord("IF NOT EXISTS ")
  2174  	}
  2175  	ctx.WriteName(n.StatsName)
  2176  	switch n.StatsType {
  2177  	case StatsTypeCardinality:
  2178  		ctx.WriteKeyWord(" (cardinality) ")
  2179  	case StatsTypeDependency:
  2180  		ctx.WriteKeyWord(" (dependency) ")
  2181  	case StatsTypeCorrelation:
  2182  		ctx.WriteKeyWord(" (correlation) ")
  2183  	}
  2184  	ctx.WriteKeyWord("ON ")
  2185  	if err := n.Table.Restore(ctx); err != nil {
  2186  		return errors.Annotate(err, "An error occurred while restore CreateStatisticsStmt.Table")
  2187  	}
  2188  
  2189  	ctx.WritePlain("(")
  2190  	for i, col := range n.Columns {
  2191  		if i != 0 {
  2192  			ctx.WritePlain(", ")
  2193  		}
  2194  		if err := col.Restore(ctx); err != nil {
  2195  			return errors.Annotatef(err, "An error occurred while restore CreateStatisticsStmt.Columns: [%v]", i)
  2196  		}
  2197  	}
  2198  	ctx.WritePlain(")")
  2199  	return nil
  2200  }
  2201  
  2202  // Accept implements Node Accept interface.
  2203  func (n *CreateStatisticsStmt) Accept(v Visitor) (Node, bool) {
  2204  	newNode, skipChildren := v.Enter(n)
  2205  	if skipChildren {
  2206  		return v.Leave(newNode)
  2207  	}
  2208  	n = newNode.(*CreateStatisticsStmt)
  2209  	node, ok := n.Table.Accept(v)
  2210  	if !ok {
  2211  		return n, false
  2212  	}
  2213  	n.Table = node.(*TableName)
  2214  	for i, col := range n.Columns {
  2215  		node, ok = col.Accept(v)
  2216  		if !ok {
  2217  			return n, false
  2218  		}
  2219  		n.Columns[i] = node.(*ColumnName)
  2220  	}
  2221  	return v.Leave(n)
  2222  }
  2223  
  2224  // DropStatisticsStmt is a statement to drop extended statistics.
  2225  // Examples:
  2226  //
  2227  //	DROP STATISTICS stats1;
  2228  type DropStatisticsStmt struct {
  2229  	stmtNode
  2230  
  2231  	StatsName string
  2232  }
  2233  
  2234  // Restore implements Node interface.
  2235  func (n *DropStatisticsStmt) Restore(ctx *format.RestoreCtx) error {
  2236  	ctx.WriteKeyWord("DROP STATISTICS ")
  2237  	ctx.WriteName(n.StatsName)
  2238  	return nil
  2239  }
  2240  
  2241  // Accept implements Node Accept interface.
  2242  func (n *DropStatisticsStmt) Accept(v Visitor) (Node, bool) {
  2243  	newNode, skipChildren := v.Enter(n)
  2244  	if skipChildren {
  2245  		return v.Leave(newNode)
  2246  	}
  2247  	n = newNode.(*DropStatisticsStmt)
  2248  	return v.Leave(n)
  2249  }
  2250  
  2251  // DoStmt is the struct for DO statement.
  2252  type DoStmt struct {
  2253  	stmtNode
  2254  
  2255  	Exprs []ExprNode
  2256  }
  2257  
  2258  // Restore implements Node interface.
  2259  func (n *DoStmt) Restore(ctx *format.RestoreCtx) error {
  2260  	ctx.WriteKeyWord("DO ")
  2261  	for i, v := range n.Exprs {
  2262  		if i != 0 {
  2263  			ctx.WritePlain(", ")
  2264  		}
  2265  		if err := v.Restore(ctx); err != nil {
  2266  			return errors.Annotatef(err, "An error occurred while restore DoStmt.Exprs[%d]", i)
  2267  		}
  2268  	}
  2269  	return nil
  2270  }
  2271  
  2272  // Accept implements Node Accept interface.
  2273  func (n *DoStmt) Accept(v Visitor) (Node, bool) {
  2274  	newNode, skipChildren := v.Enter(n)
  2275  	if skipChildren {
  2276  		return v.Leave(newNode)
  2277  	}
  2278  	n = newNode.(*DoStmt)
  2279  	for i, val := range n.Exprs {
  2280  		node, ok := val.Accept(v)
  2281  		if !ok {
  2282  			return n, false
  2283  		}
  2284  		n.Exprs[i] = node.(ExprNode)
  2285  	}
  2286  	return v.Leave(n)
  2287  }
  2288  
  2289  // AdminStmtType is the type for admin statement.
  2290  type AdminStmtType int
  2291  
  2292  // Admin statement types.
  2293  const (
  2294  	AdminShowDDL = iota + 1
  2295  	AdminCheckTable
  2296  	AdminShowDDLJobs
  2297  	AdminCancelDDLJobs
  2298  	AdminPauseDDLJobs
  2299  	AdminResumeDDLJobs
  2300  	AdminCheckIndex
  2301  	AdminRecoverIndex
  2302  	AdminCleanupIndex
  2303  	AdminCheckIndexRange
  2304  	AdminShowDDLJobQueries
  2305  	AdminShowDDLJobQueriesWithRange
  2306  	AdminChecksumTable
  2307  	AdminShowSlow
  2308  	AdminShowNextRowID
  2309  	AdminReloadExprPushdownBlacklist
  2310  	AdminReloadOptRuleBlacklist
  2311  	AdminPluginDisable
  2312  	AdminPluginEnable
  2313  	AdminFlushBindings
  2314  	AdminCaptureBindings
  2315  	AdminEvolveBindings
  2316  	AdminReloadBindings
  2317  	AdminShowTelemetry
  2318  	AdminResetTelemetryID
  2319  	AdminReloadStatistics
  2320  	AdminFlushPlanCache
  2321  )
  2322  
  2323  // HandleRange represents a range where handle value >= Begin and < End.
  2324  type HandleRange struct {
  2325  	Begin int64
  2326  	End   int64
  2327  }
  2328  
  2329  type StatementScope int
  2330  
  2331  const (
  2332  	StatementScopeNone StatementScope = iota
  2333  	StatementScopeSession
  2334  	StatementScopeInstance
  2335  	StatementScopeGlobal
  2336  )
  2337  
  2338  // ShowSlowType defines the type for SlowSlow statement.
  2339  type ShowSlowType int
  2340  
  2341  const (
  2342  	// ShowSlowTop is a ShowSlowType constant.
  2343  	ShowSlowTop ShowSlowType = iota
  2344  	// ShowSlowRecent is a ShowSlowType constant.
  2345  	ShowSlowRecent
  2346  )
  2347  
  2348  // ShowSlowKind defines the kind for SlowSlow statement when the type is ShowSlowTop.
  2349  type ShowSlowKind int
  2350  
  2351  const (
  2352  	// ShowSlowKindDefault is a ShowSlowKind constant.
  2353  	ShowSlowKindDefault ShowSlowKind = iota
  2354  	// ShowSlowKindInternal is a ShowSlowKind constant.
  2355  	ShowSlowKindInternal
  2356  	// ShowSlowKindAll is a ShowSlowKind constant.
  2357  	ShowSlowKindAll
  2358  )
  2359  
  2360  // ShowSlow is used for the following command:
  2361  //
  2362  //	admin show slow top [ internal | all] N
  2363  //	admin show slow recent N
  2364  type ShowSlow struct {
  2365  	Tp    ShowSlowType
  2366  	Count uint64
  2367  	Kind  ShowSlowKind
  2368  }
  2369  
  2370  // Restore implements Node interface.
  2371  func (n *ShowSlow) Restore(ctx *format.RestoreCtx) error {
  2372  	switch n.Tp {
  2373  	case ShowSlowRecent:
  2374  		ctx.WriteKeyWord("RECENT ")
  2375  	case ShowSlowTop:
  2376  		ctx.WriteKeyWord("TOP ")
  2377  		switch n.Kind {
  2378  		case ShowSlowKindDefault:
  2379  			// do nothing
  2380  		case ShowSlowKindInternal:
  2381  			ctx.WriteKeyWord("INTERNAL ")
  2382  		case ShowSlowKindAll:
  2383  			ctx.WriteKeyWord("ALL ")
  2384  		default:
  2385  			return errors.New("Unsupported kind of ShowSlowTop")
  2386  		}
  2387  	default:
  2388  		return errors.New("Unsupported type of ShowSlow")
  2389  	}
  2390  	ctx.WritePlainf("%d", n.Count)
  2391  	return nil
  2392  }
  2393  
  2394  // LimitSimple is the struct for Admin statement limit option.
  2395  type LimitSimple struct {
  2396  	Count  uint64
  2397  	Offset uint64
  2398  }
  2399  
  2400  // AdminStmt is the struct for Admin statement.
  2401  type AdminStmt struct {
  2402  	stmtNode
  2403  
  2404  	Tp        AdminStmtType
  2405  	Index     string
  2406  	Tables    []*TableName
  2407  	JobIDs    []int64
  2408  	JobNumber int64
  2409  
  2410  	HandleRanges   []HandleRange
  2411  	ShowSlow       *ShowSlow
  2412  	Plugins        []string
  2413  	Where          ExprNode
  2414  	StatementScope StatementScope
  2415  	LimitSimple    LimitSimple
  2416  }
  2417  
  2418  // Restore implements Node interface.
  2419  func (n *AdminStmt) Restore(ctx *format.RestoreCtx) error {
  2420  	restoreTables := func() error {
  2421  		for i, v := range n.Tables {
  2422  			if i != 0 {
  2423  				ctx.WritePlain(", ")
  2424  			}
  2425  			if err := v.Restore(ctx); err != nil {
  2426  				return errors.Annotatef(err, "An error occurred while restore AdminStmt.Tables[%d]", i)
  2427  			}
  2428  		}
  2429  		return nil
  2430  	}
  2431  	restoreJobIDs := func() {
  2432  		for i, v := range n.JobIDs {
  2433  			if i != 0 {
  2434  				ctx.WritePlain(", ")
  2435  			}
  2436  			ctx.WritePlainf("%d", v)
  2437  		}
  2438  	}
  2439  
  2440  	ctx.WriteKeyWord("ADMIN ")
  2441  	switch n.Tp {
  2442  	case AdminShowDDL:
  2443  		ctx.WriteKeyWord("SHOW DDL")
  2444  	case AdminShowDDLJobs:
  2445  		ctx.WriteKeyWord("SHOW DDL JOBS")
  2446  		if n.JobNumber != 0 {
  2447  			ctx.WritePlainf(" %d", n.JobNumber)
  2448  		}
  2449  		if n.Where != nil {
  2450  			ctx.WriteKeyWord(" WHERE ")
  2451  			if err := n.Where.Restore(ctx); err != nil {
  2452  				return errors.Annotate(err, "An error occurred while restore ShowStmt.Where")
  2453  			}
  2454  		}
  2455  	case AdminShowNextRowID:
  2456  		ctx.WriteKeyWord("SHOW ")
  2457  		if err := restoreTables(); err != nil {
  2458  			return err
  2459  		}
  2460  		ctx.WriteKeyWord(" NEXT_ROW_ID")
  2461  	case AdminCheckTable:
  2462  		ctx.WriteKeyWord("CHECK TABLE ")
  2463  		if err := restoreTables(); err != nil {
  2464  			return err
  2465  		}
  2466  	case AdminCheckIndex:
  2467  		ctx.WriteKeyWord("CHECK INDEX ")
  2468  		if err := restoreTables(); err != nil {
  2469  			return err
  2470  		}
  2471  		ctx.WritePlainf(" %s", n.Index)
  2472  	case AdminRecoverIndex:
  2473  		ctx.WriteKeyWord("RECOVER INDEX ")
  2474  		if err := restoreTables(); err != nil {
  2475  			return err
  2476  		}
  2477  		ctx.WritePlainf(" %s", n.Index)
  2478  	case AdminCleanupIndex:
  2479  		ctx.WriteKeyWord("CLEANUP INDEX ")
  2480  		if err := restoreTables(); err != nil {
  2481  			return err
  2482  		}
  2483  		ctx.WritePlainf(" %s", n.Index)
  2484  	case AdminCheckIndexRange:
  2485  		ctx.WriteKeyWord("CHECK INDEX ")
  2486  		if err := restoreTables(); err != nil {
  2487  			return err
  2488  		}
  2489  		ctx.WritePlainf(" %s", n.Index)
  2490  		if n.HandleRanges != nil {
  2491  			ctx.WritePlain(" ")
  2492  			for i, v := range n.HandleRanges {
  2493  				if i != 0 {
  2494  					ctx.WritePlain(", ")
  2495  				}
  2496  				ctx.WritePlainf("(%d,%d)", v.Begin, v.End)
  2497  			}
  2498  		}
  2499  	case AdminChecksumTable:
  2500  		ctx.WriteKeyWord("CHECKSUM TABLE ")
  2501  		if err := restoreTables(); err != nil {
  2502  			return err
  2503  		}
  2504  	case AdminCancelDDLJobs:
  2505  		ctx.WriteKeyWord("CANCEL DDL JOBS ")
  2506  		restoreJobIDs()
  2507  	case AdminPauseDDLJobs:
  2508  		ctx.WriteKeyWord("PAUSE DDL JOBS ")
  2509  		restoreJobIDs()
  2510  	case AdminResumeDDLJobs:
  2511  		ctx.WriteKeyWord("RESUME DDL JOBS ")
  2512  		restoreJobIDs()
  2513  	case AdminShowDDLJobQueries:
  2514  		ctx.WriteKeyWord("SHOW DDL JOB QUERIES ")
  2515  		restoreJobIDs()
  2516  	case AdminShowDDLJobQueriesWithRange:
  2517  		ctx.WriteKeyWord("SHOW DDL JOB QUERIES LIMIT ")
  2518  		ctx.WritePlainf("%d, %d", n.LimitSimple.Offset, n.LimitSimple.Count)
  2519  	case AdminShowSlow:
  2520  		ctx.WriteKeyWord("SHOW SLOW ")
  2521  		if err := n.ShowSlow.Restore(ctx); err != nil {
  2522  			return errors.Annotate(err, "An error occurred while restore AdminStmt.ShowSlow")
  2523  		}
  2524  	case AdminReloadExprPushdownBlacklist:
  2525  		ctx.WriteKeyWord("RELOAD EXPR_PUSHDOWN_BLACKLIST")
  2526  	case AdminReloadOptRuleBlacklist:
  2527  		ctx.WriteKeyWord("RELOAD OPT_RULE_BLACKLIST")
  2528  	case AdminPluginEnable:
  2529  		ctx.WriteKeyWord("PLUGINS ENABLE")
  2530  		for i, v := range n.Plugins {
  2531  			if i == 0 {
  2532  				ctx.WritePlain(" ")
  2533  			} else {
  2534  				ctx.WritePlain(", ")
  2535  			}
  2536  			ctx.WritePlain(v)
  2537  		}
  2538  	case AdminPluginDisable:
  2539  		ctx.WriteKeyWord("PLUGINS DISABLE")
  2540  		for i, v := range n.Plugins {
  2541  			if i == 0 {
  2542  				ctx.WritePlain(" ")
  2543  			} else {
  2544  				ctx.WritePlain(", ")
  2545  			}
  2546  			ctx.WritePlain(v)
  2547  		}
  2548  	case AdminFlushBindings:
  2549  		ctx.WriteKeyWord("FLUSH BINDINGS")
  2550  	case AdminCaptureBindings:
  2551  		ctx.WriteKeyWord("CAPTURE BINDINGS")
  2552  	case AdminEvolveBindings:
  2553  		ctx.WriteKeyWord("EVOLVE BINDINGS")
  2554  	case AdminReloadBindings:
  2555  		ctx.WriteKeyWord("RELOAD BINDINGS")
  2556  	case AdminShowTelemetry:
  2557  		ctx.WriteKeyWord("SHOW TELEMETRY")
  2558  	case AdminResetTelemetryID:
  2559  		ctx.WriteKeyWord("RESET TELEMETRY_ID")
  2560  	case AdminReloadStatistics:
  2561  		ctx.WriteKeyWord("RELOAD STATS_EXTENDED")
  2562  	case AdminFlushPlanCache:
  2563  		if n.StatementScope == StatementScopeSession {
  2564  			ctx.WriteKeyWord("FLUSH SESSION PLAN_CACHE")
  2565  		} else if n.StatementScope == StatementScopeInstance {
  2566  			ctx.WriteKeyWord("FLUSH INSTANCE PLAN_CACHE")
  2567  		} else if n.StatementScope == StatementScopeGlobal {
  2568  			ctx.WriteKeyWord("FLUSH GLOBAL PLAN_CACHE")
  2569  		}
  2570  	default:
  2571  		return errors.New("Unsupported AdminStmt type")
  2572  	}
  2573  	return nil
  2574  }
  2575  
  2576  // Accept implements Node Accept interface.
  2577  func (n *AdminStmt) Accept(v Visitor) (Node, bool) {
  2578  	newNode, skipChildren := v.Enter(n)
  2579  	if skipChildren {
  2580  		return v.Leave(newNode)
  2581  	}
  2582  
  2583  	n = newNode.(*AdminStmt)
  2584  	for i, val := range n.Tables {
  2585  		node, ok := val.Accept(v)
  2586  		if !ok {
  2587  			return n, false
  2588  		}
  2589  		n.Tables[i] = node.(*TableName)
  2590  	}
  2591  
  2592  	if n.Where != nil {
  2593  		node, ok := n.Where.Accept(v)
  2594  		if !ok {
  2595  			return n, false
  2596  		}
  2597  		n.Where = node.(ExprNode)
  2598  	}
  2599  
  2600  	return v.Leave(n)
  2601  }
  2602  
  2603  // RoleOrPriv is a temporary structure to be further processed into auth.RoleIdentity or PrivElem
  2604  type RoleOrPriv struct {
  2605  	Symbols string      // hold undecided symbols
  2606  	Node    interface{} // hold auth.RoleIdentity or PrivElem that can be sure when parsing
  2607  }
  2608  
  2609  func (n *RoleOrPriv) ToRole() (*auth.RoleIdentity, error) {
  2610  	if n.Node != nil {
  2611  		if r, ok := n.Node.(*auth.RoleIdentity); ok {
  2612  			return r, nil
  2613  		}
  2614  		return nil, errors.Errorf("can't convert to RoleIdentity, type %T", n.Node)
  2615  	}
  2616  	return &auth.RoleIdentity{Username: n.Symbols, Hostname: "%"}, nil
  2617  }
  2618  
  2619  func (n *RoleOrPriv) ToPriv() (*PrivElem, error) {
  2620  	if n.Node != nil {
  2621  		if p, ok := n.Node.(*PrivElem); ok {
  2622  			return p, nil
  2623  		}
  2624  		return nil, errors.Errorf("can't convert to PrivElem, type %T", n.Node)
  2625  	}
  2626  	if len(n.Symbols) == 0 {
  2627  		return nil, errors.New("symbols should not be length 0")
  2628  	}
  2629  	return &PrivElem{Priv: mysql.ExtendedPriv, Name: n.Symbols}, nil
  2630  }
  2631  
  2632  // PrivElem is the privilege type and optional column list.
  2633  type PrivElem struct {
  2634  	node
  2635  
  2636  	Priv mysql.PrivilegeType
  2637  	Cols []*ColumnName
  2638  	Name string
  2639  }
  2640  
  2641  // Restore implements Node interface.
  2642  func (n *PrivElem) Restore(ctx *format.RestoreCtx) error {
  2643  	if n.Priv == mysql.AllPriv {
  2644  		ctx.WriteKeyWord("ALL")
  2645  	} else if n.Priv == mysql.ExtendedPriv {
  2646  		ctx.WriteKeyWord(n.Name)
  2647  	} else {
  2648  		str, ok := mysql.Priv2Str[n.Priv]
  2649  		if !ok {
  2650  			return errors.New("Undefined privilege type")
  2651  		}
  2652  		ctx.WriteKeyWord(str)
  2653  	}
  2654  	if n.Cols != nil {
  2655  		ctx.WritePlain(" (")
  2656  		for i, v := range n.Cols {
  2657  			if i != 0 {
  2658  				ctx.WritePlain(",")
  2659  			}
  2660  			if err := v.Restore(ctx); err != nil {
  2661  				return errors.Annotatef(err, "An error occurred while restore PrivElem.Cols[%d]", i)
  2662  			}
  2663  		}
  2664  		ctx.WritePlain(")")
  2665  	}
  2666  	return nil
  2667  }
  2668  
  2669  // Accept implements Node Accept interface.
  2670  func (n *PrivElem) Accept(v Visitor) (Node, bool) {
  2671  	newNode, skipChildren := v.Enter(n)
  2672  	if skipChildren {
  2673  		return v.Leave(newNode)
  2674  	}
  2675  	n = newNode.(*PrivElem)
  2676  	for i, val := range n.Cols {
  2677  		node, ok := val.Accept(v)
  2678  		if !ok {
  2679  			return n, false
  2680  		}
  2681  		n.Cols[i] = node.(*ColumnName)
  2682  	}
  2683  	return v.Leave(n)
  2684  }
  2685  
  2686  // ObjectTypeType is the type for object type.
  2687  type ObjectTypeType int
  2688  
  2689  const (
  2690  	// ObjectTypeNone is for empty object type.
  2691  	ObjectTypeNone ObjectTypeType = iota + 1
  2692  	// ObjectTypeTable means the following object is a table.
  2693  	ObjectTypeTable
  2694  	// ObjectTypeFunction means the following object is a stored function.
  2695  	ObjectTypeFunction
  2696  	// ObjectTypeProcedure means the following object is a stored procedure.
  2697  	ObjectTypeProcedure
  2698  )
  2699  
  2700  // Restore implements Node interface.
  2701  func (n ObjectTypeType) Restore(ctx *format.RestoreCtx) error {
  2702  	switch n {
  2703  	case ObjectTypeNone:
  2704  		// do nothing
  2705  	case ObjectTypeTable:
  2706  		ctx.WriteKeyWord("TABLE")
  2707  	case ObjectTypeFunction:
  2708  		ctx.WriteKeyWord("FUNCTION")
  2709  	case ObjectTypeProcedure:
  2710  		ctx.WriteKeyWord("PROCEDURE")
  2711  	default:
  2712  		return errors.New("Unsupported object type")
  2713  	}
  2714  	return nil
  2715  }
  2716  
  2717  // GrantLevelType is the type for grant level.
  2718  type GrantLevelType int
  2719  
  2720  const (
  2721  	// GrantLevelNone is the dummy const for default value.
  2722  	GrantLevelNone GrantLevelType = iota + 1
  2723  	// GrantLevelGlobal means the privileges are administrative or apply to all databases on a given server.
  2724  	GrantLevelGlobal
  2725  	// GrantLevelDB means the privileges apply to all objects in a given database.
  2726  	GrantLevelDB
  2727  	// GrantLevelTable means the privileges apply to all columns in a given table.
  2728  	GrantLevelTable
  2729  )
  2730  
  2731  // GrantLevel is used for store the privilege scope.
  2732  type GrantLevel struct {
  2733  	Level     GrantLevelType
  2734  	DBName    string
  2735  	TableName string
  2736  }
  2737  
  2738  // Restore implements Node interface.
  2739  func (n *GrantLevel) Restore(ctx *format.RestoreCtx) error {
  2740  	switch n.Level {
  2741  	case GrantLevelDB:
  2742  		if n.DBName == "" {
  2743  			ctx.WritePlain("*")
  2744  		} else {
  2745  			ctx.WriteName(n.DBName)
  2746  			ctx.WritePlain(".*")
  2747  		}
  2748  	case GrantLevelGlobal:
  2749  		ctx.WritePlain("*.*")
  2750  	case GrantLevelTable:
  2751  		if n.DBName != "" {
  2752  			ctx.WriteName(n.DBName)
  2753  			ctx.WritePlain(".")
  2754  		}
  2755  		ctx.WriteName(n.TableName)
  2756  	}
  2757  	return nil
  2758  }
  2759  
  2760  // RevokeStmt is the struct for REVOKE statement.
  2761  type RevokeStmt struct {
  2762  	stmtNode
  2763  
  2764  	Privs      []*PrivElem
  2765  	ObjectType ObjectTypeType
  2766  	Level      *GrantLevel
  2767  	Users      []*UserSpec
  2768  }
  2769  
  2770  // Restore implements Node interface.
  2771  func (n *RevokeStmt) Restore(ctx *format.RestoreCtx) error {
  2772  	ctx.WriteKeyWord("REVOKE ")
  2773  	for i, v := range n.Privs {
  2774  		if i != 0 {
  2775  			ctx.WritePlain(", ")
  2776  		}
  2777  		if err := v.Restore(ctx); err != nil {
  2778  			return errors.Annotatef(err, "An error occurred while restore RevokeStmt.Privs[%d]", i)
  2779  		}
  2780  	}
  2781  	ctx.WriteKeyWord(" ON ")
  2782  	if n.ObjectType != ObjectTypeNone {
  2783  		if err := n.ObjectType.Restore(ctx); err != nil {
  2784  			return errors.Annotate(err, "An error occurred while restore RevokeStmt.ObjectType")
  2785  		}
  2786  		ctx.WritePlain(" ")
  2787  	}
  2788  	if err := n.Level.Restore(ctx); err != nil {
  2789  		return errors.Annotate(err, "An error occurred while restore RevokeStmt.Level")
  2790  	}
  2791  	ctx.WriteKeyWord(" FROM ")
  2792  	for i, v := range n.Users {
  2793  		if i != 0 {
  2794  			ctx.WritePlain(", ")
  2795  		}
  2796  		if err := v.Restore(ctx); err != nil {
  2797  			return errors.Annotatef(err, "An error occurred while restore RevokeStmt.Users[%d]", i)
  2798  		}
  2799  	}
  2800  	return nil
  2801  }
  2802  
  2803  // Accept implements Node Accept interface.
  2804  func (n *RevokeStmt) Accept(v Visitor) (Node, bool) {
  2805  	newNode, skipChildren := v.Enter(n)
  2806  	if skipChildren {
  2807  		return v.Leave(newNode)
  2808  	}
  2809  	n = newNode.(*RevokeStmt)
  2810  	for i, val := range n.Privs {
  2811  		node, ok := val.Accept(v)
  2812  		if !ok {
  2813  			return n, false
  2814  		}
  2815  		n.Privs[i] = node.(*PrivElem)
  2816  	}
  2817  	return v.Leave(n)
  2818  }
  2819  
  2820  // RevokeStmt is the struct for REVOKE statement.
  2821  type RevokeRoleStmt struct {
  2822  	stmtNode
  2823  
  2824  	Roles []*auth.RoleIdentity
  2825  	Users []*auth.UserIdentity
  2826  }
  2827  
  2828  // Restore implements Node interface.
  2829  func (n *RevokeRoleStmt) Restore(ctx *format.RestoreCtx) error {
  2830  	ctx.WriteKeyWord("REVOKE ")
  2831  	for i, role := range n.Roles {
  2832  		if i != 0 {
  2833  			ctx.WritePlain(", ")
  2834  		}
  2835  		if err := role.Restore(ctx); err != nil {
  2836  			return errors.Annotatef(err, "An error occurred while restore RevokeRoleStmt.Roles[%d]", i)
  2837  		}
  2838  	}
  2839  	ctx.WriteKeyWord(" FROM ")
  2840  	for i, v := range n.Users {
  2841  		if i != 0 {
  2842  			ctx.WritePlain(", ")
  2843  		}
  2844  		if err := v.Restore(ctx); err != nil {
  2845  			return errors.Annotatef(err, "An error occurred while restore RevokeRoleStmt.Users[%d]", i)
  2846  		}
  2847  	}
  2848  	return nil
  2849  }
  2850  
  2851  // Accept implements Node Accept interface.
  2852  func (n *RevokeRoleStmt) Accept(v Visitor) (Node, bool) {
  2853  	newNode, skipChildren := v.Enter(n)
  2854  	if skipChildren {
  2855  		return v.Leave(newNode)
  2856  	}
  2857  	n = newNode.(*RevokeRoleStmt)
  2858  	return v.Leave(n)
  2859  }
  2860  
  2861  // GrantStmt is the struct for GRANT statement.
  2862  type GrantStmt struct {
  2863  	stmtNode
  2864  
  2865  	Privs                 []*PrivElem
  2866  	ObjectType            ObjectTypeType
  2867  	Level                 *GrantLevel
  2868  	Users                 []*UserSpec
  2869  	AuthTokenOrTLSOptions []*AuthTokenOrTLSOption
  2870  	WithGrant             bool
  2871  }
  2872  
  2873  // Restore implements Node interface.
  2874  func (n *GrantStmt) Restore(ctx *format.RestoreCtx) error {
  2875  	ctx.WriteKeyWord("GRANT ")
  2876  	for i, v := range n.Privs {
  2877  		if i != 0 && v.Priv != 0 {
  2878  			ctx.WritePlain(", ")
  2879  		} else if v.Priv == 0 {
  2880  			ctx.WritePlain(" ")
  2881  		}
  2882  		if err := v.Restore(ctx); err != nil {
  2883  			return errors.Annotatef(err, "An error occurred while restore GrantStmt.Privs[%d]", i)
  2884  		}
  2885  	}
  2886  	ctx.WriteKeyWord(" ON ")
  2887  	if n.ObjectType != ObjectTypeNone {
  2888  		if err := n.ObjectType.Restore(ctx); err != nil {
  2889  			return errors.Annotate(err, "An error occurred while restore GrantStmt.ObjectType")
  2890  		}
  2891  		ctx.WritePlain(" ")
  2892  	}
  2893  	if err := n.Level.Restore(ctx); err != nil {
  2894  		return errors.Annotate(err, "An error occurred while restore GrantStmt.Level")
  2895  	}
  2896  	ctx.WriteKeyWord(" TO ")
  2897  	for i, v := range n.Users {
  2898  		if i != 0 {
  2899  			ctx.WritePlain(", ")
  2900  		}
  2901  		if err := v.Restore(ctx); err != nil {
  2902  			return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i)
  2903  		}
  2904  	}
  2905  	if n.AuthTokenOrTLSOptions != nil {
  2906  		if len(n.AuthTokenOrTLSOptions) != 0 {
  2907  			ctx.WriteKeyWord(" REQUIRE ")
  2908  		}
  2909  		for i, option := range n.AuthTokenOrTLSOptions {
  2910  			if i != 0 {
  2911  				ctx.WriteKeyWord(" AND ")
  2912  			}
  2913  			if err := option.Restore(ctx); err != nil {
  2914  				return errors.Annotatef(err, "An error occurred while restore GrantStmt.AuthTokenOrTLSOptions[%d]", i)
  2915  			}
  2916  		}
  2917  	}
  2918  	if n.WithGrant {
  2919  		ctx.WriteKeyWord(" WITH GRANT OPTION")
  2920  	}
  2921  	return nil
  2922  }
  2923  
  2924  // SecureText implements SensitiveStatement interface.
  2925  func (n *GrantStmt) SecureText() string {
  2926  	text := n.text
  2927  	// Filter "identified by xxx" because it would expose password information.
  2928  	idx := strings.Index(strings.ToLower(text), "identified")
  2929  	if idx > 0 {
  2930  		text = text[:idx]
  2931  	}
  2932  	return text
  2933  }
  2934  
  2935  // Accept implements Node Accept interface.
  2936  func (n *GrantStmt) Accept(v Visitor) (Node, bool) {
  2937  	newNode, skipChildren := v.Enter(n)
  2938  	if skipChildren {
  2939  		return v.Leave(newNode)
  2940  	}
  2941  	n = newNode.(*GrantStmt)
  2942  	for i, val := range n.Privs {
  2943  		node, ok := val.Accept(v)
  2944  		if !ok {
  2945  			return n, false
  2946  		}
  2947  		n.Privs[i] = node.(*PrivElem)
  2948  	}
  2949  	return v.Leave(n)
  2950  }
  2951  
  2952  // GrantProxyStmt is the struct for GRANT PROXY statement.
  2953  type GrantProxyStmt struct {
  2954  	stmtNode
  2955  
  2956  	LocalUser     *auth.UserIdentity
  2957  	ExternalUsers []*auth.UserIdentity
  2958  	WithGrant     bool
  2959  }
  2960  
  2961  // Accept implements Node Accept interface.
  2962  func (n *GrantProxyStmt) Accept(v Visitor) (Node, bool) {
  2963  	newNode, skipChildren := v.Enter(n)
  2964  	if skipChildren {
  2965  		return v.Leave(newNode)
  2966  	}
  2967  	n = newNode.(*GrantProxyStmt)
  2968  	return v.Leave(n)
  2969  }
  2970  
  2971  // Restore implements Node interface.
  2972  func (n *GrantProxyStmt) Restore(ctx *format.RestoreCtx) error {
  2973  	ctx.WriteKeyWord("GRANT PROXY ON ")
  2974  	if err := n.LocalUser.Restore(ctx); err != nil {
  2975  		return errors.Annotatef(err, "An error occurred while restore GrantProxyStmt.LocalUser")
  2976  	}
  2977  	ctx.WriteKeyWord(" TO ")
  2978  	for i, v := range n.ExternalUsers {
  2979  		if i != 0 {
  2980  			ctx.WritePlain(", ")
  2981  		}
  2982  		if err := v.Restore(ctx); err != nil {
  2983  			return errors.Annotatef(err, "An error occurred while restore GrantProxyStmt.ExternalUsers[%d]", i)
  2984  		}
  2985  	}
  2986  	if n.WithGrant {
  2987  		ctx.WriteKeyWord(" WITH GRANT OPTION")
  2988  	}
  2989  	return nil
  2990  }
  2991  
  2992  // GrantRoleStmt is the struct for GRANT TO statement.
  2993  type GrantRoleStmt struct {
  2994  	stmtNode
  2995  
  2996  	Roles []*auth.RoleIdentity
  2997  	Users []*auth.UserIdentity
  2998  }
  2999  
  3000  // Accept implements Node Accept interface.
  3001  func (n *GrantRoleStmt) Accept(v Visitor) (Node, bool) {
  3002  	newNode, skipChildren := v.Enter(n)
  3003  	if skipChildren {
  3004  		return v.Leave(newNode)
  3005  	}
  3006  	n = newNode.(*GrantRoleStmt)
  3007  	return v.Leave(n)
  3008  }
  3009  
  3010  // Restore implements Node interface.
  3011  func (n *GrantRoleStmt) Restore(ctx *format.RestoreCtx) error {
  3012  	ctx.WriteKeyWord("GRANT ")
  3013  	if len(n.Roles) > 0 {
  3014  		for i, role := range n.Roles {
  3015  			if i != 0 {
  3016  				ctx.WritePlain(", ")
  3017  			}
  3018  			if err := role.Restore(ctx); err != nil {
  3019  				return errors.Annotatef(err, "An error occurred while restore GrantRoleStmt.Roles[%d]", i)
  3020  			}
  3021  		}
  3022  	}
  3023  	ctx.WriteKeyWord(" TO ")
  3024  	for i, v := range n.Users {
  3025  		if i != 0 {
  3026  			ctx.WritePlain(", ")
  3027  		}
  3028  		if err := v.Restore(ctx); err != nil {
  3029  			return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i)
  3030  		}
  3031  	}
  3032  	return nil
  3033  }
  3034  
  3035  // SecureText implements SensitiveStatement interface.
  3036  func (n *GrantRoleStmt) SecureText() string {
  3037  	text := n.text
  3038  	// Filter "identified by xxx" because it would expose password information.
  3039  	idx := strings.Index(strings.ToLower(text), "identified")
  3040  	if idx > 0 {
  3041  		text = text[:idx]
  3042  	}
  3043  	return text
  3044  }
  3045  
  3046  // ShutdownStmt is a statement to stop the TiDB server.
  3047  // See https://dev.mysql.com/doc/refman/5.7/en/shutdown.html
  3048  type ShutdownStmt struct {
  3049  	stmtNode
  3050  }
  3051  
  3052  // Restore implements Node interface.
  3053  func (n *ShutdownStmt) Restore(ctx *format.RestoreCtx) error {
  3054  	ctx.WriteKeyWord("SHUTDOWN")
  3055  	return nil
  3056  }
  3057  
  3058  // Accept implements Node Accept interface.
  3059  func (n *ShutdownStmt) Accept(v Visitor) (Node, bool) {
  3060  	newNode, skipChildren := v.Enter(n)
  3061  	if skipChildren {
  3062  		return v.Leave(newNode)
  3063  	}
  3064  	n = newNode.(*ShutdownStmt)
  3065  	return v.Leave(n)
  3066  }
  3067  
  3068  // RestartStmt is a statement to restart the TiDB server.
  3069  // See https://dev.mysql.com/doc/refman/8.0/en/restart.html
  3070  type RestartStmt struct {
  3071  	stmtNode
  3072  }
  3073  
  3074  // Restore implements Node interface.
  3075  func (n *RestartStmt) Restore(ctx *format.RestoreCtx) error {
  3076  	ctx.WriteKeyWord("RESTART")
  3077  	return nil
  3078  }
  3079  
  3080  // Accept implements Node Accept interface.
  3081  func (n *RestartStmt) Accept(v Visitor) (Node, bool) {
  3082  	newNode, skipChildren := v.Enter(n)
  3083  	if skipChildren {
  3084  		return v.Leave(newNode)
  3085  	}
  3086  	n = newNode.(*RestartStmt)
  3087  	return v.Leave(n)
  3088  }
  3089  
  3090  // HelpStmt is a statement for server side help
  3091  // See https://dev.mysql.com/doc/refman/8.0/en/help.html
  3092  type HelpStmt struct {
  3093  	stmtNode
  3094  
  3095  	Topic string
  3096  }
  3097  
  3098  // Restore implements Node interface.
  3099  func (n *HelpStmt) Restore(ctx *format.RestoreCtx) error {
  3100  	ctx.WriteKeyWord("HELP ")
  3101  	ctx.WriteString(n.Topic)
  3102  	return nil
  3103  }
  3104  
  3105  // Accept implements Node Accept interface.
  3106  func (n *HelpStmt) Accept(v Visitor) (Node, bool) {
  3107  	newNode, skipChildren := v.Enter(n)
  3108  	if skipChildren {
  3109  		return v.Leave(newNode)
  3110  	}
  3111  	n = newNode.(*HelpStmt)
  3112  	return v.Leave(n)
  3113  }
  3114  
  3115  // RenameUserStmt is a statement to rename a user.
  3116  // See http://dev.mysql.com/doc/refman/5.7/en/rename-user.html
  3117  type RenameUserStmt struct {
  3118  	stmtNode
  3119  
  3120  	UserToUsers []*UserToUser
  3121  }
  3122  
  3123  // Restore implements Node interface.
  3124  func (n *RenameUserStmt) Restore(ctx *format.RestoreCtx) error {
  3125  	ctx.WriteKeyWord("RENAME USER ")
  3126  	for index, user2user := range n.UserToUsers {
  3127  		if index != 0 {
  3128  			ctx.WritePlain(", ")
  3129  		}
  3130  		if err := user2user.Restore(ctx); err != nil {
  3131  			return errors.Annotate(err, "An error occurred while restore RenameUserStmt.UserToUsers")
  3132  		}
  3133  	}
  3134  	return nil
  3135  }
  3136  
  3137  // Accept implements Node Accept interface.
  3138  func (n *RenameUserStmt) Accept(v Visitor) (Node, bool) {
  3139  	newNode, skipChildren := v.Enter(n)
  3140  	if skipChildren {
  3141  		return v.Leave(newNode)
  3142  	}
  3143  	n = newNode.(*RenameUserStmt)
  3144  
  3145  	for i, t := range n.UserToUsers {
  3146  		node, ok := t.Accept(v)
  3147  		if !ok {
  3148  			return n, false
  3149  		}
  3150  		n.UserToUsers[i] = node.(*UserToUser)
  3151  	}
  3152  	return v.Leave(n)
  3153  }
  3154  
  3155  // UserToUser represents renaming old user to new user used in RenameUserStmt.
  3156  type UserToUser struct {
  3157  	node
  3158  	OldUser *auth.UserIdentity
  3159  	NewUser *auth.UserIdentity
  3160  }
  3161  
  3162  // Restore implements Node interface.
  3163  func (n *UserToUser) Restore(ctx *format.RestoreCtx) error {
  3164  	if err := n.OldUser.Restore(ctx); err != nil {
  3165  		return errors.Annotate(err, "An error occurred while restore UserToUser.OldUser")
  3166  	}
  3167  	ctx.WriteKeyWord(" TO ")
  3168  	if err := n.NewUser.Restore(ctx); err != nil {
  3169  		return errors.Annotate(err, "An error occurred while restore UserToUser.NewUser")
  3170  	}
  3171  	return nil
  3172  }
  3173  
  3174  // Accept implements Node Accept interface.
  3175  func (n *UserToUser) Accept(v Visitor) (Node, bool) {
  3176  	newNode, skipChildren := v.Enter(n)
  3177  	if skipChildren {
  3178  		return v.Leave(newNode)
  3179  	}
  3180  	n = newNode.(*UserToUser)
  3181  	return v.Leave(n)
  3182  }
  3183  
  3184  type BRIEKind uint8
  3185  type BRIEOptionType uint16
  3186  
  3187  const (
  3188  	BRIEKindBackup BRIEKind = iota
  3189  	BRIEKindCancelJob
  3190  	BRIEKindStreamStart
  3191  	BRIEKindStreamMetaData
  3192  	BRIEKindStreamStatus
  3193  	BRIEKindStreamPause
  3194  	BRIEKindStreamResume
  3195  	BRIEKindStreamStop
  3196  	BRIEKindStreamPurge
  3197  	BRIEKindRestore
  3198  	BRIEKindRestorePIT
  3199  	BRIEKindShowJob
  3200  	BRIEKindShowQuery
  3201  	BRIEKindShowBackupMeta
  3202  	// common BRIE options
  3203  	BRIEOptionRateLimit BRIEOptionType = iota + 1
  3204  	BRIEOptionConcurrency
  3205  	BRIEOptionChecksum
  3206  	BRIEOptionSendCreds
  3207  	BRIEOptionCheckpoint
  3208  	BRIEOptionStartTS
  3209  	BRIEOptionUntilTS
  3210  	// backup options
  3211  	BRIEOptionBackupTimeAgo
  3212  	BRIEOptionBackupTS
  3213  	BRIEOptionBackupTSO
  3214  	BRIEOptionLastBackupTS
  3215  	BRIEOptionLastBackupTSO
  3216  	BRIEOptionGCTTL
  3217  	// restore options
  3218  	BRIEOptionOnline
  3219  	BRIEOptionFullBackupStorage
  3220  	BRIEOptionRestoredTS
  3221  	// import options
  3222  	BRIEOptionAnalyze
  3223  	BRIEOptionBackend
  3224  	BRIEOptionOnDuplicate
  3225  	BRIEOptionSkipSchemaFiles
  3226  	BRIEOptionStrictFormat
  3227  	BRIEOptionTiKVImporter
  3228  	BRIEOptionResume
  3229  	// CSV options
  3230  	BRIEOptionCSVBackslashEscape
  3231  	BRIEOptionCSVDelimiter
  3232  	BRIEOptionCSVHeader
  3233  	BRIEOptionCSVNotNull
  3234  	BRIEOptionCSVNull
  3235  	BRIEOptionCSVSeparator
  3236  	BRIEOptionCSVTrimLastSeparators
  3237  
  3238  	BRIECSVHeaderIsColumns = ^uint64(0)
  3239  )
  3240  
  3241  type BRIEOptionLevel uint64
  3242  
  3243  const (
  3244  	BRIEOptionLevelOff      BRIEOptionLevel = iota // equals FALSE
  3245  	BRIEOptionLevelRequired                        // equals TRUE
  3246  	BRIEOptionLevelOptional
  3247  )
  3248  
  3249  func (kind BRIEKind) String() string {
  3250  	switch kind {
  3251  	case BRIEKindBackup:
  3252  		return "BACKUP"
  3253  	case BRIEKindRestore:
  3254  		return "RESTORE"
  3255  	case BRIEKindStreamStart:
  3256  		return "BACKUP LOGS"
  3257  	case BRIEKindStreamStop:
  3258  		return "STOP BACKUP LOGS"
  3259  	case BRIEKindStreamPause:
  3260  		return "PAUSE BACKUP LOGS"
  3261  	case BRIEKindStreamResume:
  3262  		return "RESUME BACKUP LOGS"
  3263  	case BRIEKindStreamStatus:
  3264  		return "SHOW BACKUP LOGS STATUS"
  3265  	case BRIEKindStreamMetaData:
  3266  		return "SHOW BACKUP LOGS METADATA"
  3267  	case BRIEKindStreamPurge:
  3268  		return "PURGE BACKUP LOGS"
  3269  	case BRIEKindRestorePIT:
  3270  		return "RESTORE POINT"
  3271  	case BRIEKindShowJob:
  3272  		return "SHOW BR JOB"
  3273  	case BRIEKindShowQuery:
  3274  		return "SHOW BR JOB QUERY"
  3275  	case BRIEKindCancelJob:
  3276  		return "CANCEL BR JOB"
  3277  	case BRIEKindShowBackupMeta:
  3278  		return "SHOW BACKUP METADATA"
  3279  	default:
  3280  		return ""
  3281  	}
  3282  }
  3283  
  3284  func (kind BRIEOptionType) String() string {
  3285  	switch kind {
  3286  	case BRIEOptionRateLimit:
  3287  		return "RATE_LIMIT"
  3288  	case BRIEOptionConcurrency:
  3289  		return "CONCURRENCY"
  3290  	case BRIEOptionChecksum:
  3291  		return "CHECKSUM"
  3292  	case BRIEOptionSendCreds:
  3293  		return "SEND_CREDENTIALS_TO_TIKV"
  3294  	case BRIEOptionBackupTimeAgo, BRIEOptionBackupTS, BRIEOptionBackupTSO:
  3295  		return "SNAPSHOT"
  3296  	case BRIEOptionLastBackupTS, BRIEOptionLastBackupTSO:
  3297  		return "LAST_BACKUP"
  3298  	case BRIEOptionOnline:
  3299  		return "ONLINE"
  3300  	case BRIEOptionCheckpoint:
  3301  		return "CHECKPOINT"
  3302  	case BRIEOptionAnalyze:
  3303  		return "ANALYZE"
  3304  	case BRIEOptionBackend:
  3305  		return "BACKEND"
  3306  	case BRIEOptionOnDuplicate:
  3307  		return "ON_DUPLICATE"
  3308  	case BRIEOptionSkipSchemaFiles:
  3309  		return "SKIP_SCHEMA_FILES"
  3310  	case BRIEOptionStrictFormat:
  3311  		return "STRICT_FORMAT"
  3312  	case BRIEOptionTiKVImporter:
  3313  		return "TIKV_IMPORTER"
  3314  	case BRIEOptionResume:
  3315  		return "RESUME"
  3316  	case BRIEOptionCSVBackslashEscape:
  3317  		return "CSV_BACKSLASH_ESCAPE"
  3318  	case BRIEOptionCSVDelimiter:
  3319  		return "CSV_DELIMITER"
  3320  	case BRIEOptionCSVHeader:
  3321  		return "CSV_HEADER"
  3322  	case BRIEOptionCSVNotNull:
  3323  		return "CSV_NOT_NULL"
  3324  	case BRIEOptionCSVNull:
  3325  		return "CSV_NULL"
  3326  	case BRIEOptionCSVSeparator:
  3327  		return "CSV_SEPARATOR"
  3328  	case BRIEOptionCSVTrimLastSeparators:
  3329  		return "CSV_TRIM_LAST_SEPARATORS"
  3330  	case BRIEOptionFullBackupStorage:
  3331  		return "FULL_BACKUP_STORAGE"
  3332  	case BRIEOptionRestoredTS:
  3333  		return "RESTORED_TS"
  3334  	case BRIEOptionStartTS:
  3335  		return "START_TS"
  3336  	case BRIEOptionUntilTS:
  3337  		return "UNTIL_TS"
  3338  	case BRIEOptionGCTTL:
  3339  		return "GC_TTL"
  3340  	default:
  3341  		return ""
  3342  	}
  3343  }
  3344  
  3345  func (level BRIEOptionLevel) String() string {
  3346  	switch level {
  3347  	case BRIEOptionLevelOff:
  3348  		return "OFF"
  3349  	case BRIEOptionLevelOptional:
  3350  		return "OPTIONAL"
  3351  	case BRIEOptionLevelRequired:
  3352  		return "REQUIRED"
  3353  	default:
  3354  		return ""
  3355  	}
  3356  }
  3357  
  3358  type BRIEOption struct {
  3359  	Tp        BRIEOptionType
  3360  	StrValue  string
  3361  	UintValue uint64
  3362  }
  3363  
  3364  func (opt *BRIEOption) Restore(ctx *format.RestoreCtx) error {
  3365  	ctx.WriteKeyWord(opt.Tp.String())
  3366  	ctx.WritePlain(" = ")
  3367  	switch opt.Tp {
  3368  	case BRIEOptionBackupTS, BRIEOptionLastBackupTS, BRIEOptionBackend, BRIEOptionOnDuplicate, BRIEOptionTiKVImporter, BRIEOptionCSVDelimiter, BRIEOptionCSVNull, BRIEOptionCSVSeparator, BRIEOptionFullBackupStorage, BRIEOptionRestoredTS, BRIEOptionStartTS, BRIEOptionUntilTS, BRIEOptionGCTTL:
  3369  		ctx.WriteString(opt.StrValue)
  3370  	case BRIEOptionBackupTimeAgo:
  3371  		ctx.WritePlainf("%d ", opt.UintValue/1000)
  3372  		ctx.WriteKeyWord("MICROSECOND AGO")
  3373  	case BRIEOptionRateLimit:
  3374  		ctx.WritePlainf("%d ", opt.UintValue/1048576)
  3375  		ctx.WriteKeyWord("MB")
  3376  		ctx.WritePlain("/")
  3377  		ctx.WriteKeyWord("SECOND")
  3378  	case BRIEOptionCSVHeader:
  3379  		if opt.UintValue == BRIECSVHeaderIsColumns {
  3380  			ctx.WriteKeyWord("COLUMNS")
  3381  		} else {
  3382  			ctx.WritePlainf("%d", opt.UintValue)
  3383  		}
  3384  	case BRIEOptionChecksum, BRIEOptionAnalyze:
  3385  		// BACKUP/RESTORE doesn't support OPTIONAL value for now, should warn at executor
  3386  		ctx.WriteKeyWord(BRIEOptionLevel(opt.UintValue).String())
  3387  	default:
  3388  		ctx.WritePlainf("%d", opt.UintValue)
  3389  	}
  3390  	return nil
  3391  }
  3392  
  3393  // BRIEStmt is a statement for backup, restore, import and export.
  3394  type BRIEStmt struct {
  3395  	stmtNode
  3396  
  3397  	Kind    BRIEKind
  3398  	Schemas []string
  3399  	Tables  []*TableName
  3400  	Storage string
  3401  	JobID   int64
  3402  	Options []*BRIEOption
  3403  }
  3404  
  3405  func (n *BRIEStmt) Accept(v Visitor) (Node, bool) {
  3406  	newNode, skipChildren := v.Enter(n)
  3407  	if skipChildren {
  3408  		return v.Leave(newNode)
  3409  	}
  3410  	n = newNode.(*BRIEStmt)
  3411  	for i, val := range n.Tables {
  3412  		node, ok := val.Accept(v)
  3413  		if !ok {
  3414  			return n, false
  3415  		}
  3416  		n.Tables[i] = node.(*TableName)
  3417  	}
  3418  	return v.Leave(n)
  3419  }
  3420  
  3421  func (n *BRIEStmt) Restore(ctx *format.RestoreCtx) error {
  3422  	ctx.WriteKeyWord(n.Kind.String())
  3423  
  3424  	switch n.Kind {
  3425  	case BRIEKindRestore, BRIEKindBackup:
  3426  		switch {
  3427  		case len(n.Tables) != 0:
  3428  			ctx.WriteKeyWord(" TABLE ")
  3429  			for index, table := range n.Tables {
  3430  				if index != 0 {
  3431  					ctx.WritePlain(", ")
  3432  				}
  3433  				if err := table.Restore(ctx); err != nil {
  3434  					return errors.Annotatef(err, "An error occurred while restore BRIEStmt.Tables[%d]", index)
  3435  				}
  3436  			}
  3437  		case len(n.Schemas) != 0:
  3438  			ctx.WriteKeyWord(" DATABASE ")
  3439  			for index, schema := range n.Schemas {
  3440  				if index != 0 {
  3441  					ctx.WritePlain(", ")
  3442  				}
  3443  				ctx.WriteName(schema)
  3444  			}
  3445  		default:
  3446  			ctx.WriteKeyWord(" DATABASE")
  3447  			ctx.WritePlain(" *")
  3448  		}
  3449  
  3450  		if n.Kind == BRIEKindBackup {
  3451  			ctx.WriteKeyWord(" TO ")
  3452  			ctx.WriteString(n.Storage)
  3453  		} else {
  3454  			ctx.WriteKeyWord(" FROM ")
  3455  			ctx.WriteString(n.Storage)
  3456  		}
  3457  	case BRIEKindCancelJob, BRIEKindShowJob, BRIEKindShowQuery:
  3458  		ctx.WritePlainf(" %d", n.JobID)
  3459  	case BRIEKindStreamStart:
  3460  		ctx.WriteKeyWord(" TO ")
  3461  		ctx.WriteString(n.Storage)
  3462  	case BRIEKindRestorePIT, BRIEKindStreamMetaData, BRIEKindShowBackupMeta, BRIEKindStreamPurge:
  3463  		ctx.WriteKeyWord(" FROM ")
  3464  		ctx.WriteString(n.Storage)
  3465  	}
  3466  
  3467  	for _, opt := range n.Options {
  3468  		ctx.WritePlain(" ")
  3469  		if err := opt.Restore(ctx); err != nil {
  3470  			return err
  3471  		}
  3472  	}
  3473  
  3474  	return nil
  3475  }
  3476  
  3477  // RedactURL redacts the secret tokens in the URL. only S3 url need redaction for now.
  3478  // if the url is not a valid url, return the original string.
  3479  func RedactURL(str string) string {
  3480  	// FIXME: this solution is not scalable, and duplicates some logic from BR.
  3481  	u, err := url.Parse(str)
  3482  	if err != nil {
  3483  		return str
  3484  	}
  3485  	scheme := u.Scheme
  3486  	failpoint.Inject("forceRedactURL", func() {
  3487  		scheme = "s3"
  3488  	})
  3489  	if strings.ToLower(scheme) == "s3" {
  3490  		values := u.Query()
  3491  		for k := range values {
  3492  			// see below on why we normalize key
  3493  			// https://github.com/pingcap/tidb/blob/a7c0d95f16ea2582bb569278c3f829403e6c3a7e/br/pkg/storage/parse.go#L163
  3494  			normalizedKey := strings.ToLower(strings.ReplaceAll(k, "_", "-"))
  3495  			if normalizedKey == "access-key" || normalizedKey == "secret-access-key" || normalizedKey == "session-token" {
  3496  				values[k] = []string{"xxxxxx"}
  3497  			}
  3498  		}
  3499  		u.RawQuery = values.Encode()
  3500  	}
  3501  	return u.String()
  3502  }
  3503  
  3504  // SecureText implements SensitiveStmtNode
  3505  func (n *BRIEStmt) SecureText() string {
  3506  	redactedStmt := &BRIEStmt{
  3507  		Kind:    n.Kind,
  3508  		Schemas: n.Schemas,
  3509  		Tables:  n.Tables,
  3510  		Storage: RedactURL(n.Storage),
  3511  		Options: n.Options,
  3512  	}
  3513  
  3514  	var sb strings.Builder
  3515  	_ = redactedStmt.Restore(format.NewRestoreCtx(format.DefaultRestoreFlags, &sb))
  3516  	return sb.String()
  3517  }
  3518  
  3519  type LoadDataActionTp int
  3520  
  3521  const (
  3522  	LoadDataPause LoadDataActionTp = iota
  3523  	LoadDataResume
  3524  	LoadDataCancel
  3525  	LoadDataDrop
  3526  )
  3527  
  3528  // LoadDataActionStmt represent PAUSE/RESUME/CANCEL/DROP LOAD DATA JOB statement.
  3529  type LoadDataActionStmt struct {
  3530  	stmtNode
  3531  
  3532  	Tp    LoadDataActionTp
  3533  	JobID int64
  3534  }
  3535  
  3536  func (n *LoadDataActionStmt) Accept(v Visitor) (Node, bool) {
  3537  	newNode, _ := v.Enter(n)
  3538  	return v.Leave(newNode)
  3539  }
  3540  
  3541  func (n *LoadDataActionStmt) Restore(ctx *format.RestoreCtx) error {
  3542  	switch n.Tp {
  3543  	case LoadDataPause:
  3544  		ctx.WriteKeyWord("PAUSE LOAD DATA JOB ")
  3545  	case LoadDataResume:
  3546  		ctx.WriteKeyWord("RESUME LOAD DATA JOB ")
  3547  	case LoadDataCancel:
  3548  		ctx.WriteKeyWord("CANCEL LOAD DATA JOB ")
  3549  	case LoadDataDrop:
  3550  		ctx.WriteKeyWord("DROP LOAD DATA JOB ")
  3551  	default:
  3552  		return errors.Errorf("invalid load data action type: %d", n.Tp)
  3553  	}
  3554  	ctx.WritePlainf("%d", n.JobID)
  3555  	return nil
  3556  }
  3557  
  3558  type ImportIntoActionTp string
  3559  
  3560  const (
  3561  	ImportIntoCancel ImportIntoActionTp = "cancel"
  3562  )
  3563  
  3564  // ImportIntoActionStmt represent CANCEL IMPORT INTO JOB statement.
  3565  // will support pause/resume/drop later.
  3566  type ImportIntoActionStmt struct {
  3567  	stmtNode
  3568  
  3569  	Tp    ImportIntoActionTp
  3570  	JobID int64
  3571  }
  3572  
  3573  func (n *ImportIntoActionStmt) Accept(v Visitor) (Node, bool) {
  3574  	newNode, _ := v.Enter(n)
  3575  	return v.Leave(newNode)
  3576  }
  3577  
  3578  func (n *ImportIntoActionStmt) Restore(ctx *format.RestoreCtx) error {
  3579  	if n.Tp != ImportIntoCancel {
  3580  		return errors.Errorf("invalid IMPORT INTO action type: %s", n.Tp)
  3581  	}
  3582  	ctx.WriteKeyWord("CANCEL IMPORT JOB ")
  3583  	ctx.WritePlainf("%d", n.JobID)
  3584  	return nil
  3585  }
  3586  
  3587  // Ident is the table identifier composed of schema name and table name.
  3588  type Ident struct {
  3589  	Schema model.CIStr
  3590  	Name   model.CIStr
  3591  }
  3592  
  3593  // String implements fmt.Stringer interface.
  3594  func (i Ident) String() string {
  3595  	if i.Schema.O == "" {
  3596  		return i.Name.O
  3597  	}
  3598  	return fmt.Sprintf("%s.%s", i.Schema, i.Name)
  3599  }
  3600  
  3601  // SelectStmtOpts wrap around select hints and switches
  3602  type SelectStmtOpts struct {
  3603  	Distinct        bool
  3604  	SQLBigResult    bool
  3605  	SQLBufferResult bool
  3606  	SQLCache        bool
  3607  	SQLSmallResult  bool
  3608  	CalcFoundRows   bool
  3609  	StraightJoin    bool
  3610  	Priority        mysql.PriorityEnum
  3611  	TableHints      []*TableOptimizerHint
  3612  	ExplicitAll     bool
  3613  }
  3614  
  3615  // TableOptimizerHint is Table level optimizer hint
  3616  type TableOptimizerHint struct {
  3617  	node
  3618  	// HintName is the name or alias of the table(s) which the hint will affect.
  3619  	// Table hints has no schema info
  3620  	// It allows only table name or alias (if table has an alias)
  3621  	HintName model.CIStr
  3622  	// HintData is the payload of the hint. The actual type of this field
  3623  	// is defined differently as according `HintName`. Define as following:
  3624  	//
  3625  	// Statement Execution Time Optimizer Hints
  3626  	// See https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html#optimizer-hints-execution-time
  3627  	// - MAX_EXECUTION_TIME  => uint64
  3628  	// - MEMORY_QUOTA        => int64
  3629  	// - QUERY_TYPE          => model.CIStr
  3630  	//
  3631  	// Time Range is used to hint the time range of inspection tables
  3632  	// e.g: select /*+ time_range('','') */ * from information_schema.inspection_result.
  3633  	// - TIME_RANGE          => ast.HintTimeRange
  3634  	// - READ_FROM_STORAGE   => model.CIStr
  3635  	// - USE_TOJA            => bool
  3636  	// - NTH_PLAN            => int64
  3637  	HintData interface{}
  3638  	// QBName is the default effective query block of this hint.
  3639  	QBName  model.CIStr
  3640  	Tables  []HintTable
  3641  	Indexes []model.CIStr
  3642  }
  3643  
  3644  // HintTimeRange is the payload of `TIME_RANGE` hint
  3645  type HintTimeRange struct {
  3646  	From string
  3647  	To   string
  3648  }
  3649  
  3650  // HintSetVar is the payload of `SET_VAR` hint
  3651  type HintSetVar struct {
  3652  	VarName string
  3653  	Value   string
  3654  }
  3655  
  3656  // HintTable is table in the hint. It may have query block info.
  3657  type HintTable struct {
  3658  	DBName        model.CIStr
  3659  	TableName     model.CIStr
  3660  	QBName        model.CIStr
  3661  	PartitionList []model.CIStr
  3662  }
  3663  
  3664  func (ht *HintTable) Restore(ctx *format.RestoreCtx) {
  3665  	if ht.DBName.L != "" {
  3666  		ctx.WriteName(ht.DBName.String())
  3667  		ctx.WriteKeyWord(".")
  3668  	}
  3669  	ctx.WriteName(ht.TableName.String())
  3670  	if ht.QBName.L != "" {
  3671  		ctx.WriteKeyWord("@")
  3672  		ctx.WriteName(ht.QBName.String())
  3673  	}
  3674  	if len(ht.PartitionList) > 0 {
  3675  		ctx.WriteKeyWord(" PARTITION")
  3676  		ctx.WritePlain("(")
  3677  		for i, p := range ht.PartitionList {
  3678  			if i > 0 {
  3679  				ctx.WritePlain(", ")
  3680  			}
  3681  			ctx.WriteName(p.String())
  3682  		}
  3683  		ctx.WritePlain(")")
  3684  	}
  3685  }
  3686  
  3687  // Restore implements Node interface.
  3688  func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error {
  3689  	ctx.WriteKeyWord(n.HintName.String())
  3690  	ctx.WritePlain("(")
  3691  	if n.QBName.L != "" {
  3692  		if n.HintName.L != "qb_name" {
  3693  			ctx.WriteKeyWord("@")
  3694  		}
  3695  		ctx.WriteName(n.QBName.String())
  3696  	}
  3697  	if n.HintName.L == "qb_name" && len(n.Tables) == 0 {
  3698  		ctx.WritePlain(")")
  3699  		return nil
  3700  	}
  3701  	// Hints without args except query block.
  3702  	switch n.HintName.L {
  3703  	case "mpp_1phase_agg", "mpp_2phase_agg", "hash_agg", "stream_agg", "agg_to_cop", "read_consistent_replica", "no_index_merge", "ignore_plan_cache", "limit_to_cop", "straight_join", "merge", "no_decorrelate":
  3704  		ctx.WritePlain(")")
  3705  		return nil
  3706  	}
  3707  	if n.QBName.L != "" {
  3708  		ctx.WritePlain(" ")
  3709  	}
  3710  	// Hints with args except query block.
  3711  	switch n.HintName.L {
  3712  	case "max_execution_time":
  3713  		ctx.WritePlainf("%d", n.HintData.(uint64))
  3714  	case "resource_group":
  3715  		ctx.WriteName(n.HintData.(string))
  3716  	case "nth_plan":
  3717  		ctx.WritePlainf("%d", n.HintData.(int64))
  3718  	case "tidb_hj", "tidb_smj", "tidb_inlj", "hash_join", "hash_join_build", "hash_join_probe", "merge_join", "inl_join", "broadcast_join", "shuffle_join", "inl_hash_join", "inl_merge_join", "leading":
  3719  		for i, table := range n.Tables {
  3720  			if i != 0 {
  3721  				ctx.WritePlain(", ")
  3722  			}
  3723  			table.Restore(ctx)
  3724  		}
  3725  	case "use_index", "ignore_index", "use_index_merge", "force_index", "order_index", "no_order_index":
  3726  		n.Tables[0].Restore(ctx)
  3727  		ctx.WritePlain(" ")
  3728  		for i, index := range n.Indexes {
  3729  			if i != 0 {
  3730  				ctx.WritePlain(", ")
  3731  			}
  3732  			ctx.WriteName(index.String())
  3733  		}
  3734  	case "qb_name":
  3735  		if len(n.Tables) > 0 {
  3736  			ctx.WritePlain(", ")
  3737  			for i, table := range n.Tables {
  3738  				if i != 0 {
  3739  					ctx.WritePlain(". ")
  3740  				}
  3741  				table.Restore(ctx)
  3742  			}
  3743  		}
  3744  	case "use_toja", "use_cascades":
  3745  		if n.HintData.(bool) {
  3746  			ctx.WritePlain("TRUE")
  3747  		} else {
  3748  			ctx.WritePlain("FALSE")
  3749  		}
  3750  	case "query_type":
  3751  		ctx.WriteKeyWord(n.HintData.(model.CIStr).String())
  3752  	case "memory_quota":
  3753  		ctx.WritePlainf("%d MB", n.HintData.(int64)/1024/1024)
  3754  	case "read_from_storage":
  3755  		ctx.WriteKeyWord(n.HintData.(model.CIStr).String())
  3756  		for i, table := range n.Tables {
  3757  			if i == 0 {
  3758  				ctx.WritePlain("[")
  3759  			}
  3760  			table.Restore(ctx)
  3761  			if i == len(n.Tables)-1 {
  3762  				ctx.WritePlain("]")
  3763  			} else {
  3764  				ctx.WritePlain(", ")
  3765  			}
  3766  		}
  3767  	case "time_range":
  3768  		hintData := n.HintData.(HintTimeRange)
  3769  		ctx.WriteString(hintData.From)
  3770  		ctx.WritePlain(", ")
  3771  		ctx.WriteString(hintData.To)
  3772  	case "set_var":
  3773  		hintData := n.HintData.(HintSetVar)
  3774  		ctx.WritePlain(hintData.VarName)
  3775  		ctx.WritePlain(" = ")
  3776  		ctx.WritePlain(hintData.Value)
  3777  	}
  3778  	ctx.WritePlain(")")
  3779  	return nil
  3780  }
  3781  
  3782  // Accept implements Node Accept interface.
  3783  func (n *TableOptimizerHint) Accept(v Visitor) (Node, bool) {
  3784  	newNode, skipChildren := v.Enter(n)
  3785  	if skipChildren {
  3786  		return v.Leave(newNode)
  3787  	}
  3788  	n = newNode.(*TableOptimizerHint)
  3789  	return v.Leave(n)
  3790  }
  3791  
  3792  // TextString represent a string, it can be a binary literal.
  3793  type TextString struct {
  3794  	Value           string
  3795  	IsBinaryLiteral bool
  3796  }
  3797  
  3798  type BinaryLiteral interface {
  3799  	ToString() string
  3800  }
  3801  
  3802  // NewDecimal creates a types.Decimal value, it's provided by parser driver.
  3803  var NewDecimal func(string) (interface{}, error)
  3804  
  3805  // NewHexLiteral creates a types.HexLiteral value, it's provided by parser driver.
  3806  var NewHexLiteral func(string) (interface{}, error)
  3807  
  3808  // NewBitLiteral creates a types.BitLiteral value, it's provided by parser driver.
  3809  var NewBitLiteral func(string) (interface{}, error)
  3810  
  3811  // SetResourceGroupStmt is a statement to set the resource group name for current session.
  3812  type SetResourceGroupStmt struct {
  3813  	stmtNode
  3814  	Name model.CIStr
  3815  }
  3816  
  3817  func (n *SetResourceGroupStmt) Restore(ctx *format.RestoreCtx) error {
  3818  	ctx.WriteKeyWord("SET RESOURCE GROUP ")
  3819  	ctx.WriteName(n.Name.O)
  3820  	return nil
  3821  }
  3822  
  3823  // Accept implements Node Accept interface.
  3824  func (n *SetResourceGroupStmt) Accept(v Visitor) (Node, bool) {
  3825  	newNode, skipChildren := v.Enter(n)
  3826  	if skipChildren {
  3827  		return v.Leave(newNode)
  3828  	}
  3829  	n = newNode.(*SetResourceGroupStmt)
  3830  	return v.Leave(n)
  3831  }
  3832  
  3833  // CalibrateResourceType is the type for CalibrateResource statement.
  3834  type CalibrateResourceType int
  3835  
  3836  // calibrate resource [ workload < TPCC | OLTP_READ_WRITE | OLTP_READ_ONLY | OLTP_WRITE_ONLY | TPCH_10> ]
  3837  const (
  3838  	WorkloadNone CalibrateResourceType = iota
  3839  	TPCC
  3840  	OLTPREADWRITE
  3841  	OLTPREADONLY
  3842  	OLTPWRITEONLY
  3843  	TPCH10
  3844  )
  3845  
  3846  func (n CalibrateResourceType) Restore(ctx *format.RestoreCtx) error {
  3847  	switch n {
  3848  	case TPCC:
  3849  		ctx.WriteKeyWord(" WORKLOAD TPCC")
  3850  	case OLTPREADWRITE:
  3851  		ctx.WriteKeyWord(" WORKLOAD OLTP_READ_WRITE")
  3852  	case OLTPREADONLY:
  3853  		ctx.WriteKeyWord(" WORKLOAD OLTP_READ_ONLY")
  3854  	case OLTPWRITEONLY:
  3855  		ctx.WriteKeyWord(" WORKLOAD OLTP_WRITE_ONLY")
  3856  	case TPCH10:
  3857  		ctx.WriteKeyWord(" WORKLOAD TPCH_10")
  3858  	}
  3859  	return nil
  3860  }
  3861  
  3862  // CalibrateResourceStmt is a statement to fetch the cluster RU capacity
  3863  type CalibrateResourceStmt struct {
  3864  	stmtNode
  3865  	DynamicCalibrateResourceOptionList []*DynamicCalibrateResourceOption
  3866  	Tp                                 CalibrateResourceType
  3867  }
  3868  
  3869  // Restore implements Node interface.
  3870  func (n *CalibrateResourceStmt) Restore(ctx *format.RestoreCtx) error {
  3871  	ctx.WriteKeyWord("CALIBRATE RESOURCE")
  3872  	if err := n.Tp.Restore(ctx); err != nil {
  3873  		return errors.Annotate(err, "An error occurred while restore CalibrateResourceStmt.CalibrateResourceType")
  3874  	}
  3875  	for i, option := range n.DynamicCalibrateResourceOptionList {
  3876  		ctx.WritePlain(" ")
  3877  		if err := option.Restore(ctx); err != nil {
  3878  			return errors.Annotatef(err, "An error occurred while splicing DynamicCalibrateResourceOption: [%v]", i)
  3879  		}
  3880  	}
  3881  	return nil
  3882  }
  3883  
  3884  // Accept implements Node Accept interface.
  3885  func (n *CalibrateResourceStmt) Accept(v Visitor) (Node, bool) {
  3886  	newNode, skipChildren := v.Enter(n)
  3887  	if skipChildren {
  3888  		return v.Leave(newNode)
  3889  	}
  3890  	n = newNode.(*CalibrateResourceStmt)
  3891  	for _, val := range n.DynamicCalibrateResourceOptionList {
  3892  		_, ok := val.Accept(v)
  3893  		if !ok {
  3894  			return n, false
  3895  		}
  3896  	}
  3897  	return v.Leave(n)
  3898  }
  3899  
  3900  type DynamicCalibrateType int
  3901  
  3902  const (
  3903  	// specific time
  3904  	CalibrateStartTime = iota
  3905  	CalibrateEndTime
  3906  	CalibrateDuration
  3907  )
  3908  
  3909  type DynamicCalibrateResourceOption struct {
  3910  	stmtNode
  3911  	Tp       DynamicCalibrateType
  3912  	StrValue string
  3913  	Ts       ExprNode
  3914  	Unit     TimeUnitType
  3915  }
  3916  
  3917  func (n *DynamicCalibrateResourceOption) Restore(ctx *format.RestoreCtx) error {
  3918  	switch n.Tp {
  3919  	case CalibrateStartTime:
  3920  		ctx.WriteKeyWord("START_TIME ")
  3921  		if err := n.Ts.Restore(ctx); err != nil {
  3922  			return errors.Annotate(err, "An error occurred while splicing DynamicCalibrateResourceOption StartTime")
  3923  		}
  3924  	case CalibrateEndTime:
  3925  		ctx.WriteKeyWord("END_TIME ")
  3926  		if err := n.Ts.Restore(ctx); err != nil {
  3927  			return errors.Annotate(err, "An error occurred while splicing DynamicCalibrateResourceOption EndTime")
  3928  		}
  3929  	case CalibrateDuration:
  3930  		ctx.WriteKeyWord("DURATION ")
  3931  		if len(n.StrValue) > 0 {
  3932  			ctx.WriteString(n.StrValue)
  3933  		} else {
  3934  			ctx.WriteKeyWord("INTERVAL ")
  3935  			if err := n.Ts.Restore(ctx); err != nil {
  3936  				return errors.Annotate(err, "An error occurred while restore DynamicCalibrateResourceOption DURATION TS")
  3937  			}
  3938  			ctx.WritePlain(" ")
  3939  			ctx.WriteKeyWord(n.Unit.String())
  3940  		}
  3941  	default:
  3942  		return errors.Errorf("invalid DynamicCalibrateResourceOption: %d", n.Tp)
  3943  	}
  3944  	return nil
  3945  }
  3946  
  3947  // Accept implements Node Accept interface.
  3948  func (n *DynamicCalibrateResourceOption) Accept(v Visitor) (Node, bool) {
  3949  	newNode, skipChildren := v.Enter(n)
  3950  	if skipChildren {
  3951  		return v.Leave(newNode)
  3952  	}
  3953  	n = newNode.(*DynamicCalibrateResourceOption)
  3954  	if n.Ts != nil {
  3955  		node, ok := n.Ts.Accept(v)
  3956  		if !ok {
  3957  			return n, false
  3958  		}
  3959  		n.Ts = node.(ExprNode)
  3960  	}
  3961  	return v.Leave(n)
  3962  }
  3963  
  3964  // DropQueryWatchStmt is a statement to drop a runaway watch item.
  3965  type DropQueryWatchStmt struct {
  3966  	stmtNode
  3967  	IntValue int64
  3968  }
  3969  
  3970  func (n *DropQueryWatchStmt) Restore(ctx *format.RestoreCtx) error {
  3971  	ctx.WriteKeyWord("QUERY WATCH REMOVE ")
  3972  	ctx.WritePlainf("%d", n.IntValue)
  3973  	return nil
  3974  }
  3975  
  3976  // Accept implements Node Accept interface.
  3977  func (n *DropQueryWatchStmt) Accept(v Visitor) (Node, bool) {
  3978  	newNode, _ := v.Enter(n)
  3979  	n = newNode.(*DropQueryWatchStmt)
  3980  	return v.Leave(n)
  3981  }
  3982  
  3983  // AddQueryWatchStmt is a statement to add a runaway watch item.
  3984  type AddQueryWatchStmt struct {
  3985  	stmtNode
  3986  	QueryWatchOptionList []*QueryWatchOption
  3987  }
  3988  
  3989  func (n *AddQueryWatchStmt) Restore(ctx *format.RestoreCtx) error {
  3990  	ctx.WriteKeyWord("QUERY WATCH ADD")
  3991  	for i, option := range n.QueryWatchOptionList {
  3992  		ctx.WritePlain(" ")
  3993  		if err := option.Restore(ctx); err != nil {
  3994  			return errors.Annotatef(err, "An error occurred while splicing QueryWatchOptionList: [%v]", i)
  3995  		}
  3996  	}
  3997  	return nil
  3998  }
  3999  
  4000  // Accept implements Node Accept interface.
  4001  func (n *AddQueryWatchStmt) Accept(v Visitor) (Node, bool) {
  4002  	newNode, _ := v.Enter(n)
  4003  	n = newNode.(*AddQueryWatchStmt)
  4004  	for _, val := range n.QueryWatchOptionList {
  4005  		_, ok := val.Accept(v)
  4006  		if !ok {
  4007  			return n, false
  4008  		}
  4009  	}
  4010  	return v.Leave(n)
  4011  }
  4012  
  4013  type QueryWatchOptionType int
  4014  
  4015  const (
  4016  	QueryWatchResourceGroup QueryWatchOptionType = iota
  4017  	QueryWatchAction
  4018  	QueryWatchType
  4019  )
  4020  
  4021  // QueryWatchOption is used for parsing manual management of watching runaway queries option.
  4022  type QueryWatchOption struct {
  4023  	stmtNode
  4024  	Tp        QueryWatchOptionType
  4025  	StrValue  model.CIStr
  4026  	IntValue  int32
  4027  	ExprValue ExprNode
  4028  	BoolValue bool
  4029  }
  4030  
  4031  func (n *QueryWatchOption) Restore(ctx *format.RestoreCtx) error {
  4032  	switch n.Tp {
  4033  	case QueryWatchResourceGroup:
  4034  		ctx.WriteKeyWord("RESOURCE GROUP ")
  4035  		if n.ExprValue != nil {
  4036  			if err := n.ExprValue.Restore(ctx); err != nil {
  4037  				return errors.Annotatef(err, "An error occurred while splicing ExprValue: [%v]", n.ExprValue)
  4038  			}
  4039  		} else {
  4040  			ctx.WriteName(n.StrValue.O)
  4041  		}
  4042  	case QueryWatchAction:
  4043  		ctx.WriteKeyWord("ACTION ")
  4044  		ctx.WritePlain("= ")
  4045  		ctx.WriteKeyWord(model.RunawayActionType(n.IntValue).String())
  4046  	case QueryWatchType:
  4047  		if n.BoolValue {
  4048  			ctx.WriteKeyWord("SQL TEXT ")
  4049  			ctx.WriteKeyWord(model.RunawayWatchType(n.IntValue).String())
  4050  			ctx.WriteKeyWord(" TO ")
  4051  		} else {
  4052  			switch n.IntValue {
  4053  			case int32(model.WatchSimilar):
  4054  				ctx.WriteKeyWord("SQL DIGEST ")
  4055  			case int32(model.WatchPlan):
  4056  				ctx.WriteKeyWord("PLAN DIGEST ")
  4057  			}
  4058  		}
  4059  		if err := n.ExprValue.Restore(ctx); err != nil {
  4060  			return errors.Annotatef(err, "An error occurred while splicing ExprValue: [%v]", n.ExprValue)
  4061  		}
  4062  	}
  4063  	return nil
  4064  }
  4065  
  4066  // Accept implements Node Accept interface.
  4067  func (n *QueryWatchOption) Accept(v Visitor) (Node, bool) {
  4068  	newNode, skipChildren := v.Enter(n)
  4069  	if skipChildren {
  4070  		return v.Leave(newNode)
  4071  	}
  4072  	n = newNode.(*QueryWatchOption)
  4073  	if n.ExprValue != nil {
  4074  		node, ok := n.ExprValue.Accept(v)
  4075  		if !ok {
  4076  			return n, false
  4077  		}
  4078  		n.ExprValue = node.(ExprNode)
  4079  	}
  4080  	return v.Leave(n)
  4081  }
  4082  
  4083  func CheckQueryWatchAppend(ops []*QueryWatchOption, newOp *QueryWatchOption) bool {
  4084  	for _, op := range ops {
  4085  		if op.Tp == newOp.Tp {
  4086  			return false
  4087  		}
  4088  	}
  4089  	return true
  4090  }