Merge pull request #960 from pingcap/zxylvlp/move-ast-functions-to-buildin

evaluator: move the evaluate of ast function trim to buildin
This commit is contained in:
zxylvlp
2016-03-09 18:23:13 +08:00
9 changed files with 133 additions and 166 deletions

View File

@ -68,8 +68,6 @@ func (f *flagSetter) Leave(in Node) (Node, bool) {
x.SetFlag(FlagHasFunc | x.Expr.GetFlag())
case *FuncDateArithExpr:
f.funcDateArith(x)
case *FuncTrimExpr:
f.funcTrim(x)
case *IsNullExpr:
x.SetFlag(x.Expr.GetFlag())
case *IsTruthExpr:
@ -160,14 +158,6 @@ func (f *flagSetter) funcCall(x *FuncCallExpr) {
x.SetFlag(flag)
}
func (f *flagSetter) funcTrim(x *FuncTrimExpr) {
flag := FlagHasFunc | x.Str.GetFlag()
if x.RemStr != nil {
flag |= x.RemStr.GetFlag()
}
x.SetFlag(flag)
}
func (f *flagSetter) funcDateArith(x *FuncDateArithExpr) {
flag := FlagHasFunc | x.Date.GetFlag()
if x.Interval != nil {

View File

@ -29,7 +29,6 @@ var (
_ FuncNode = &FuncCallExpr{}
_ FuncNode = &FuncCastExpr{}
_ FuncNode = &FuncDateArithExpr{}
_ FuncNode = &FuncTrimExpr{}
)
// UnquoteString is not quoted when printed.
@ -112,38 +111,6 @@ const (
TrimTrailing
)
// FuncTrimExpr remove leading/trailing/both remstr.
// See: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_trim
type FuncTrimExpr struct {
funcNode
Str ExprNode
RemStr ExprNode
Direction TrimDirectionType
}
// Accept implements Node Accept interface.
func (n *FuncTrimExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*FuncTrimExpr)
node, ok := n.Str.Accept(v)
if !ok {
return n, false
}
n.Str = node.(ExprNode)
if n.RemStr != nil {
node, ok = n.RemStr.Accept(v)
if !ok {
return n, false
}
n.RemStr = node.(ExprNode)
}
return v.Leave(n)
}
// DateArithType is type for DateArith type.
type DateArithType byte

View File

@ -92,6 +92,7 @@ var Funcs = map[string]Func{
"substring": {builtinSubstring, 2, 3, true, false},
"substring_index": {builtinSubstringIndex, 3, 3, true, false},
"locate": {builtinLocate, 2, 3, true, false},
"trim": {builtinTrim, 1, 3, true, false},
// information functions
"current_user": {builtinCurrentUser, 0, 0, false, false},

View File

@ -23,6 +23,7 @@ import (
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/util/charset"
"github.com/pingcap/tidb/util/types"
@ -276,9 +277,9 @@ func builtinSubstring(args []interface{}, _ context.Context) (interface{}, error
// See: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_substring-index
func builtinSubstringIndex(args []interface{}, _ context.Context) (interface{}, error) {
// The meaning of the elements of args.
//args[0] -> StrExpr
//args[1] -> Delim
//args[2] -> Count
// args[0] -> StrExpr
// args[1] -> Delim
// args[2] -> Count
fs := args[0]
str, err := types.ToString(fs)
if err != nil {
@ -324,9 +325,9 @@ func builtinSubstringIndex(args []interface{}, _ context.Context) (interface{},
// See: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_locate
func builtinLocate(args []interface{}, _ context.Context) (interface{}, error) {
// The meaning of the elements of args.
//args[0] -> SubStr
//args[1] -> Str
//args[2] -> Pos
// args[0] -> SubStr
// args[1] -> Str
// args[2] -> Pos
// eval str
fs := args[1]
if fs == nil {
@ -370,3 +371,79 @@ func builtinLocate(args []interface{}, _ context.Context) (interface{}, error) {
}
return int64(i) + pos + 1, nil
}
const spaceChars = "\n\t\r "
// See: https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_trim
func builtinTrim(args []interface{}, _ context.Context) (interface{}, error) {
// args[0] -> Str
// args[1] -> RemStr
// args[2] -> Direction
// eval str
fs := args[0]
if fs == nil {
return nil, nil
}
str, err := types.ToString(fs)
if err != nil {
return nil, errors.Trace(err)
}
remstr := ""
// eval remstr
if len(args) > 1 {
fs = args[1]
if fs != nil {
remstr, err = types.ToString(fs)
if err != nil {
return nil, errors.Trace(err)
}
}
}
// do trim
var result string
var direction ast.TrimDirectionType
if len(args) > 2 {
direction = args[2].(ast.TrimDirectionType)
} else {
direction = ast.TrimBothDefault
}
if direction == ast.TrimLeading {
if len(remstr) > 0 {
result = trimLeft(str, remstr)
} else {
result = strings.TrimLeft(str, spaceChars)
}
} else if direction == ast.TrimTrailing {
if len(remstr) > 0 {
result = trimRight(str, remstr)
} else {
result = strings.TrimRight(str, spaceChars)
}
} else if len(remstr) > 0 {
x := trimLeft(str, remstr)
result = trimRight(x, remstr)
} else {
result = strings.Trim(str, spaceChars)
}
return result, nil
}
func trimLeft(str, remstr string) string {
for {
x := strings.TrimPrefix(str, remstr)
if len(x) == len(str) {
return x
}
str = x
}
}
func trimRight(str, remstr string) string {
for {
x := strings.TrimSuffix(str, remstr)
if len(x) == len(str) {
return x
}
str = x
}
}

View File

@ -125,8 +125,6 @@ func (e *Evaluator) Leave(in ast.Node) (out ast.Node, ok bool) {
ok = e.funcCast(v)
case *ast.FuncDateArithExpr:
ok = e.funcDateArith(v)
case *ast.FuncTrimExpr:
ok = e.funcTrim(v)
case *ast.IsNullExpr:
ok = e.isNull(v)
case *ast.IsTruthExpr:
@ -709,78 +707,6 @@ func (e *Evaluator) funcCast(v *ast.FuncCastExpr) bool {
return true
}
const spaceChars = "\n\t\r "
func (e *Evaluator) funcTrim(v *ast.FuncTrimExpr) bool {
// eval str
fs := v.Str.GetValue()
if fs == nil {
v.SetValue(nil)
return true
}
str, err := types.ToString(fs)
if err != nil {
e.err = errors.Trace(err)
return false
}
remstr := ""
// eval remstr
if v.RemStr != nil {
fs = v.RemStr.GetValue()
if fs == nil {
v.SetValue(nil)
return true
}
remstr, err = types.ToString(fs)
if err != nil {
e.err = errors.Trace(err)
return false
}
}
// Do trim
var result string
if v.Direction == ast.TrimLeading {
if len(remstr) > 0 {
result = trimLeft(str, remstr)
} else {
result = strings.TrimLeft(str, spaceChars)
}
} else if v.Direction == ast.TrimTrailing {
if len(remstr) > 0 {
result = trimRight(str, remstr)
} else {
result = strings.TrimRight(str, spaceChars)
}
} else if len(remstr) > 0 {
x := trimLeft(str, remstr)
result = trimRight(x, remstr)
} else {
result = strings.Trim(str, spaceChars)
}
v.SetValue(result)
return true
}
func trimLeft(str, remstr string) string {
for {
x := strings.TrimPrefix(str, remstr)
if len(x) == len(str) {
return x
}
str = x
}
}
func trimRight(str, remstr string) string {
for {
x := strings.TrimSuffix(str, remstr)
if len(x) == len(str) {
return x
}
str = x
}
}
func (e *Evaluator) funcDateArith(v *ast.FuncDateArithExpr) bool {
// health check for date and interval
nodeDate := v.Date.GetValue()

View File

@ -1108,14 +1108,14 @@ func (s *testEvaluatorSuite) TestTrim(c *C) {
}
ctx := mock.NewContext()
for _, v := range tbl {
f := &ast.FuncTrimExpr{
Str: ast.NewValueExpr(v.str),
Direction: v.dir,
f := &ast.FuncCallExpr{
FnName: model.NewCIStr("TRIM"),
Args: []ast.ExprNode{
ast.NewValueExpr(v.str),
ast.NewValueExpr(v.remstr),
ast.NewValueExpr(v.dir),
},
}
if v.remstr != nil {
f.RemStr = ast.NewValueExpr(v.remstr)
}
r, err := Eval(ctx, f)
c.Assert(err, IsNil)
c.Assert(r, Equals, v.result)

View File

@ -274,7 +274,7 @@ func (v *typeInferrer) handleFuncCallExpr(x *ast.FuncCallExpr) {
tp.Decimal = v.getFsp(x)
case "dayname", "version", "database", "user", "current_user",
"concat", "concat_ws", "left", "lower", "repeat", "replace", "upper", "convert",
"substring", "substring_index":
"substring", "substring_index", "trim":
tp = types.NewFieldType(mysql.TypeVarString)
chs = v.defaultCharset
case "strcmp":

View File

@ -734,8 +734,8 @@ var (
57372: 354, // by (3x)
57673: 355, // ByItem (3x)
57677: 356, // ColumnDef (3x)
57691: 357, // Constraint (3x)
57393: 358, // constraint (3x)
57393: 357, // constraint (3x)
57691: 358, // Constraint (3x)
57693: 359, // ConstraintKeywordOpt (3x)
57715: 360, // DeleteFromStmt (3x)
57740: 361, // FieldOpt (3x)
@ -1302,8 +1302,8 @@ var (
"by",
"ByItem",
"ColumnDef",
"Constraint",
"constraint",
"Constraint",
"ConstraintKeywordOpt",
"DeleteFromStmt",
"FieldOpt",
@ -2214,7 +2214,7 @@ var (
698: {473, 1},
699: {522, 1},
700: {522, 3},
701: {357, 2},
701: {358, 2},
702: {438, 1},
703: {438, 1},
704: {438, 4},
@ -5315,7 +5315,7 @@ var (
{673, 673, 673, 673, 6: 673, 9: 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 123: 673},
{927, 976, 928, 945, 6: 934, 9: 950, 977, 979, 980, 978, 991, 942, 981, 982, 983, 941, 957, 959, 951, 944, 999, 968, 935, 938, 937, 1009, 989, 1018, 992, 1023, 1025, 1027, 949, 986, 1032, 961, 965, 966, 970, 1002, 930, 936, 939, 940, 974, 1028, 953, 955, 956, 964, 973, 931, 933, 932, 975, 994, 943, 946, 958, 988, 998, 947, 969, 984, 996, 993, 997, 954, 960, 962, 963, 990, 995, 967, 1000, 1001, 971, 929, 1033, 1003, 1004, 1005, 1006, 1008, 1007, 1010, 1011, 1012, 1013, 1014, 1015, 987, 1016, 1017, 924, 1019, 1020, 1021, 1022, 1024, 948, 1026, 1029, 1030, 952, 1031, 985, 972, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 198: 1043, 926, 925, 295: 2047},
{125: 2048},
{927, 976, 928, 945, 6: 934, 9: 950, 977, 979, 980, 978, 991, 942, 981, 982, 983, 941, 957, 959, 951, 944, 999, 968, 935, 938, 937, 1009, 989, 1018, 992, 1023, 1025, 1027, 949, 986, 1032, 961, 965, 966, 970, 1002, 930, 936, 939, 940, 974, 1028, 953, 955, 956, 964, 973, 931, 933, 932, 975, 994, 943, 946, 958, 988, 998, 947, 969, 984, 996, 993, 997, 954, 960, 962, 963, 990, 995, 967, 1000, 1001, 971, 929, 1033, 1003, 1004, 1005, 1006, 1008, 1007, 1010, 1011, 1012, 1013, 1014, 1015, 987, 1016, 1017, 924, 1019, 1020, 1021, 1022, 1024, 948, 1026, 1029, 1030, 952, 1031, 985, 972, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 195: 834, 834, 2055, 1075, 926, 925, 234: 2050, 236: 834, 238: 834, 255: 834, 257: 834, 356: 2053, 2054, 2049, 2052, 438: 2056, 525: 2051},
{927, 976, 928, 945, 6: 934, 9: 950, 977, 979, 980, 978, 991, 942, 981, 982, 983, 941, 957, 959, 951, 944, 999, 968, 935, 938, 937, 1009, 989, 1018, 992, 1023, 1025, 1027, 949, 986, 1032, 961, 965, 966, 970, 1002, 930, 936, 939, 940, 974, 1028, 953, 955, 956, 964, 973, 931, 933, 932, 975, 994, 943, 946, 958, 988, 998, 947, 969, 984, 996, 993, 997, 954, 960, 962, 963, 990, 995, 967, 1000, 1001, 971, 929, 1033, 1003, 1004, 1005, 1006, 1008, 1007, 1010, 1011, 1012, 1013, 1014, 1015, 987, 1016, 1017, 924, 1019, 1020, 1021, 1022, 1024, 948, 1026, 1029, 1030, 952, 1031, 985, 972, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 195: 834, 834, 2055, 1075, 926, 925, 234: 2050, 236: 834, 238: 834, 255: 834, 257: 834, 356: 2053, 2049, 2054, 2052, 438: 2056, 525: 2051},
// 1195
{927, 976, 928, 945, 6: 934, 9: 950, 977, 979, 980, 978, 991, 942, 981, 982, 983, 941, 957, 959, 951, 944, 999, 968, 935, 938, 937, 1009, 989, 1018, 992, 1023, 1025, 1027, 949, 986, 1032, 961, 965, 966, 970, 1002, 930, 936, 939, 940, 974, 1028, 953, 955, 956, 964, 973, 931, 933, 932, 975, 994, 943, 946, 958, 988, 998, 947, 969, 984, 996, 993, 997, 954, 960, 962, 963, 990, 995, 967, 1000, 1001, 971, 929, 1033, 1003, 1004, 1005, 1006, 1008, 1007, 1010, 1011, 1012, 1013, 1014, 1015, 987, 1016, 1017, 924, 1019, 1020, 1021, 1022, 1024, 948, 1026, 1029, 1030, 952, 1031, 985, 972, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 195: 833, 833, 198: 2309, 926, 925, 236: 833, 238: 833, 255: 833, 257: 833, 437: 2308},
{25: 2219, 27: 2216, 2215, 39: 2218, 55: 2198, 2192, 2191, 67: 2206, 72: 2212, 2217, 145: 2205, 189: 2200, 253: 87, 258: 2193, 2189, 261: 87, 263: 2190, 2208, 2197, 2204, 2175, 2176, 2195, 2177, 2188, 2210, 2214, 2209, 2187, 2213, 2194, 279: 2196, 2186, 2178, 2207, 2185, 2211, 2180, 2179, 2201, 453: 2184, 2202, 466: 2174, 478: 2182, 2183, 486: 2181, 492: 2199, 2172, 523: 2173, 529: 2203, 532: 2171},
@ -5398,7 +5398,7 @@ var (
{7: 2115, 2077},
{4: 800, 800, 7: 800, 800},
{2123, 2124, 4: 132, 132, 760, 9: 2128, 2125, 2127, 2129, 2126, 2133, 2121, 2130, 2131, 2132, 128: 2120, 142: 760, 202: 760, 324: 2122, 341: 2135, 370: 2134, 2119},
{927, 976, 928, 945, 6: 934, 9: 950, 977, 979, 980, 978, 991, 942, 981, 982, 983, 941, 957, 959, 951, 944, 999, 968, 935, 938, 937, 1009, 989, 1018, 992, 1023, 1025, 1027, 949, 986, 1032, 961, 965, 966, 970, 1002, 930, 936, 939, 940, 974, 1028, 953, 955, 956, 964, 973, 931, 933, 932, 975, 994, 943, 946, 958, 988, 998, 947, 969, 984, 996, 993, 997, 954, 960, 962, 963, 990, 995, 967, 1000, 1001, 971, 929, 1033, 1003, 1004, 1005, 1006, 1008, 1007, 1010, 1011, 1012, 1013, 1014, 1015, 987, 1016, 1017, 924, 1019, 1020, 1021, 1022, 1024, 948, 1026, 1029, 1030, 952, 1031, 985, 972, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 195: 834, 834, 2055, 1075, 926, 925, 234: 2050, 236: 834, 238: 834, 255: 834, 257: 834, 356: 2053, 2054, 2049, 2052, 438: 2118},
{927, 976, 928, 945, 6: 934, 9: 950, 977, 979, 980, 978, 991, 942, 981, 982, 983, 941, 957, 959, 951, 944, 999, 968, 935, 938, 937, 1009, 989, 1018, 992, 1023, 1025, 1027, 949, 986, 1032, 961, 965, 966, 970, 1002, 930, 936, 939, 940, 974, 1028, 953, 955, 956, 964, 973, 931, 933, 932, 975, 994, 943, 946, 958, 988, 998, 947, 969, 984, 996, 993, 997, 954, 960, 962, 963, 990, 995, 967, 1000, 1001, 971, 929, 1033, 1003, 1004, 1005, 1006, 1008, 1007, 1010, 1011, 1012, 1013, 1014, 1015, 987, 1016, 1017, 924, 1019, 1020, 1021, 1022, 1024, 948, 1026, 1029, 1030, 952, 1031, 985, 972, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 195: 834, 834, 2055, 1075, 926, 925, 234: 2050, 236: 834, 238: 834, 255: 834, 257: 834, 356: 2053, 2049, 2054, 2052, 438: 2118},
{7: 148, 148},
// 1265
{4: 764, 764},
@ -5661,7 +5661,7 @@ var (
// 1480
{4: 851, 851, 8: 2358},
{4: 850, 850, 8: 850},
{841, 841, 841, 841, 6: 841, 9: 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 195: 834, 834, 236: 834, 238: 834, 255: 834, 257: 834, 357: 2352, 2049, 2052, 384: 2345, 2351},
{841, 841, 841, 841, 6: 841, 9: 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 195: 834, 834, 236: 834, 238: 834, 255: 834, 257: 834, 357: 2049, 2352, 2052, 384: 2345, 2351},
{841, 841, 841, 841, 6: 841, 9: 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 841, 195: 2340, 236: 2343, 238: 2344, 255: 2342, 384: 2345, 2339, 488: 2341},
{4: 836, 836, 8: 836},
// 1485
@ -7275,30 +7275,33 @@ yynewstate:
}
case 437:
{
yyVAL.item = &ast.FuncTrimExpr{
Str: yyS[yypt-1].item.(ast.ExprNode),
yyVAL.item = &ast.FuncCallExpr{
FnName: model.NewCIStr(yyS[yypt-3].item.(string)),
Args: []ast.ExprNode{yyS[yypt-1].item.(ast.ExprNode)},
}
}
case 438:
{
yyVAL.item = &ast.FuncTrimExpr{
Str: yyS[yypt-1].item.(ast.ExprNode),
RemStr: yyS[yypt-3].item.(ast.ExprNode),
yyVAL.item = &ast.FuncCallExpr{
FnName: model.NewCIStr(yyS[yypt-5].item.(string)),
Args: []ast.ExprNode{yyS[yypt-1].item.(ast.ExprNode), yyS[yypt-3].item.(ast.ExprNode)},
}
}
case 439:
{
yyVAL.item = &ast.FuncTrimExpr{
Str: yyS[yypt-1].item.(ast.ExprNode),
Direction: yyS[yypt-3].item.(ast.TrimDirectionType),
nilVal := ast.NewValueExpr(nil)
direction := ast.NewValueExpr(yyS[yypt-3].item)
yyVAL.item = &ast.FuncCallExpr{
FnName: model.NewCIStr(yyS[yypt-5].item.(string)),
Args: []ast.ExprNode{yyS[yypt-1].item.(ast.ExprNode), nilVal, direction},
}
}
case 440:
{
yyVAL.item = &ast.FuncTrimExpr{
Str: yyS[yypt-1].item.(ast.ExprNode),
RemStr: yyS[yypt-3].item.(ast.ExprNode),
Direction: yyS[yypt-4].item.(ast.TrimDirectionType),
direction := ast.NewValueExpr(yyS[yypt-4].item)
yyVAL.item = &ast.FuncCallExpr{
FnName: model.NewCIStr(yyS[yypt-6].item.(string)),
Args: []ast.ExprNode{yyS[yypt-1].item.(ast.ExprNode), yyS[yypt-3].item.(ast.ExprNode), direction},
}
}
case 441:

View File

@ -2363,31 +2363,34 @@ FunctionCallNonKeyword:
}
| "TRIM" '(' Expression ')'
{
$$ = &ast.FuncTrimExpr{
Str: $3.(ast.ExprNode),
}
$$ = &ast.FuncCallExpr{
FnName: model.NewCIStr($1.(string)),
Args: []ast.ExprNode{$3.(ast.ExprNode)},
}
}
| "TRIM" '(' Expression "FROM" Expression ')'
{
$$ = &ast.FuncTrimExpr{
Str: $5.(ast.ExprNode),
RemStr: $3.(ast.ExprNode),
}
$$ = &ast.FuncCallExpr{
FnName: model.NewCIStr($1.(string)),
Args: []ast.ExprNode{$5.(ast.ExprNode), $3.(ast.ExprNode)},
}
}
| "TRIM" '(' TrimDirection "FROM" Expression ')'
{
$$ = &ast.FuncTrimExpr{
Str: $5.(ast.ExprNode),
Direction: $3.(ast.TrimDirectionType),
}
nilVal := ast.NewValueExpr(nil)
direction := ast.NewValueExpr($3)
$$ = &ast.FuncCallExpr{
FnName: model.NewCIStr($1.(string)),
Args: []ast.ExprNode{$5.(ast.ExprNode), nilVal, direction},
}
}
| "TRIM" '(' TrimDirection Expression "FROM" Expression ')'
{
$$ = &ast.FuncTrimExpr{
Str: $6.(ast.ExprNode),
RemStr: $4.(ast.ExprNode),
Direction: $3.(ast.TrimDirectionType),
}
direction := ast.NewValueExpr($3)
$$ = &ast.FuncCallExpr{
FnName: model.NewCIStr($1.(string)),
Args: []ast.ExprNode{$6.(ast.ExprNode),$4.(ast.ExprNode), direction},
}
}
| "UPPER" '(' Expression ')'
{