Files
tidb/expression/visitor.go
2015-10-13 15:52:51 +08:00

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
}