500 lines
13 KiB
Go
500 lines
13 KiB
Go
// 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 expression
|
|
|
|
import "github.com/juju/errors"
|
|
|
|
// Visitor represents a visitor pattern.
|
|
type Visitor interface {
|
|
// VisitBetween visits Between expression.
|
|
VisitBetween(b *Between) (Expression, error)
|
|
|
|
// VisitBinaryOperation visits BinaryOperation expression.
|
|
VisitBinaryOperation(o *BinaryOperation) (Expression, error)
|
|
|
|
// VisitCall visits Call expression.
|
|
VisitCall(c *Call) (Expression, error)
|
|
|
|
// VisitCompareSubQuery visits CompareSubQuery expression.
|
|
VisitCompareSubQuery(cs *CompareSubQuery) (Expression, error)
|
|
|
|
// VisitDefault visits Default expression.
|
|
VisitDefault(d *Default) (Expression, error)
|
|
|
|
// VisitFunctionCase visits FunctionCase expression.
|
|
VisitFunctionCase(f *FunctionCase) (Expression, error)
|
|
|
|
// VisitFunctionCast visits FunctionCast expression.
|
|
VisitFunctionCast(f *FunctionCast) (Expression, error)
|
|
|
|
// VisitFunctionConvert visits FunctionConvert expression.
|
|
VisitFunctionConvert(f *FunctionConvert) (Expression, error)
|
|
|
|
// VisitFunctionSubstring visits FunctionSubstring expression.
|
|
VisitFunctionSubstring(ss *FunctionSubstring) (Expression, error)
|
|
|
|
// VisitFunctionSubstringIndex visits FunctionSubstringIndex expression.
|
|
VisitFunctionSubstringIndex(ss *FunctionSubstringIndex) (Expression, error)
|
|
|
|
// VisitFunctionLocate visits FunctionLocate expression.
|
|
VisitFunctionLocate(ss *FunctionLocate) (Expression, error)
|
|
|
|
// VisitExistsSubQuery visits ExistsSubQuery expression.
|
|
VisitExistsSubQuery(es *ExistsSubQuery) (Expression, error)
|
|
|
|
// VisitIdent visits Ident expression.
|
|
VisitIdent(i *Ident) (Expression, error)
|
|
|
|
// VisitIsNull visits IsNull expression.
|
|
VisitIsNull(is *IsNull) (Expression, error)
|
|
|
|
// VisitIsTruth visits IsTruth expression.
|
|
VisitIsTruth(is *IsTruth) (Expression, error)
|
|
|
|
// VisitParamMaker visits ParamMarker expression.
|
|
VisitParamMaker(pm *ParamMarker) (Expression, error)
|
|
|
|
// VisitPatternIn visits PatternIn expression.
|
|
VisitPatternIn(n *PatternIn) (Expression, error)
|
|
|
|
// VisitPatternLike visits PatternLike expression.
|
|
VisitPatternLike(p *PatternLike) (Expression, error)
|
|
|
|
// VisitPatternRegexp visits PatternRegexp expression.
|
|
VisitPatternRegexp(p *PatternRegexp) (Expression, error)
|
|
|
|
// VisitPExpr visits PExpr expression.
|
|
VisitPExpr(p *PExpr) (Expression, error)
|
|
|
|
// VisitPosition visits Position expression.
|
|
VisitPosition(p *Position) (Expression, error)
|
|
|
|
// VisitRow visits Row expression.
|
|
VisitRow(r *Row) (Expression, error)
|
|
|
|
// VisitSubQuery visits SubQuery expression.
|
|
VisitSubQuery(sq SubQuery) (Expression, error)
|
|
|
|
// VisitUnaryOperation visits UnaryOperation expression.
|
|
VisitUnaryOperation(u *UnaryOperation) (Expression, error)
|
|
|
|
// VisitValue visits Value expression.
|
|
VisitValue(v Value) (Expression, error)
|
|
|
|
// VisitValues visits Values expression.
|
|
VisitValues(v *Values) (Expression, error)
|
|
|
|
// VisitVariable visits Variable expression.
|
|
VisitVariable(v *Variable) (Expression, error)
|
|
|
|
// VisitWhenClause visits WhenClause expression.
|
|
VisitWhenClause(w *WhenClause) (Expression, error)
|
|
|
|
// VisitExtract visits Extract expression.
|
|
VisitExtract(v *Extract) (Expression, error)
|
|
|
|
// VisitFunctionTrim visits FunctionTrim expression.
|
|
VisitFunctionTrim(v *FunctionTrim) (Expression, error)
|
|
|
|
// VisitDateAdd visits DateAdd expression.
|
|
VisitDateAdd(da *DateAdd) (Expression, error)
|
|
}
|
|
|
|
// BaseVisitor is the base implementation of Visitor.
|
|
// It traverses the expression tree and call expression's Accept function.
|
|
// It can not be used directly.
|
|
// A specific Visitor implementation can embed it in and only implements
|
|
// desired methods to do the job.
|
|
type BaseVisitor struct {
|
|
V Visitor
|
|
}
|
|
|
|
// VisitBetween implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitBetween(b *Between) (Expression, error) {
|
|
var err error
|
|
b.Expr, err = b.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return b, errors.Trace(err)
|
|
}
|
|
b.Left, err = b.Left.Accept(bv.V)
|
|
if err != nil {
|
|
return b, errors.Trace(err)
|
|
}
|
|
b.Right, err = b.Right.Accept(bv.V)
|
|
if err != nil {
|
|
return b, errors.Trace(err)
|
|
}
|
|
return b, nil
|
|
}
|
|
|
|
// VisitBinaryOperation implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitBinaryOperation(o *BinaryOperation) (Expression, error) {
|
|
var err error
|
|
o.L, err = o.L.Accept(bv.V)
|
|
if err != nil {
|
|
return o, errors.Trace(err)
|
|
}
|
|
o.R, err = o.R.Accept(bv.V)
|
|
if err != nil {
|
|
return o, errors.Trace(err)
|
|
}
|
|
return o, nil
|
|
}
|
|
|
|
// VisitCall implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitCall(c *Call) (Expression, error) {
|
|
var err error
|
|
for i := range c.Args {
|
|
c.Args[i], err = c.Args[i].Accept(bv.V)
|
|
if err != nil {
|
|
return c, errors.Trace(err)
|
|
}
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// VisitCompareSubQuery implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitCompareSubQuery(cs *CompareSubQuery) (Expression, error) {
|
|
var err error
|
|
cs.L, err = cs.L.Accept(bv.V)
|
|
if err != nil {
|
|
return cs, errors.Trace(err)
|
|
}
|
|
_, err = cs.R.Accept(bv.V)
|
|
if err != nil {
|
|
return cs, errors.Trace(err)
|
|
}
|
|
return cs, nil
|
|
}
|
|
|
|
// VisitDefault implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitDefault(d *Default) (Expression, error) {
|
|
return d, nil
|
|
}
|
|
|
|
// VisitExistsSubQuery implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitExistsSubQuery(es *ExistsSubQuery) (Expression, error) {
|
|
var err error
|
|
_, err = es.Sel.Accept(bv.V)
|
|
if err != nil {
|
|
return es, errors.Trace(err)
|
|
}
|
|
return es, nil
|
|
}
|
|
|
|
// VisitFunctionCase implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitFunctionCase(f *FunctionCase) (Expression, error) {
|
|
var err error
|
|
if f.Value != nil {
|
|
f.Value, err = f.Value.Accept(bv.V)
|
|
if err != nil {
|
|
return f, errors.Trace(err)
|
|
}
|
|
}
|
|
for i := range f.WhenClauses {
|
|
_, err = f.WhenClauses[i].Accept(bv.V)
|
|
if err != nil {
|
|
return f, errors.Trace(err)
|
|
}
|
|
}
|
|
if f.ElseClause != nil {
|
|
f.ElseClause, err = f.ElseClause.Accept(bv.V)
|
|
if err != nil {
|
|
return f, errors.Trace(err)
|
|
}
|
|
}
|
|
return f, nil
|
|
}
|
|
|
|
//VisitFunctionCast implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitFunctionCast(f *FunctionCast) (Expression, error) {
|
|
var err error
|
|
f.Expr, err = f.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return f, errors.Trace(err)
|
|
}
|
|
return f, nil
|
|
}
|
|
|
|
// VisitFunctionConvert implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitFunctionConvert(f *FunctionConvert) (Expression, error) {
|
|
var err error
|
|
f.Expr, err = f.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return f, errors.Trace(err)
|
|
}
|
|
return f, nil
|
|
}
|
|
|
|
// VisitFunctionSubstring implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitFunctionSubstring(ss *FunctionSubstring) (Expression, error) {
|
|
var err error
|
|
ss.StrExpr, err = ss.StrExpr.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
ss.Pos, err = ss.Pos.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
if ss.Len == nil {
|
|
return ss, nil
|
|
}
|
|
ss.Len, err = ss.Len.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
return ss, nil
|
|
}
|
|
|
|
// VisitFunctionSubstringIndex implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitFunctionSubstringIndex(ss *FunctionSubstringIndex) (Expression, error) {
|
|
var err error
|
|
ss.StrExpr, err = ss.StrExpr.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
ss.Delim, err = ss.Delim.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
if ss.Count == nil {
|
|
return ss, nil
|
|
}
|
|
ss.Count, err = ss.Count.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
return ss, nil
|
|
}
|
|
|
|
// VisitFunctionLocate implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitFunctionLocate(ss *FunctionLocate) (Expression, error) {
|
|
var err error
|
|
ss.Str, err = ss.Str.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
ss.SubStr, err = ss.SubStr.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
if ss.Pos == nil {
|
|
return ss, nil
|
|
}
|
|
ss.Pos, err = ss.Pos.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
return ss, nil
|
|
}
|
|
|
|
// VisitIdent implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitIdent(i *Ident) (Expression, error) {
|
|
return i, nil
|
|
}
|
|
|
|
// VisitIsNull implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitIsNull(is *IsNull) (Expression, error) {
|
|
var err error
|
|
is.Expr, err = is.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return is, errors.Trace(err)
|
|
}
|
|
return is, nil
|
|
}
|
|
|
|
// VisitIsTruth implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitIsTruth(is *IsTruth) (Expression, error) {
|
|
var err error
|
|
is.Expr, err = is.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return is, errors.Trace(err)
|
|
}
|
|
return is, nil
|
|
}
|
|
|
|
// VisitParamMaker implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitParamMaker(pm *ParamMarker) (Expression, error) {
|
|
if pm.Expr == nil {
|
|
return pm, nil
|
|
}
|
|
var err error
|
|
pm.Expr, err = pm.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return pm, errors.Trace(err)
|
|
}
|
|
return pm, nil
|
|
}
|
|
|
|
// VisitPatternIn implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitPatternIn(n *PatternIn) (Expression, error) {
|
|
var err error
|
|
n.Expr, err = n.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return n, errors.Trace(err)
|
|
}
|
|
if n.Sel != nil {
|
|
_, err = n.Sel.Accept(bv.V)
|
|
if err != nil {
|
|
return n, errors.Trace(err)
|
|
}
|
|
}
|
|
for i := range n.List {
|
|
n.List[i], err = n.List[i].Accept(bv.V)
|
|
if err != nil {
|
|
return n, errors.Trace(err)
|
|
}
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
// VisitPatternLike implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitPatternLike(p *PatternLike) (Expression, error) {
|
|
var err error
|
|
p.Expr, err = p.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return p, errors.Trace(err)
|
|
}
|
|
p.Pattern, err = p.Pattern.Accept(bv.V)
|
|
if err != nil {
|
|
return p, errors.Trace(err)
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
// VisitPatternRegexp implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitPatternRegexp(p *PatternRegexp) (Expression, error) {
|
|
var err error
|
|
p.Expr, err = p.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return p, errors.Trace(err)
|
|
}
|
|
p.Pattern, err = p.Pattern.Accept(bv.V)
|
|
if err != nil {
|
|
return p, errors.Trace(err)
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
// VisitPExpr implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitPExpr(p *PExpr) (Expression, error) {
|
|
var err error
|
|
p.Expr, err = p.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return p, errors.Trace(err)
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
// VisitPosition implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitPosition(p *Position) (Expression, error) {
|
|
return p, nil
|
|
}
|
|
|
|
// VisitRow implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitRow(r *Row) (Expression, error) {
|
|
var err error
|
|
for i := range r.Values {
|
|
r.Values[i], err = r.Values[i].Accept(bv.V)
|
|
if err != nil {
|
|
return r, errors.Trace(err)
|
|
}
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// VisitSubQuery implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitSubQuery(sq SubQuery) (Expression, error) {
|
|
return sq, nil
|
|
}
|
|
|
|
// VisitUnaryOperation implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitUnaryOperation(u *UnaryOperation) (Expression, error) {
|
|
var err error
|
|
u.V, err = u.V.Accept(bv.V)
|
|
if err != nil {
|
|
return u, errors.Trace(err)
|
|
}
|
|
return u, nil
|
|
}
|
|
|
|
// VisitValue implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitValue(v Value) (Expression, error) {
|
|
return v, nil
|
|
}
|
|
|
|
// VisitValues implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitValues(v *Values) (Expression, error) {
|
|
return v, nil
|
|
}
|
|
|
|
// VisitVariable implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitVariable(v *Variable) (Expression, error) {
|
|
return v, nil
|
|
}
|
|
|
|
// VisitWhenClause implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitWhenClause(w *WhenClause) (Expression, error) {
|
|
var err error
|
|
w.Expr, err = w.Expr.Accept(bv.V)
|
|
if err != nil {
|
|
return w, errors.Trace(err)
|
|
}
|
|
w.Result, err = w.Result.Accept(bv.V)
|
|
if err != nil {
|
|
return w, errors.Trace(err)
|
|
}
|
|
return w, nil
|
|
}
|
|
|
|
// VisitExtract implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitExtract(v *Extract) (Expression, error) {
|
|
var err error
|
|
v.Date, err = v.Date.Accept(bv.V)
|
|
return v, errors.Trace(err)
|
|
}
|
|
|
|
// VisitFunctionTrim implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitFunctionTrim(ss *FunctionTrim) (Expression, error) {
|
|
var err error
|
|
ss.Str, err = ss.Str.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
if ss.RemStr != nil {
|
|
ss.RemStr, err = ss.RemStr.Accept(bv.V)
|
|
if err != nil {
|
|
return ss, errors.Trace(err)
|
|
}
|
|
}
|
|
return ss, nil
|
|
}
|
|
|
|
// VisitDateAdd implements Visitor interface.
|
|
func (bv *BaseVisitor) VisitDateAdd(da *DateAdd) (Expression, error) {
|
|
var err error
|
|
da.Date, err = da.Date.Accept(bv.V)
|
|
if err != nil {
|
|
return da, errors.Trace(err)
|
|
}
|
|
|
|
da.Interval, err = da.Interval.Accept(bv.V)
|
|
if err != nil {
|
|
return da, errors.Trace(err)
|
|
}
|
|
|
|
return da, nil
|
|
}
|