Fetch the repository succeeded.
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package ast
import (
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/util/auth"
)
var (
_ DMLNode = &DeleteStmt{}
_ DMLNode = &InsertStmt{}
_ DMLNode = &UnionStmt{}
_ DMLNode = &UpdateStmt{}
_ DMLNode = &SelectStmt{}
_ DMLNode = &ShowStmt{}
_ DMLNode = &LoadDataStmt{}
_ Node = &Assignment{}
_ Node = &ByItem{}
_ Node = &FieldList{}
_ Node = &GroupByClause{}
_ Node = &HavingClause{}
_ Node = &Join{}
_ Node = &Limit{}
_ Node = &OnCondition{}
_ Node = &OrderByClause{}
_ Node = &SelectField{}
_ Node = &TableName{}
_ Node = &TableRefsClause{}
_ Node = &TableSource{}
_ Node = &UnionSelectList{}
_ Node = &WildCardField{}
)
// JoinType is join type, including cross/left/right/full.
type JoinType int
const (
// CrossJoin is cross join type.
CrossJoin JoinType = iota + 1
// LeftJoin is left Join type.
LeftJoin
// RightJoin is right Join type.
RightJoin
)
// Join represents table join.
type Join struct {
node
resultSetNode
// Left table can be TableSource or JoinNode.
Left ResultSetNode
// Right table can be TableSource or JoinNode or nil.
Right ResultSetNode
// Tp represents join type.
Tp JoinType
// On represents join on condition.
On *OnCondition
// Using represents join using clause.
Using []*ColumnName
// NaturalJoin represents join is natural join.
NaturalJoin bool
// StraightJoin represents a straight join.
StraightJoin bool
}
// Accept implements Node Accept interface.
func (n *Join) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*Join)
node, ok := n.Left.Accept(v)
if !ok {
return n, false
}
n.Left = node.(ResultSetNode)
if n.Right != nil {
node, ok = n.Right.Accept(v)
if !ok {
return n, false
}
n.Right = node.(ResultSetNode)
}
if n.On != nil {
node, ok = n.On.Accept(v)
if !ok {
return n, false
}
n.On = node.(*OnCondition)
}
return v.Leave(n)
}
// TableName represents a table name.
type TableName struct {
node
resultSetNode
Schema model.CIStr
Name model.CIStr
DBInfo *model.DBInfo
TableInfo *model.TableInfo
IndexHints []*IndexHint
}
// IndexHintType is the type for index hint use, ignore or force.
type IndexHintType int
// IndexHintUseType values.
const (
HintUse IndexHintType = 1
HintIgnore IndexHintType = 2
HintForce IndexHintType = 3
)
// IndexHintScope is the type for index hint for join, order by or group by.
type IndexHintScope int
// Index hint scopes.
const (
HintForScan IndexHintScope = 1
HintForJoin IndexHintScope = 2
HintForOrderBy IndexHintScope = 3
HintForGroupBy IndexHintScope = 4
)
// IndexHint represents a hint for optimizer to use/ignore/force for join/order by/group by.
type IndexHint struct {
IndexNames []model.CIStr
HintType IndexHintType
HintScope IndexHintScope
}
// Accept implements Node Accept interface.
func (n *TableName) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TableName)
return v.Leave(n)
}
// DeleteTableList is the tablelist used in delete statement multi-table mode.
type DeleteTableList struct {
node
Tables []*TableName
}
// Accept implements Node Accept interface.
func (n *DeleteTableList) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DeleteTableList)
if n != nil {
for i, t := range n.Tables {
node, ok := t.Accept(v)
if !ok {
return n, false
}
n.Tables[i] = node.(*TableName)
}
}
return v.Leave(n)
}
// OnCondition represents JOIN on condition.
type OnCondition struct {
node
Expr ExprNode
}
// Accept implements Node Accept interface.
func (n *OnCondition) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*OnCondition)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// TableSource represents table source with a name.
type TableSource struct {
node
// Source is the source of the data, can be a TableName,
// a SelectStmt, a UnionStmt, or a JoinNode.
Source ResultSetNode
// AsName is the alias name of the table source.
AsName model.CIStr
}
// Accept implements Node Accept interface.
func (n *TableSource) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TableSource)
node, ok := n.Source.Accept(v)
if !ok {
return n, false
}
n.Source = node.(ResultSetNode)
return v.Leave(n)
}
// SelectLockType is the lock type for SelectStmt.
type SelectLockType int
// Select lock types.
const (
SelectLockNone SelectLockType = iota
SelectLockForUpdate
SelectLockInShareMode
)
// String implements fmt.Stringer.
func (slt SelectLockType) String() string {
switch slt {
case SelectLockNone:
return "none"
case SelectLockForUpdate:
return "for update"
case SelectLockInShareMode:
return "in share mode"
}
return "unsupported select lock type"
}
// WildCardField is a special type of select field content.
type WildCardField struct {
node
Table model.CIStr
Schema model.CIStr
}
// Accept implements Node Accept interface.
func (n *WildCardField) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*WildCardField)
return v.Leave(n)
}
// SelectField represents fields in select statement.
// There are two type of select field: wildcard
// and expression with optional alias name.
type SelectField struct {
node
// Offset is used to get original text.
Offset int
// WildCard is not nil, Expr will be nil.
WildCard *WildCardField
// Expr is not nil, WildCard will be nil.
Expr ExprNode
// AsName is alias name for Expr.
AsName model.CIStr
// Auxiliary stands for if this field is auxiliary.
// When we add a Field into SelectField list which is used for having/orderby clause but the field is not in select clause,
// we should set its Auxiliary to true. Then the TrimExec will trim the field.
Auxiliary bool
}
// Accept implements Node Accept interface.
func (n *SelectField) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SelectField)
if n.Expr != nil {
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
}
return v.Leave(n)
}
// FieldList represents field list in select statement.
type FieldList struct {
node
Fields []*SelectField
}
// Accept implements Node Accept interface.
func (n *FieldList) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*FieldList)
for i, val := range n.Fields {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Fields[i] = node.(*SelectField)
}
return v.Leave(n)
}
// TableRefsClause represents table references clause in dml statement.
type TableRefsClause struct {
node
TableRefs *Join
}
// Accept implements Node Accept interface.
func (n *TableRefsClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TableRefsClause)
node, ok := n.TableRefs.Accept(v)
if !ok {
return n, false
}
n.TableRefs = node.(*Join)
return v.Leave(n)
}
// ByItem represents an item in order by or group by.
type ByItem struct {
node
Expr ExprNode
Desc bool
}
// Accept implements Node Accept interface.
func (n *ByItem) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ByItem)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// GroupByClause represents group by clause.
type GroupByClause struct {
node
Items []*ByItem
}
// Accept implements Node Accept interface.
func (n *GroupByClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*GroupByClause)
for i, val := range n.Items {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Items[i] = node.(*ByItem)
}
return v.Leave(n)
}
// HavingClause represents having clause.
type HavingClause struct {
node
Expr ExprNode
}
// Accept implements Node Accept interface.
func (n *HavingClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*HavingClause)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// OrderByClause represents order by clause.
type OrderByClause struct {
node
Items []*ByItem
ForUnion bool
}
// Accept implements Node Accept interface.
func (n *OrderByClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*OrderByClause)
for i, val := range n.Items {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Items[i] = node.(*ByItem)
}
return v.Leave(n)
}
// SelectStmt represents the select query node.
// See https://dev.mysql.com/doc/refman/5.7/en/select.html
type SelectStmt struct {
dmlNode
resultSetNode
// SelectStmtOpts wraps around select hints and switches.
*SelectStmtOpts
// Distinct represents whether the select has distinct option.
Distinct bool
// From is the from clause of the query.
From *TableRefsClause
// Where is the where clause in select statement.
Where ExprNode
// Fields is the select expression list.
Fields *FieldList
// GroupBy is the group by expression list.
GroupBy *GroupByClause
// Having is the having condition.
Having *HavingClause
// OrderBy is the ordering expression list.
OrderBy *OrderByClause
// Limit is the limit clause.
Limit *Limit
// LockTp is the lock type
LockTp SelectLockType
// TableHints represents the table level Optimizer Hint for join type
TableHints []*TableOptimizerHint
// IsAfterUnionDistinct indicates whether it's a stmt after "union distinct".
IsAfterUnionDistinct bool
// IsInBraces indicates whether it's a stmt in brace.
IsInBraces bool
}
// Accept implements Node Accept interface.
func (n *SelectStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SelectStmt)
if n.TableHints != nil && len(n.TableHints) != 0 {
newHints := make([]*TableOptimizerHint, len(n.TableHints))
for i, hint := range n.TableHints {
node, ok := hint.Accept(v)
if !ok {
return n, false
}
newHints[i] = node.(*TableOptimizerHint)
}
n.TableHints = newHints
}
if n.From != nil {
node, ok := n.From.Accept(v)
if !ok {
return n, false
}
n.From = node.(*TableRefsClause)
}
if n.Where != nil {
node, ok := n.Where.Accept(v)
if !ok {
return n, false
}
n.Where = node.(ExprNode)
}
if n.Fields != nil {
node, ok := n.Fields.Accept(v)
if !ok {
return n, false
}
n.Fields = node.(*FieldList)
}
if n.GroupBy != nil {
node, ok := n.GroupBy.Accept(v)
if !ok {
return n, false
}
n.GroupBy = node.(*GroupByClause)
}
if n.Having != nil {
node, ok := n.Having.Accept(v)
if !ok {
return n, false
}
n.Having = node.(*HavingClause)
}
if n.OrderBy != nil {
node, ok := n.OrderBy.Accept(v)
if !ok {
return n, false
}
n.OrderBy = node.(*OrderByClause)
}
if n.Limit != nil {
node, ok := n.Limit.Accept(v)
if !ok {
return n, false
}
n.Limit = node.(*Limit)
}
return v.Leave(n)
}
// UnionSelectList represents the select list in a union statement.
type UnionSelectList struct {
node
Selects []*SelectStmt
}
// Accept implements Node Accept interface.
func (n *UnionSelectList) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*UnionSelectList)
for i, sel := range n.Selects {
node, ok := sel.Accept(v)
if !ok {
return n, false
}
n.Selects[i] = node.(*SelectStmt)
}
return v.Leave(n)
}
// UnionStmt represents "union statement"
// See https://dev.mysql.com/doc/refman/5.7/en/union.html
type UnionStmt struct {
dmlNode
resultSetNode
SelectList *UnionSelectList
OrderBy *OrderByClause
Limit *Limit
}
// Accept implements Node Accept interface.
func (n *UnionStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*UnionStmt)
if n.SelectList != nil {
node, ok := n.SelectList.Accept(v)
if !ok {
return n, false
}
n.SelectList = node.(*UnionSelectList)
}
if n.OrderBy != nil {
node, ok := n.OrderBy.Accept(v)
if !ok {
return n, false
}
n.OrderBy = node.(*OrderByClause)
}
if n.Limit != nil {
node, ok := n.Limit.Accept(v)
if !ok {
return n, false
}
n.Limit = node.(*Limit)
}
return v.Leave(n)
}
// Assignment is the expression for assignment, like a = 1.
type Assignment struct {
node
// Column is the column name to be assigned.
Column *ColumnName
// Expr is the expression assigning to ColName.
Expr ExprNode
}
// Accept implements Node Accept interface.
func (n *Assignment) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*Assignment)
node, ok := n.Column.Accept(v)
if !ok {
return n, false
}
n.Column = node.(*ColumnName)
node, ok = n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// LoadDataStmt is a statement to load data from a specified file, then insert this rows into an existing table.
// See https://dev.mysql.com/doc/refman/5.7/en/load-data.html
type LoadDataStmt struct {
dmlNode
IsLocal bool
Path string
Table *TableName
Columns []*ColumnName
FieldsInfo *FieldsClause
LinesInfo *LinesClause
}
// Accept implements Node Accept interface.
func (n *LoadDataStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*LoadDataStmt)
if n.Table != nil {
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
}
for i, val := range n.Columns {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Columns[i] = node.(*ColumnName)
}
return v.Leave(n)
}
// FieldsClause represents fields references clause in load data statement.
type FieldsClause struct {
Terminated string
Enclosed byte
Escaped byte
}
// LinesClause represents lines references clause in load data statement.
type LinesClause struct {
Starting string
Terminated string
}
// InsertStmt is a statement to insert new rows into an existing table.
// See https://dev.mysql.com/doc/refman/5.7/en/insert.html
type InsertStmt struct {
dmlNode
IsReplace bool
IgnoreErr bool
Table *TableRefsClause
Columns []*ColumnName
Lists [][]ExprNode
Setlist []*Assignment
Priority mysql.PriorityEnum
OnDuplicate []*Assignment
Select ResultSetNode
}
// Accept implements Node Accept interface.
func (n *InsertStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*InsertStmt)
if n.Select != nil {
node, ok := n.Select.Accept(v)
if !ok {
return n, false
}
n.Select = node.(ResultSetNode)
}
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableRefsClause)
for i, val := range n.Columns {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Columns[i] = node.(*ColumnName)
}
for i, list := range n.Lists {
for j, val := range list {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Lists[i][j] = node.(ExprNode)
}
}
for i, val := range n.Setlist {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Setlist[i] = node.(*Assignment)
}
for i, val := range n.OnDuplicate {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.OnDuplicate[i] = node.(*Assignment)
}
return v.Leave(n)
}
// DeleteStmt is a statement to delete rows from table.
// See https://dev.mysql.com/doc/refman/5.7/en/delete.html
type DeleteStmt struct {
dmlNode
// TableRefs is used in both single table and multiple table delete statement.
TableRefs *TableRefsClause
// Tables is only used in multiple table delete statement.
Tables *DeleteTableList
Where ExprNode
Order *OrderByClause
Limit *Limit
Priority mysql.PriorityEnum
IgnoreErr bool
Quick bool
IsMultiTable bool
BeforeFrom bool
// TableHints represents the table level Optimizer Hint for join type.
TableHints []*TableOptimizerHint
}
// Accept implements Node Accept interface.
func (n *DeleteStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DeleteStmt)
node, ok := n.TableRefs.Accept(v)
if !ok {
return n, false
}
n.TableRefs = node.(*TableRefsClause)
node, ok = n.Tables.Accept(v)
if !ok {
return n, false
}
n.Tables = node.(*DeleteTableList)
if n.Where != nil {
node, ok = n.Where.Accept(v)
if !ok {
return n, false
}
n.Where = node.(ExprNode)
}
if n.Order != nil {
node, ok = n.Order.Accept(v)
if !ok {
return n, false
}
n.Order = node.(*OrderByClause)
}
if n.Limit != nil {
node, ok = n.Limit.Accept(v)
if !ok {
return n, false
}
n.Limit = node.(*Limit)
}
return v.Leave(n)
}
// UpdateStmt is a statement to update columns of existing rows in tables with new values.
// See https://dev.mysql.com/doc/refman/5.7/en/update.html
type UpdateStmt struct {
dmlNode
TableRefs *TableRefsClause
List []*Assignment
Where ExprNode
Order *OrderByClause
Limit *Limit
Priority mysql.PriorityEnum
IgnoreErr bool
MultipleTable bool
TableHints []*TableOptimizerHint
}
// Accept implements Node Accept interface.
func (n *UpdateStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*UpdateStmt)
node, ok := n.TableRefs.Accept(v)
if !ok {
return n, false
}
n.TableRefs = node.(*TableRefsClause)
for i, val := range n.List {
node, ok = val.Accept(v)
if !ok {
return n, false
}
n.List[i] = node.(*Assignment)
}
if n.Where != nil {
node, ok = n.Where.Accept(v)
if !ok {
return n, false
}
n.Where = node.(ExprNode)
}
if n.Order != nil {
node, ok = n.Order.Accept(v)
if !ok {
return n, false
}
n.Order = node.(*OrderByClause)
}
if n.Limit != nil {
node, ok = n.Limit.Accept(v)
if !ok {
return n, false
}
n.Limit = node.(*Limit)
}
return v.Leave(n)
}
// Limit is the limit clause.
type Limit struct {
node
Count ExprNode
Offset ExprNode
}
// Accept implements Node Accept interface.
func (n *Limit) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
if n.Count != nil {
node, ok := n.Count.Accept(v)
if !ok {
return n, false
}
n.Count = node.(ExprNode)
}
if n.Offset != nil {
node, ok := n.Offset.Accept(v)
if !ok {
return n, false
}
n.Offset = node.(ExprNode)
}
n = newNode.(*Limit)
return v.Leave(n)
}
// ShowStmtType is the type for SHOW statement.
type ShowStmtType int
// Show statement types.
const (
ShowNone = iota
ShowEngines
ShowDatabases
ShowTables
ShowTableStatus
ShowColumns
ShowWarnings
ShowCharset
ShowVariables
ShowStatus
ShowCollation
ShowCreateTable
ShowGrants
ShowTriggers
ShowProcedureStatus
ShowIndex
ShowProcessList
ShowCreateDatabase
ShowEvents
ShowStatsMeta
ShowStatsHistograms
ShowStatsBuckets
ShowStatsHealthy
ShowPlugins
ShowProfiles
ShowMasterStatus
ShowPrivileges
ShowErrors
)
// ShowStmt is a statement to provide information about databases, tables, columns and so on.
// See https://dev.mysql.com/doc/refman/5.7/en/show.html
type ShowStmt struct {
dmlNode
resultSetNode
Tp ShowStmtType // Databases/Tables/Columns/....
DBName string
Table *TableName // Used for showing columns.
Column *ColumnName // Used for `desc table column`.
Flag int // Some flag parsed from sql, such as FULL.
Full bool
User *auth.UserIdentity // Used for show grants.
// GlobalScope is used by show variables
GlobalScope bool
Pattern *PatternLikeExpr
Where ExprNode
}
// Accept implements Node Accept interface.
func (n *ShowStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ShowStmt)
if n.Table != nil {
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
}
if n.Column != nil {
node, ok := n.Column.Accept(v)
if !ok {
return n, false
}
n.Column = node.(*ColumnName)
}
if n.Pattern != nil {
node, ok := n.Pattern.Accept(v)
if !ok {
return n, false
}
n.Pattern = node.(*PatternLikeExpr)
}
switch n.Tp {
case ShowTriggers, ShowProcedureStatus, ShowProcessList, ShowEvents:
// We don't have any data to return for those types,
// but visiting Where may cause resolving error, so return here to avoid error.
return v.Leave(n)
}
if n.Where != nil {
node, ok := n.Where.Accept(v)
if !ok {
return n, false
}
n.Where = node.(ExprNode)
}
return v.Leave(n)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。