|
- // 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 (
- "fmt"
-
- "github.com/pingcap/tidb/context"
- "github.com/pingcap/tidb/model"
- "github.com/pingcap/tidb/mysql"
- "github.com/pingcap/tidb/sessionctx/db"
- )
-
- var (
- _ StmtNode = &AdminStmt{}
- _ StmtNode = &BeginStmt{}
- _ StmtNode = &CommitStmt{}
- _ StmtNode = &CreateUserStmt{}
- _ StmtNode = &DeallocateStmt{}
- _ StmtNode = &DoStmt{}
- _ StmtNode = &ExecuteStmt{}
- _ StmtNode = &ExplainStmt{}
- _ StmtNode = &GrantStmt{}
- _ StmtNode = &PrepareStmt{}
- _ StmtNode = &RollbackStmt{}
- _ StmtNode = &SetCharsetStmt{}
- _ StmtNode = &SetPwdStmt{}
- _ StmtNode = &SetStmt{}
- _ StmtNode = &UseStmt{}
-
- _ Node = &PrivElem{}
- _ Node = &VariableAssignment{}
- )
-
- // TypeOpt is used for parsing data type option from SQL.
- type TypeOpt struct {
- IsUnsigned bool
- IsZerofill bool
- }
-
- // FloatOpt is used for parsing floating-point type option from SQL.
- // See: http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html
- type FloatOpt struct {
- Flen int
- Decimal int
- }
-
- // AuthOption is used for parsing create use statement.
- type AuthOption struct {
- // AuthString/HashString can be empty, so we need to decide which one to use.
- ByAuthString bool
- AuthString string
- HashString string
- // TODO: support auth_plugin
- }
-
- // ExplainStmt is a statement to provide information about how is SQL statement executed
- // or get columns information in a table.
- // See: https://dev.mysql.com/doc/refman/5.7/en/explain.html
- type ExplainStmt struct {
- stmtNode
-
- Stmt StmtNode
- }
-
- // Accept implements Node Accept interface.
- func (n *ExplainStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ExplainStmt)
- node, ok := n.Stmt.Accept(v)
- if !ok {
- return n, false
- }
- n.Stmt = node.(DMLNode)
- return v.Leave(n)
- }
-
- // PrepareStmt is a statement to prepares a SQL statement which contains placeholders,
- // and it is executed with ExecuteStmt and released with DeallocateStmt.
- // See: https://dev.mysql.com/doc/refman/5.7/en/prepare.html
- type PrepareStmt struct {
- stmtNode
-
- Name string
- SQLText string
- SQLVar *VariableExpr
- }
-
- // Accept implements Node Accept interface.
- func (n *PrepareStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PrepareStmt)
- if n.SQLVar != nil {
- node, ok := n.SQLVar.Accept(v)
- if !ok {
- return n, false
- }
- n.SQLVar = node.(*VariableExpr)
- }
- return v.Leave(n)
- }
-
- // DeallocateStmt is a statement to release PreparedStmt.
- // See: https://dev.mysql.com/doc/refman/5.7/en/deallocate-prepare.html
- type DeallocateStmt struct {
- stmtNode
-
- Name string
- }
-
- // Accept implements Node Accept interface.
- func (n *DeallocateStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DeallocateStmt)
- return v.Leave(n)
- }
-
- // ExecuteStmt is a statement to execute PreparedStmt.
- // See: https://dev.mysql.com/doc/refman/5.7/en/execute.html
- type ExecuteStmt struct {
- stmtNode
-
- Name string
- UsingVars []ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *ExecuteStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ExecuteStmt)
- for i, val := range n.UsingVars {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.UsingVars[i] = node.(ExprNode)
- }
- return v.Leave(n)
- }
-
- // BeginStmt is a statement to start a new transaction.
- // See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
- type BeginStmt struct {
- stmtNode
- }
-
- // Accept implements Node Accept interface.
- func (n *BeginStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*BeginStmt)
- return v.Leave(n)
- }
-
- // CommitStmt is a statement to commit the current transaction.
- // See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
- type CommitStmt struct {
- stmtNode
- }
-
- // Accept implements Node Accept interface.
- func (n *CommitStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CommitStmt)
- return v.Leave(n)
- }
-
- // RollbackStmt is a statement to roll back the current transaction.
- // See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
- type RollbackStmt struct {
- stmtNode
- }
-
- // Accept implements Node Accept interface.
- func (n *RollbackStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*RollbackStmt)
- return v.Leave(n)
- }
-
- // UseStmt is a statement to use the DBName database as the current database.
- // See: https://dev.mysql.com/doc/refman/5.7/en/use.html
- type UseStmt struct {
- stmtNode
-
- DBName string
- }
-
- // Accept implements Node Accept interface.
- func (n *UseStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*UseStmt)
- return v.Leave(n)
- }
-
- // VariableAssignment is a variable assignment struct.
- type VariableAssignment struct {
- node
- Name string
- Value ExprNode
- IsGlobal bool
- IsSystem bool
- }
-
- // Accept implements Node interface.
- func (n *VariableAssignment) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*VariableAssignment)
- node, ok := n.Value.Accept(v)
- if !ok {
- return n, false
- }
- n.Value = node.(ExprNode)
- return v.Leave(n)
- }
-
- // SetStmt is the statement to set variables.
- type SetStmt struct {
- stmtNode
- // Variables is the list of variable assignment.
- Variables []*VariableAssignment
- }
-
- // Accept implements Node Accept interface.
- func (n *SetStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetStmt)
- for i, val := range n.Variables {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Variables[i] = node.(*VariableAssignment)
- }
- return v.Leave(n)
- }
-
- // SetCharsetStmt is a statement to assign values to character and collation variables.
- // See: https://dev.mysql.com/doc/refman/5.7/en/set-statement.html
- type SetCharsetStmt struct {
- stmtNode
-
- Charset string
- Collate string
- }
-
- // Accept implements Node Accept interface.
- func (n *SetCharsetStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetCharsetStmt)
- return v.Leave(n)
- }
-
- // SetPwdStmt is a statement to assign a password to user account.
- // See: https://dev.mysql.com/doc/refman/5.7/en/set-password.html
- type SetPwdStmt struct {
- stmtNode
-
- User string
- Password string
- }
-
- // Accept implements Node Accept interface.
- func (n *SetPwdStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetPwdStmt)
- return v.Leave(n)
- }
-
- // UserSpec is used for parsing create user statement.
- type UserSpec struct {
- User string
- AuthOpt *AuthOption
- }
-
- // CreateUserStmt creates user account.
- // See: https://dev.mysql.com/doc/refman/5.7/en/create-user.html
- type CreateUserStmt struct {
- stmtNode
-
- IfNotExists bool
- Specs []*UserSpec
- }
-
- // Accept implements Node Accept interface.
- func (n *CreateUserStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CreateUserStmt)
- return v.Leave(n)
- }
-
- // DoStmt is the struct for DO statement.
- type DoStmt struct {
- stmtNode
-
- Exprs []ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *DoStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DoStmt)
- for i, val := range n.Exprs {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Exprs[i] = node.(ExprNode)
- }
- return v.Leave(n)
- }
-
- // AdminStmtType is the type for admin statement.
- type AdminStmtType int
-
- // Admin statement types.
- const (
- AdminShowDDL = iota + 1
- AdminCheckTable
- )
-
- // AdminStmt is the struct for Admin statement.
- type AdminStmt struct {
- stmtNode
-
- Tp AdminStmtType
- Tables []*TableName
- }
-
- // Accept implements Node Accpet interface.
- func (n *AdminStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
-
- n = newNode.(*AdminStmt)
- for i, val := range n.Tables {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Tables[i] = node.(*TableName)
- }
-
- return v.Leave(n)
- }
-
- // PrivElem is the privilege type and optional column list.
- type PrivElem struct {
- node
-
- Priv mysql.PrivilegeType
- Cols []*ColumnName
- }
-
- // Accept implements Node Accept interface.
- func (n *PrivElem) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PrivElem)
- for i, val := range n.Cols {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Cols[i] = node.(*ColumnName)
- }
- return v.Leave(n)
- }
-
- // ObjectTypeType is the type for object type.
- type ObjectTypeType int
-
- const (
- // ObjectTypeNone is for empty object type.
- ObjectTypeNone ObjectTypeType = iota + 1
- // ObjectTypeTable means the following object is a table.
- ObjectTypeTable
- )
-
- // GrantLevelType is the type for grant level.
- type GrantLevelType int
-
- const (
- // GrantLevelNone is the dummy const for default value.
- GrantLevelNone GrantLevelType = iota + 1
- // GrantLevelGlobal means the privileges are administrative or apply to all databases on a given server.
- GrantLevelGlobal
- // GrantLevelDB means the privileges apply to all objects in a given database.
- GrantLevelDB
- // GrantLevelTable means the privileges apply to all columns in a given table.
- GrantLevelTable
- )
-
- // GrantLevel is used for store the privilege scope.
- type GrantLevel struct {
- Level GrantLevelType
- DBName string
- TableName string
- }
-
- // GrantStmt is the struct for GRANT statement.
- type GrantStmt struct {
- stmtNode
-
- Privs []*PrivElem
- ObjectType ObjectTypeType
- Level *GrantLevel
- Users []*UserSpec
- }
-
- // Accept implements Node Accept interface.
- func (n *GrantStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*GrantStmt)
- for i, val := range n.Privs {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Privs[i] = node.(*PrivElem)
- }
- return v.Leave(n)
- }
-
- // Ident is the table identifier composed of schema name and table name.
- type Ident struct {
- Schema model.CIStr
- Name model.CIStr
- }
-
- // Full returns an Ident which set schema to the current schema if it is empty.
- func (i Ident) Full(ctx context.Context) (full Ident) {
- full.Name = i.Name
- if i.Schema.O != "" {
- full.Schema = i.Schema
- } else {
- full.Schema = model.NewCIStr(db.GetCurrentSchema(ctx))
- }
- return
- }
-
- // String implements fmt.Stringer interface
- func (i Ident) String() string {
- if i.Schema.O == "" {
- return i.Name.O
- }
- return fmt.Sprintf("%s.%s", i.Schema, i.Name)
- }
|