Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
891 lines
18 KiB
891 lines
18 KiB
// 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" |
|
) |
|
|
|
var ( |
|
_ DMLNode = &DeleteStmt{} |
|
_ DMLNode = &InsertStmt{} |
|
_ DMLNode = &UnionStmt{} |
|
_ DMLNode = &UpdateStmt{} |
|
_ DMLNode = &SelectStmt{} |
|
_ DMLNode = &ShowStmt{} |
|
|
|
_ 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 |
|
} |
|
|
|
// 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 |
|
} |
|
|
|
// 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 represetns 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) |
|
} |
|
|
|
// SetResultFields implements ResultSetNode interface. |
|
func (n *TableSource) SetResultFields(rfs []*ResultField) { |
|
n.Source.SetResultFields(rfs) |
|
} |
|
|
|
// GetResultFields implements ResultSetNode interface. |
|
func (n *TableSource) GetResultFields() []*ResultField { |
|
return n.Source.GetResultFields() |
|
} |
|
|
|
// SelectLockType is the lock type for SelectStmt. |
|
type SelectLockType int |
|
|
|
// Select lock types. |
|
const ( |
|
SelectLockNone SelectLockType = iota |
|
SelectLockForUpdate |
|
SelectLockInShareMode |
|
) |
|
|
|
// 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 |
|
// If WildCard is not nil, Expr will be nil. |
|
WildCard *WildCardField |
|
// If Expr is not nil, WildCard will be nil. |
|
Expr ExprNode |
|
// Alias name for Expr. |
|
AsName model.CIStr |
|
} |
|
|
|
// 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 |
|
|
|
// Distinct represents if 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 |
|
// Lock is the lock type |
|
LockTp SelectLockType |
|
} |
|
|
|
// 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.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 |
|
|
|
Distinct bool |
|
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) |
|
} |
|
|
|
// Priority const values. |
|
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html |
|
const ( |
|
NoPriority = iota |
|
LowPriority |
|
HighPriority |
|
DelayedPriority |
|
) |
|
|
|
// 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 |
|
Table *TableRefsClause |
|
Columns []*ColumnName |
|
Lists [][]ExprNode |
|
Setlist []*Assignment |
|
Priority int |
|
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 |
|
|
|
// Used in both single table and multiple table delete statement. |
|
TableRefs *TableRefsClause |
|
// Only used in multiple table delete statement. |
|
Tables *DeleteTableList |
|
Where ExprNode |
|
Order *OrderByClause |
|
Limit *Limit |
|
LowPriority bool |
|
Ignore bool |
|
Quick bool |
|
IsMultiTable bool |
|
BeforeFrom bool |
|
} |
|
|
|
// 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 |
|
LowPriority bool |
|
Ignore bool |
|
MultipleTable bool |
|
} |
|
|
|
// 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 |
|
|
|
Offset uint64 |
|
Count uint64 |
|
} |
|
|
|
// Accept implements Node Accept interface. |
|
func (n *Limit) Accept(v Visitor) (Node, bool) { |
|
newNode, skipChildren := v.Enter(n) |
|
if skipChildren { |
|
return v.Leave(newNode) |
|
} |
|
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 |
|
) |
|
|
|
// 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 string // Used for show grants. |
|
|
|
// 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) |
|
} |
|
if n.Where != nil { |
|
node, ok := n.Where.Accept(v) |
|
if !ok { |
|
return n, false |
|
} |
|
n.Where = node.(ExprNode) |
|
} |
|
return v.Leave(n) |
|
}
|
|
|