|
- // 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 (
- "regexp"
-
- "github.com/pingcap/tidb/context"
- "github.com/pingcap/tidb/model"
- "github.com/pingcap/tidb/mysql"
- "github.com/pingcap/tidb/parser/opcode"
- "github.com/pingcap/tidb/util/types"
- )
-
- var (
- _ ExprNode = &BetweenExpr{}
- _ ExprNode = &BinaryOperationExpr{}
- _ ExprNode = &CaseExpr{}
- _ ExprNode = &ColumnNameExpr{}
- _ ExprNode = &CompareSubqueryExpr{}
- _ ExprNode = &DefaultExpr{}
- _ ExprNode = &ExistsSubqueryExpr{}
- _ ExprNode = &IsNullExpr{}
- _ ExprNode = &IsTruthExpr{}
- _ ExprNode = &ParamMarkerExpr{}
- _ ExprNode = &ParenthesesExpr{}
- _ ExprNode = &PatternInExpr{}
- _ ExprNode = &PatternLikeExpr{}
- _ ExprNode = &PatternRegexpExpr{}
- _ ExprNode = &PositionExpr{}
- _ ExprNode = &RowExpr{}
- _ ExprNode = &SubqueryExpr{}
- _ ExprNode = &UnaryOperationExpr{}
- _ ExprNode = &ValueExpr{}
- _ ExprNode = &ValuesExpr{}
- _ ExprNode = &VariableExpr{}
-
- _ Node = &ColumnName{}
- _ Node = &WhenClause{}
- )
-
- // ValueExpr is the simple value expression.
- type ValueExpr struct {
- exprNode
- }
-
- // NewValueExpr creates a ValueExpr with value, and sets default field type.
- func NewValueExpr(value interface{}) *ValueExpr {
- if ve, ok := value.(*ValueExpr); ok {
- return ve
- }
- ve := &ValueExpr{}
- ve.SetValue(value)
- if _, ok := value.(UnquoteString); ok {
- ve.Type = types.NewFieldType(mysql.TypeVarchar)
- ve.Type.Charset = mysql.DefaultCharset
- ve.Type.Collate = mysql.DefaultCollationName
- return ve
- }
- ve.Type = types.DefaultTypeForValue(value)
- return ve
- }
-
- // Accept implements Node interface.
- func (n *ValueExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ValueExpr)
- return v.Leave(n)
- }
-
- // BetweenExpr is for "between and" or "not between and" expression.
- type BetweenExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Left is the expression for minimal value in the range.
- Left ExprNode
- // Right is the expression for maximum value in the range.
- Right ExprNode
- // Not is true, the expression is "not between and".
- Not bool
- }
-
- // Accept implements Node interface.
- func (n *BetweenExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
-
- n = newNode.(*BetweenExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
-
- node, ok = n.Left.Accept(v)
- if !ok {
- return n, false
- }
- n.Left = node.(ExprNode)
-
- node, ok = n.Right.Accept(v)
- if !ok {
- return n, false
- }
- n.Right = node.(ExprNode)
-
- return v.Leave(n)
- }
-
- // BinaryOperationExpr is for binary operation like `1 + 1`, `1 - 1`, etc.
- type BinaryOperationExpr struct {
- exprNode
- // Op is the operator code for BinaryOperation.
- Op opcode.Op
- // L is the left expression in BinaryOperation.
- L ExprNode
- // R is the right expression in BinaryOperation.
- R ExprNode
- }
-
- // Accept implements Node interface.
- func (n *BinaryOperationExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
-
- n = newNode.(*BinaryOperationExpr)
- node, ok := n.L.Accept(v)
- if !ok {
- return n, false
- }
- n.L = node.(ExprNode)
-
- node, ok = n.R.Accept(v)
- if !ok {
- return n, false
- }
- n.R = node.(ExprNode)
-
- return v.Leave(n)
- }
-
- // WhenClause is the when clause in Case expression for "when condition then result".
- type WhenClause struct {
- node
- // Expr is the condition expression in WhenClause.
- Expr ExprNode
- // Result is the result expression in WhenClause.
- Result ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *WhenClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
-
- n = newNode.(*WhenClause)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
-
- node, ok = n.Result.Accept(v)
- if !ok {
- return n, false
- }
- n.Result = node.(ExprNode)
- return v.Leave(n)
- }
-
- // CaseExpr is the case expression.
- type CaseExpr struct {
- exprNode
- // Value is the compare value expression.
- Value ExprNode
- // WhenClauses is the condition check expression.
- WhenClauses []*WhenClause
- // ElseClause is the else result expression.
- ElseClause ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *CaseExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
-
- n = newNode.(*CaseExpr)
- if n.Value != nil {
- node, ok := n.Value.Accept(v)
- if !ok {
- return n, false
- }
- n.Value = node.(ExprNode)
- }
- for i, val := range n.WhenClauses {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.WhenClauses[i] = node.(*WhenClause)
- }
- if n.ElseClause != nil {
- node, ok := n.ElseClause.Accept(v)
- if !ok {
- return n, false
- }
- n.ElseClause = node.(ExprNode)
- }
- return v.Leave(n)
- }
-
- // SubqueryExec represents a subquery executor interface.
- // This interface is implemented in executor and used in plan/evaluator.
- // It will execute the subselect and get the result.
- type SubqueryExec interface {
- ExprNode
-
- // EvalRows executes the subquery and returns the multi rows with rowCount.
- // rowCount < 0 means no limit.
- // If the ColumnCount is 1, we will return a column result like {1, 2, 3},
- // otherwise, we will return a table result like {{1, 1}, {2, 2}}.
- EvalRows(ctx context.Context, rowCount int) ([]interface{}, error)
-
- // ColumnCount returns column count for the sub query.
- ColumnCount() (int, error)
- }
-
- // SubqueryExpr represents a subquery.
- type SubqueryExpr struct {
- exprNode
- // Query is the query SelectNode.
- Query ResultSetNode
- SubqueryExec SubqueryExec
- Evaluated bool
- UseOuterContext bool
- }
-
- // Accept implements Node Accept interface.
- func (n *SubqueryExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SubqueryExpr)
-
- if n.SubqueryExec != nil {
- t, ok := n.SubqueryExec.Accept(v)
- if !ok {
- return n, false
- }
- sq, ok := t.(SubqueryExec)
- if !ok {
- return n, false
- }
- n.SubqueryExec = sq
- return v.Leave(n)
- }
-
- node, ok := n.Query.Accept(v)
- if !ok {
- return n, false
- }
- n.Query = node.(ResultSetNode)
-
- return v.Leave(n)
- }
-
- // SetResultFields implements ResultSetNode interface.
- func (n *SubqueryExpr) SetResultFields(rfs []*ResultField) {
- n.Query.SetResultFields(rfs)
- }
-
- // GetResultFields implements ResultSetNode interface.
- func (n *SubqueryExpr) GetResultFields() []*ResultField {
- return n.Query.GetResultFields()
- }
-
- // CompareSubqueryExpr is the expression for "expr cmp (select ...)".
- // See: https://dev.mysql.com/doc/refman/5.7/en/comparisons-using-subqueries.html
- // See: https://dev.mysql.com/doc/refman/5.7/en/any-in-some-subqueries.html
- // See: https://dev.mysql.com/doc/refman/5.7/en/all-subqueries.html
- type CompareSubqueryExpr struct {
- exprNode
- // L is the left expression
- L ExprNode
- // Op is the comparison opcode.
- Op opcode.Op
- // R is the subquery for right expression, may be rewritten to other type of expression.
- R ExprNode
- // All is true, we should compare all records in subquery.
- All bool
- }
-
- // Accept implements Node Accept interface.
- func (n *CompareSubqueryExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CompareSubqueryExpr)
- node, ok := n.L.Accept(v)
- if !ok {
- return n, false
- }
- n.L = node.(ExprNode)
- node, ok = n.R.Accept(v)
- if !ok {
- return n, false
- }
- n.R = node.(ExprNode)
- return v.Leave(n)
- }
-
- // ColumnName represents column name.
- type ColumnName struct {
- node
- Schema model.CIStr
- Table model.CIStr
- Name model.CIStr
- }
-
- // Accept implements Node Accept interface.
- func (n *ColumnName) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ColumnName)
- return v.Leave(n)
- }
-
- // ColumnNameExpr represents a column name expression.
- type ColumnNameExpr struct {
- exprNode
-
- // Name is the referenced column name.
- Name *ColumnName
-
- // Refer is the result field the column name refers to.
- // The value of Refer.Expr is used as the value of the expression.
- Refer *ResultField
- }
-
- // Accept implements Node Accept interface.
- func (n *ColumnNameExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ColumnNameExpr)
- node, ok := n.Name.Accept(v)
- if !ok {
- return n, false
- }
- n.Name = node.(*ColumnName)
- return v.Leave(n)
- }
-
- // DefaultExpr is the default expression using default value for a column.
- type DefaultExpr struct {
- exprNode
- // Name is the column name.
- Name *ColumnName
- }
-
- // Accept implements Node Accept interface.
- func (n *DefaultExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DefaultExpr)
- if n.Name != nil {
- node, ok := n.Name.Accept(v)
- if !ok {
- return n, false
- }
- n.Name = node.(*ColumnName)
- }
- return v.Leave(n)
- }
-
- // ExistsSubqueryExpr is the expression for "exists (select ...)".
- // https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html
- type ExistsSubqueryExpr struct {
- exprNode
- // Sel is the subquery, may be rewritten to other type of expression.
- Sel ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *ExistsSubqueryExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ExistsSubqueryExpr)
- node, ok := n.Sel.Accept(v)
- if !ok {
- return n, false
- }
- n.Sel = node.(ExprNode)
- return v.Leave(n)
- }
-
- // PatternInExpr is the expression for in operator, like "expr in (1, 2, 3)" or "expr in (select c from t)".
- type PatternInExpr struct {
- exprNode
- // Expr is the value expression to be compared.
- Expr ExprNode
- // List is the list expression in compare list.
- List []ExprNode
- // Not is true, the expression is "not in".
- Not bool
- // Sel is the subquery, may be rewritten to other type of expression.
- Sel ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *PatternInExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PatternInExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- for i, val := range n.List {
- node, ok = val.Accept(v)
- if !ok {
- return n, false
- }
- n.List[i] = node.(ExprNode)
- }
- if n.Sel != nil {
- node, ok = n.Sel.Accept(v)
- if !ok {
- return n, false
- }
- n.Sel = node.(ExprNode)
- }
- return v.Leave(n)
- }
-
- // IsNullExpr is the expression for null check.
- type IsNullExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Not is true, the expression is "is not null".
- Not bool
- }
-
- // Accept implements Node Accept interface.
- func (n *IsNullExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*IsNullExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
-
- // IsTruthExpr is the expression for true/false check.
- type IsTruthExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Not is true, the expression is "is not true/false".
- Not bool
- // True indicates checking true or false.
- True int64
- }
-
- // Accept implements Node Accept interface.
- func (n *IsTruthExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*IsTruthExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
-
- // PatternLikeExpr is the expression for like operator, e.g, expr like "%123%"
- type PatternLikeExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Pattern is the like expression.
- Pattern ExprNode
- // Not is true, the expression is "not like".
- Not bool
-
- Escape byte
-
- PatChars []byte
- PatTypes []byte
- }
-
- // Accept implements Node Accept interface.
- func (n *PatternLikeExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PatternLikeExpr)
- if n.Expr != nil {
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- }
- if n.Pattern != nil {
- node, ok := n.Pattern.Accept(v)
- if !ok {
- return n, false
- }
- n.Pattern = node.(ExprNode)
- }
- return v.Leave(n)
- }
-
- // ParamMarkerExpr expression holds a place for another expression.
- // Used in parsing prepare statement.
- type ParamMarkerExpr struct {
- exprNode
- Offset int
- }
-
- // Accept implements Node Accept interface.
- func (n *ParamMarkerExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ParamMarkerExpr)
- return v.Leave(n)
- }
-
- // ParenthesesExpr is the parentheses expression.
- type ParenthesesExpr struct {
- exprNode
- // Expr is the expression in parentheses.
- Expr ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *ParenthesesExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ParenthesesExpr)
- if n.Expr != nil {
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- }
- return v.Leave(n)
- }
-
- // PositionExpr is the expression for order by and group by position.
- // MySQL use position expression started from 1, it looks a little confused inner.
- // maybe later we will use 0 at first.
- type PositionExpr struct {
- exprNode
- // N is the position, started from 1 now.
- N int
- // Refer is the result field the position refers to.
- Refer *ResultField
- }
-
- // Accept implements Node Accept interface.
- func (n *PositionExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PositionExpr)
- return v.Leave(n)
- }
-
- // PatternRegexpExpr is the pattern expression for pattern match.
- type PatternRegexpExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Pattern is the expression for pattern.
- Pattern ExprNode
- // Not is true, the expression is "not rlike",
- Not bool
-
- // Re is the compiled regexp.
- Re *regexp.Regexp
- // Sexpr is the string for Expr expression.
- Sexpr *string
- }
-
- // Accept implements Node Accept interface.
- func (n *PatternRegexpExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PatternRegexpExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- node, ok = n.Pattern.Accept(v)
- if !ok {
- return n, false
- }
- n.Pattern = node.(ExprNode)
- return v.Leave(n)
- }
-
- // RowExpr is the expression for row constructor.
- // See https://dev.mysql.com/doc/refman/5.7/en/row-subqueries.html
- type RowExpr struct {
- exprNode
-
- Values []ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *RowExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*RowExpr)
- for i, val := range n.Values {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Values[i] = node.(ExprNode)
- }
- return v.Leave(n)
- }
-
- // UnaryOperationExpr is the expression for unary operator.
- type UnaryOperationExpr struct {
- exprNode
- // Op is the operator opcode.
- Op opcode.Op
- // V is the unary expression.
- V ExprNode
- }
-
- // Accept implements Node Accept interface.
- func (n *UnaryOperationExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*UnaryOperationExpr)
- node, ok := n.V.Accept(v)
- if !ok {
- return n, false
- }
- n.V = node.(ExprNode)
- return v.Leave(n)
- }
-
- // ValuesExpr is the expression used in INSERT VALUES
- type ValuesExpr struct {
- exprNode
- // model.CIStr is column name.
- Column *ColumnNameExpr
- }
-
- // Accept implements Node Accept interface.
- func (n *ValuesExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ValuesExpr)
- node, ok := n.Column.Accept(v)
- if !ok {
- return n, false
- }
- n.Column = node.(*ColumnNameExpr)
- return v.Leave(n)
- }
-
- // VariableExpr is the expression for variable.
- type VariableExpr struct {
- exprNode
- // Name is the variable name.
- Name string
- // IsGlobal indicates whether this variable is global.
- IsGlobal bool
- // IsSystem indicates whether this variable is a system variable in current session.
- IsSystem bool
- }
-
- // Accept implements Node Accept interface.
- func (n *VariableExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*VariableExpr)
- return v.Leave(n)
- }
|