github.com/pingcap/tidb/parser@v0.0.0-20231013125129-93a834a6bf8d/ast/ast.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 is the abstract syntax tree parsed from a SQL statement by parser.
    15  // It can be analysed and transformed by optimizer.
    16  package ast
    17  
    18  import (
    19  	"io"
    20  
    21  	"github.com/pingcap/tidb/parser/charset"
    22  	"github.com/pingcap/tidb/parser/format"
    23  	"github.com/pingcap/tidb/parser/model"
    24  	"github.com/pingcap/tidb/parser/types"
    25  )
    26  
    27  // Node is the basic element of the AST.
    28  // Interfaces embed Node should have 'Node' name suffix.
    29  type Node interface {
    30  	// Restore returns the sql text from ast tree
    31  	Restore(ctx *format.RestoreCtx) error
    32  	// Accept accepts Visitor to visit itself.
    33  	// The returned node should replace original node.
    34  	// ok returns false to stop visiting.
    35  	//
    36  	// Implementation of this method should first call visitor.Enter,
    37  	// assign the returned node to its method receiver, if skipChildren returns true,
    38  	// children should be skipped. Otherwise, call its children in particular order that
    39  	// later elements depends on former elements. Finally, return visitor.Leave.
    40  	Accept(v Visitor) (node Node, ok bool)
    41  	// Text returns the utf8 encoding text of the element.
    42  	Text() string
    43  	// OriginalText returns the original text of the element.
    44  	OriginalText() string
    45  	// SetText sets original text to the Node.
    46  	SetText(enc charset.Encoding, text string)
    47  	// SetOriginTextPosition set the start offset of this node in the origin text.
    48  	SetOriginTextPosition(offset int)
    49  	// OriginTextPosition get the start offset of this node in the origin text.
    50  	OriginTextPosition() int
    51  }
    52  
    53  // Flags indicates whether an expression contains certain types of expression.
    54  const (
    55  	FlagConstant       uint64 = 0
    56  	FlagHasParamMarker uint64 = 1 << iota
    57  	FlagHasFunc
    58  	FlagHasReference
    59  	FlagHasAggregateFunc
    60  	FlagHasSubquery
    61  	FlagHasVariable
    62  	FlagHasDefault
    63  	FlagPreEvaluated
    64  	FlagHasWindowFunc
    65  )
    66  
    67  // ExprNode is a node that can be evaluated.
    68  // Name of implementations should have 'Expr' suffix.
    69  type ExprNode interface {
    70  	// Node is embedded in ExprNode.
    71  	Node
    72  	// SetType sets evaluation type to the expression.
    73  	SetType(tp *types.FieldType)
    74  	// GetType gets the evaluation type of the expression.
    75  	GetType() *types.FieldType
    76  	// SetFlag sets flag to the expression.
    77  	// Flag indicates whether the expression contains
    78  	// parameter marker, reference, aggregate function...
    79  	SetFlag(flag uint64)
    80  	// GetFlag returns the flag of the expression.
    81  	GetFlag() uint64
    82  
    83  	// Format formats the AST into a writer.
    84  	Format(w io.Writer)
    85  }
    86  
    87  // OptBinary is used for parser.
    88  type OptBinary struct {
    89  	IsBinary bool
    90  	Charset  string
    91  }
    92  
    93  // FuncNode represents function call expression node.
    94  type FuncNode interface {
    95  	ExprNode
    96  	functionExpression()
    97  }
    98  
    99  // StmtNode represents statement node.
   100  // Name of implementations should have 'Stmt' suffix.
   101  type StmtNode interface {
   102  	Node
   103  	statement()
   104  }
   105  
   106  // DDLNode represents DDL statement node.
   107  type DDLNode interface {
   108  	StmtNode
   109  	ddlStatement()
   110  }
   111  
   112  // DMLNode represents DML statement node.
   113  type DMLNode interface {
   114  	StmtNode
   115  	dmlStatement()
   116  }
   117  
   118  // ResultField represents a result field which can be a column from a table,
   119  // or an expression in select field. It is a generated property during
   120  // binding process. ResultField is the key element to evaluate a ColumnNameExpr.
   121  // After resolving process, every ColumnNameExpr will be resolved to a ResultField.
   122  // During execution, every row retrieved from table will set the row value to
   123  // ResultFields of that table, so ColumnNameExpr resolved to that ResultField can be
   124  // easily evaluated.
   125  type ResultField struct {
   126  	Column       *model.ColumnInfo
   127  	ColumnAsName model.CIStr
   128  	// EmptyOrgName indicates whether this field has an empty org_name. A field has an empty org name, if it's an
   129  	// expression. It's not sure whether it's safe to use empty string in `.Column.Name`, so a new field is added to
   130  	// indicate whether it's empty.
   131  	EmptyOrgName bool
   132  
   133  	Table       *model.TableInfo
   134  	TableAsName model.CIStr
   135  	DBName      model.CIStr
   136  }
   137  
   138  // ResultSetNode interface has a ResultFields property, represents a Node that returns result set.
   139  // Implementations include SelectStmt, SubqueryExpr, TableSource, TableName, Join and SetOprStmt.
   140  type ResultSetNode interface {
   141  	Node
   142  
   143  	resultSet()
   144  }
   145  
   146  // SensitiveStmtNode overloads StmtNode and provides a SecureText method.
   147  type SensitiveStmtNode interface {
   148  	StmtNode
   149  	// SecureText is different from Text that it hide password information.
   150  	SecureText() string
   151  }
   152  
   153  // Visitor visits a Node.
   154  type Visitor interface {
   155  	// Enter is called before children nodes are visited.
   156  	// The returned node must be the same type as the input node n.
   157  	// skipChildren returns true means children nodes should be skipped,
   158  	// this is useful when work is done in Enter and there is no need to visit children.
   159  	Enter(n Node) (node Node, skipChildren bool)
   160  	// Leave is called after children nodes have been visited.
   161  	// The returned node's type can be different from the input node if it is a ExprNode,
   162  	// Non-expression node must be the same type as the input node n.
   163  	// ok returns false to stop visiting.
   164  	Leave(n Node) (node Node, ok bool)
   165  }
   166  
   167  // GetStmtLabel generates a label for a statement.
   168  func GetStmtLabel(stmtNode StmtNode) string {
   169  	switch x := stmtNode.(type) {
   170  	case *AlterTableStmt:
   171  		return "AlterTable"
   172  	case *AnalyzeTableStmt:
   173  		return "AnalyzeTable"
   174  	case *BeginStmt:
   175  		return "Begin"
   176  	case *ChangeStmt:
   177  		return "Change"
   178  	case *CommitStmt:
   179  		return "Commit"
   180  	case *CompactTableStmt:
   181  		return "CompactTable"
   182  	case *CreateDatabaseStmt:
   183  		return "CreateDatabase"
   184  	case *CreateIndexStmt:
   185  		return "CreateIndex"
   186  	case *CreateTableStmt:
   187  		return "CreateTable"
   188  	case *CreateViewStmt:
   189  		return "CreateView"
   190  	case *CreateUserStmt:
   191  		return "CreateUser"
   192  	case *DeleteStmt:
   193  		return "Delete"
   194  	case *DropDatabaseStmt:
   195  		return "DropDatabase"
   196  	case *DropIndexStmt:
   197  		return "DropIndex"
   198  	case *DropTableStmt:
   199  		if x.IsView {
   200  			return "DropView"
   201  		}
   202  		return "DropTable"
   203  	case *ExplainStmt:
   204  		if _, ok := x.Stmt.(*ShowStmt); ok {
   205  			return "DescTable"
   206  		}
   207  		if x.Analyze {
   208  			return "ExplainAnalyzeSQL"
   209  		}
   210  		return "ExplainSQL"
   211  	case *InsertStmt:
   212  		if x.IsReplace {
   213  			return "Replace"
   214  		}
   215  		return "Insert"
   216  	case *ImportIntoStmt:
   217  		return "ImportInto"
   218  	case *LoadDataStmt:
   219  		return "LoadData"
   220  	case *RollbackStmt:
   221  		return "Rollback"
   222  	case *SelectStmt:
   223  		return "Select"
   224  	case *SetStmt, *SetPwdStmt:
   225  		return "Set"
   226  	case *ShowStmt:
   227  		return "Show"
   228  	case *TruncateTableStmt:
   229  		return "TruncateTable"
   230  	case *UpdateStmt:
   231  		return "Update"
   232  	case *GrantStmt:
   233  		return "Grant"
   234  	case *RevokeStmt:
   235  		return "Revoke"
   236  	case *DeallocateStmt:
   237  		return "Deallocate"
   238  	case *ExecuteStmt:
   239  		return "Execute"
   240  	case *PrepareStmt:
   241  		return "Prepare"
   242  	case *UseStmt:
   243  		return "Use"
   244  	case *CreateBindingStmt:
   245  		return "CreateBinding"
   246  	case *IndexAdviseStmt:
   247  		return "IndexAdvise"
   248  	case *DropBindingStmt:
   249  		return "DropBinding"
   250  	case *TraceStmt:
   251  		return "Trace"
   252  	case *ShutdownStmt:
   253  		return "Shutdown"
   254  	case *SavepointStmt:
   255  		return "Savepoint"
   256  	}
   257  	return "other"
   258  }