github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_string_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package memex
    15  
    16  import (
    17  	"fmt"
    18  	"strconv"
    19  	"strings"
    20  	"time"
    21  	"unicode/utf8"
    22  
    23  	. "github.com/whtcorpsinc/check"
    24  	"github.com/whtcorpsinc/errors"
    25  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    26  	"github.com/whtcorpsinc/BerolinaSQL/charset"
    27  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    28  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    29  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    30  	"github.com/whtcorpsinc/milevadb/types"
    31  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    32  	"github.com/whtcorpsinc/milevadb/soliton/defCauslate"
    33  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    34  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    35  )
    36  
    37  func (s *testEvaluatorSuite) TestLengthAndOctetLength(c *C) {
    38  	cases := []struct {
    39  		args     interface{}
    40  		expected int64
    41  		isNil    bool
    42  		getErr   bool
    43  	}{
    44  		{"abc", 3, false, false},
    45  		{"你好", 6, false, false},
    46  		{1, 1, false, false},
    47  		{3.14, 4, false, false},
    48  		{types.NewDecFromFloatForTest(123.123), 7, false, false},
    49  		{types.NewTime(types.FromGoTime(time.Now()), allegrosql.TypeDatetime, 6), 26, false, false},
    50  		{types.NewBinaryLiteralFromUint(0x01, -1), 1, false, false},
    51  		{types.Set{Value: 1, Name: "abc"}, 3, false, false},
    52  		{types.Duration{Duration: 12*time.Hour + 1*time.Minute + 1*time.Second, Fsp: types.DefaultFsp}, 8, false, false},
    53  		{nil, 0, true, false},
    54  		{errors.New("must error"), 0, false, true},
    55  	}
    56  
    57  	lengthMethods := []string{ast.Length, ast.OctetLength}
    58  	for _, lengthMethod := range lengthMethods {
    59  		for _, t := range cases {
    60  			f, err := newFunctionForTest(s.ctx, lengthMethod, s.primitiveValsToConstants([]interface{}{t.args})...)
    61  			c.Assert(err, IsNil)
    62  			d, err := f.Eval(chunk.Event{})
    63  			if t.getErr {
    64  				c.Assert(err, NotNil)
    65  			} else {
    66  				c.Assert(err, IsNil)
    67  				if t.isNil {
    68  					c.Assert(d.HoTT(), Equals, types.HoTTNull)
    69  				} else {
    70  					c.Assert(d.GetInt64(), Equals, t.expected)
    71  				}
    72  			}
    73  		}
    74  	}
    75  
    76  	_, err := funcs[ast.Length].getFunction(s.ctx, []Expression{NewZero()})
    77  	c.Assert(err, IsNil)
    78  }
    79  
    80  func (s *testEvaluatorSuite) TestASCII(c *C) {
    81  	cases := []struct {
    82  		args     interface{}
    83  		expected int64
    84  		isNil    bool
    85  		getErr   bool
    86  	}{
    87  		{"2", 50, false, false},
    88  		{2, 50, false, false},
    89  		{"23", 50, false, false},
    90  		{23, 50, false, false},
    91  		{2.3, 50, false, false},
    92  		{nil, 0, true, false},
    93  		{"", 0, false, false},
    94  		{"你好", 228, false, false},
    95  	}
    96  	for _, t := range cases {
    97  		f, err := newFunctionForTest(s.ctx, ast.ASCII, s.primitiveValsToConstants([]interface{}{t.args})...)
    98  		c.Assert(err, IsNil)
    99  
   100  		d, err := f.Eval(chunk.Event{})
   101  		if t.getErr {
   102  			c.Assert(err, NotNil)
   103  		} else {
   104  			c.Assert(err, IsNil)
   105  			if t.isNil {
   106  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   107  			} else {
   108  				c.Assert(d.GetInt64(), Equals, t.expected)
   109  			}
   110  		}
   111  	}
   112  	_, err := funcs[ast.Length].getFunction(s.ctx, []Expression{NewZero()})
   113  	c.Assert(err, IsNil)
   114  }
   115  
   116  func (s *testEvaluatorSuite) TestConcat(c *C) {
   117  	cases := []struct {
   118  		args    []interface{}
   119  		isNil   bool
   120  		getErr  bool
   121  		res     string
   122  		retType *types.FieldType
   123  	}{
   124  		{
   125  			[]interface{}{nil},
   126  			true, false, "",
   127  			&types.FieldType{Tp: allegrosql.TypeVarString, Flen: 0, Decimal: types.UnspecifiedLength, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin, Flag: allegrosql.BinaryFlag},
   128  		},
   129  		{
   130  			[]interface{}{"a", "b",
   131  				1, 2,
   132  				1.1, 1.2,
   133  				types.NewDecFromFloatForTest(1.1),
   134  				types.NewTime(types.FromDate(2000, 1, 1, 12, 01, 01, 0), allegrosql.TypeDatetime, types.DefaultFsp),
   135  				types.Duration{
   136  					Duration: 12*time.Hour + 1*time.Minute + 1*time.Second,
   137  					Fsp:      types.DefaultFsp},
   138  			},
   139  			false, false, "ab121.11.21.12000-01-01 12:01:0112:01:01",
   140  			&types.FieldType{Tp: allegrosql.TypeVarString, Flen: 40, Decimal: types.UnspecifiedLength, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin, Flag: allegrosql.BinaryFlag},
   141  		},
   142  		{
   143  			[]interface{}{"a", "b", nil, "c"},
   144  			true, false, "",
   145  			&types.FieldType{Tp: allegrosql.TypeVarString, Flen: 3, Decimal: types.UnspecifiedLength, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin, Flag: allegrosql.BinaryFlag},
   146  		},
   147  		{
   148  			[]interface{}{errors.New("must error")},
   149  			false, true, "",
   150  			&types.FieldType{Tp: allegrosql.TypeVarString, Flen: types.UnspecifiedLength, Decimal: types.UnspecifiedLength, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin, Flag: allegrosql.BinaryFlag},
   151  		},
   152  	}
   153  	fcName := ast.Concat
   154  	for _, t := range cases {
   155  		f, err := newFunctionForTest(s.ctx, fcName, s.primitiveValsToConstants(t.args)...)
   156  		c.Assert(err, IsNil)
   157  		v, err := f.Eval(chunk.Event{})
   158  		if t.getErr {
   159  			c.Assert(err, NotNil)
   160  		} else {
   161  			c.Assert(err, IsNil)
   162  			if t.isNil {
   163  				c.Assert(v.HoTT(), Equals, types.HoTTNull)
   164  			} else {
   165  				c.Assert(v.GetString(), Equals, t.res)
   166  			}
   167  		}
   168  	}
   169  }
   170  
   171  func (s *testEvaluatorSuite) TestConcatSig(c *C) {
   172  	defCausTypes := []*types.FieldType{
   173  		{Tp: allegrosql.TypeVarchar},
   174  		{Tp: allegrosql.TypeVarchar},
   175  	}
   176  	resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000}
   177  	args := []Expression{
   178  		&DeferredCauset{Index: 0, RetType: defCausTypes[0]},
   179  		&DeferredCauset{Index: 1, RetType: defCausTypes[1]},
   180  	}
   181  	base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
   182  	concat := &builtinConcatSig{base, 5}
   183  
   184  	cases := []struct {
   185  		args     []interface{}
   186  		warnings int
   187  		res      string
   188  	}{
   189  		{[]interface{}{"a", "b"}, 0, "ab"},
   190  		{[]interface{}{"aaa", "bbb"}, 1, ""},
   191  		{[]interface{}{"中", "a"}, 0, "中a"},
   192  		{[]interface{}{"中文", "a"}, 2, ""},
   193  	}
   194  
   195  	for _, t := range cases {
   196  		input := chunk.NewChunkWithCapacity(defCausTypes, 10)
   197  		input.AppendString(0, t.args[0].(string))
   198  		input.AppendString(1, t.args[1].(string))
   199  
   200  		res, isNull, err := concat.evalString(input.GetEvent(0))
   201  		c.Assert(res, Equals, t.res)
   202  		c.Assert(err, IsNil)
   203  		if t.warnings == 0 {
   204  			c.Assert(isNull, IsFalse)
   205  		} else {
   206  			c.Assert(isNull, IsTrue)
   207  			warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
   208  			c.Assert(warnings, HasLen, t.warnings)
   209  			lastWarn := warnings[len(warnings)-1]
   210  			c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue)
   211  		}
   212  	}
   213  }
   214  
   215  func (s *testEvaluatorSuite) TestConcatWS(c *C) {
   216  	cases := []struct {
   217  		args     []interface{}
   218  		isNil    bool
   219  		getErr   bool
   220  		expected string
   221  	}{
   222  		{
   223  			[]interface{}{nil, nil},
   224  			true, false, "",
   225  		},
   226  		{
   227  			[]interface{}{nil, "a", "b"},
   228  			true, false, "",
   229  		},
   230  		{
   231  			[]interface{}{",", "a", "b", "hello", `$^%`},
   232  			false, false,
   233  			`a,b,hello,$^%`,
   234  		},
   235  		{
   236  			[]interface{}{"|", "a", nil, "b", "c"},
   237  			false, false,
   238  			"a|b|c",
   239  		},
   240  		{
   241  			[]interface{}{",", "a", ",", "b", "c"},
   242  			false, false,
   243  			"a,,,b,c",
   244  		},
   245  		{
   246  			[]interface{}{errors.New("must error"), "a", "b"},
   247  			false, true, "",
   248  		},
   249  		{
   250  			[]interface{}{",", "a", "b", 1, 2, 1.1, 0.11,
   251  				types.NewDecFromFloatForTest(1.1),
   252  				types.NewTime(types.FromDate(2000, 1, 1, 12, 01, 01, 0), allegrosql.TypeDatetime, types.DefaultFsp),
   253  				types.Duration{
   254  					Duration: 12*time.Hour + 1*time.Minute + 1*time.Second,
   255  					Fsp:      types.DefaultFsp},
   256  			},
   257  			false, false, "a,b,1,2,1.1,0.11,1.1,2000-01-01 12:01:01,12:01:01",
   258  		},
   259  	}
   260  
   261  	fcName := ast.ConcatWS
   262  	// ERROR 1582 (42000): Incorrect parameter count in the call to native function 'concat_ws'
   263  	_, err := newFunctionForTest(s.ctx, fcName, s.primitiveValsToConstants([]interface{}{nil})...)
   264  	c.Assert(err, NotNil)
   265  
   266  	for _, t := range cases {
   267  		f, err := newFunctionForTest(s.ctx, fcName, s.primitiveValsToConstants(t.args)...)
   268  		c.Assert(err, IsNil)
   269  		val, err1 := f.Eval(chunk.Event{})
   270  		if t.getErr {
   271  			c.Assert(err1, NotNil)
   272  		} else {
   273  			c.Assert(err1, IsNil)
   274  			if t.isNil {
   275  				c.Assert(val.HoTT(), Equals, types.HoTTNull)
   276  			} else {
   277  				c.Assert(val.GetString(), Equals, t.expected)
   278  			}
   279  		}
   280  	}
   281  
   282  	_, err = funcs[ast.ConcatWS].getFunction(s.ctx, s.primitiveValsToConstants([]interface{}{nil, nil}))
   283  	c.Assert(err, IsNil)
   284  }
   285  
   286  func (s *testEvaluatorSuite) TestConcatWSSig(c *C) {
   287  	defCausTypes := []*types.FieldType{
   288  		{Tp: allegrosql.TypeVarchar},
   289  		{Tp: allegrosql.TypeVarchar},
   290  		{Tp: allegrosql.TypeVarchar},
   291  	}
   292  	resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000}
   293  	args := []Expression{
   294  		&DeferredCauset{Index: 0, RetType: defCausTypes[0]},
   295  		&DeferredCauset{Index: 1, RetType: defCausTypes[1]},
   296  		&DeferredCauset{Index: 2, RetType: defCausTypes[2]},
   297  	}
   298  	base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
   299  	concat := &builtinConcatWSSig{base, 6}
   300  
   301  	cases := []struct {
   302  		args     []interface{}
   303  		warnings int
   304  		res      string
   305  	}{
   306  		{[]interface{}{",", "a", "b"}, 0, "a,b"},
   307  		{[]interface{}{",", "aaa", "bbb"}, 1, ""},
   308  		{[]interface{}{",", "中", "a"}, 0, "中,a"},
   309  		{[]interface{}{",", "中文", "a"}, 2, ""},
   310  	}
   311  
   312  	for _, t := range cases {
   313  		input := chunk.NewChunkWithCapacity(defCausTypes, 10)
   314  		input.AppendString(0, t.args[0].(string))
   315  		input.AppendString(1, t.args[1].(string))
   316  		input.AppendString(2, t.args[2].(string))
   317  
   318  		res, isNull, err := concat.evalString(input.GetEvent(0))
   319  		c.Assert(res, Equals, t.res)
   320  		c.Assert(err, IsNil)
   321  		if t.warnings == 0 {
   322  			c.Assert(isNull, IsFalse)
   323  		} else {
   324  			c.Assert(isNull, IsTrue)
   325  			warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
   326  			c.Assert(warnings, HasLen, t.warnings)
   327  			lastWarn := warnings[len(warnings)-1]
   328  			c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue)
   329  		}
   330  	}
   331  }
   332  
   333  func (s *testEvaluatorSuite) TestLeft(c *C) {
   334  	stmtCtx := s.ctx.GetStochastikVars().StmtCtx
   335  	origin := stmtCtx.IgnoreTruncate
   336  	stmtCtx.IgnoreTruncate = true
   337  	defer func() {
   338  		stmtCtx.IgnoreTruncate = origin
   339  	}()
   340  
   341  	cases := []struct {
   342  		args   []interface{}
   343  		isNil  bool
   344  		getErr bool
   345  		res    string
   346  	}{
   347  		{[]interface{}{"abcde", 3}, false, false, "abc"},
   348  		{[]interface{}{"abcde", 0}, false, false, ""},
   349  		{[]interface{}{"abcde", 1.2}, false, false, "a"},
   350  		{[]interface{}{"abcde", 1.9}, false, false, "ab"},
   351  		{[]interface{}{"abcde", -1}, false, false, ""},
   352  		{[]interface{}{"abcde", 100}, false, false, "abcde"},
   353  		{[]interface{}{"abcde", nil}, true, false, ""},
   354  		{[]interface{}{nil, 3}, true, false, ""},
   355  		{[]interface{}{"abcde", "3"}, false, false, "abc"},
   356  		{[]interface{}{"abcde", "a"}, false, false, ""},
   357  		{[]interface{}{1234, 3}, false, false, "123"},
   358  		{[]interface{}{12.34, 3}, false, false, "12."},
   359  		{[]interface{}{types.NewBinaryLiteralFromUint(0x0102, -1), 1}, false, false, string([]byte{0x01})},
   360  		{[]interface{}{errors.New("must err"), 0}, false, true, ""},
   361  	}
   362  	for _, t := range cases {
   363  		f, err := newFunctionForTest(s.ctx, ast.Left, s.primitiveValsToConstants(t.args)...)
   364  		c.Assert(err, IsNil)
   365  		v, err := f.Eval(chunk.Event{})
   366  		if t.getErr {
   367  			c.Assert(err, NotNil)
   368  		} else {
   369  			c.Assert(err, IsNil)
   370  			if t.isNil {
   371  				c.Assert(v.HoTT(), Equals, types.HoTTNull)
   372  			} else {
   373  				c.Assert(v.GetString(), Equals, t.res)
   374  			}
   375  		}
   376  	}
   377  
   378  	_, err := funcs[ast.Left].getFunction(s.ctx, []Expression{varcharCon, int8Con})
   379  	c.Assert(err, IsNil)
   380  }
   381  
   382  func (s *testEvaluatorSuite) TestRight(c *C) {
   383  	stmtCtx := s.ctx.GetStochastikVars().StmtCtx
   384  	origin := stmtCtx.IgnoreTruncate
   385  	stmtCtx.IgnoreTruncate = true
   386  	defer func() {
   387  		stmtCtx.IgnoreTruncate = origin
   388  	}()
   389  
   390  	cases := []struct {
   391  		args   []interface{}
   392  		isNil  bool
   393  		getErr bool
   394  		res    string
   395  	}{
   396  		{[]interface{}{"abcde", 3}, false, false, "cde"},
   397  		{[]interface{}{"abcde", 0}, false, false, ""},
   398  		{[]interface{}{"abcde", 1.2}, false, false, "e"},
   399  		{[]interface{}{"abcde", 1.9}, false, false, "de"},
   400  		{[]interface{}{"abcde", -1}, false, false, ""},
   401  		{[]interface{}{"abcde", 100}, false, false, "abcde"},
   402  		{[]interface{}{"abcde", nil}, true, false, ""},
   403  		{[]interface{}{nil, 1}, true, false, ""},
   404  		{[]interface{}{"abcde", "3"}, false, false, "cde"},
   405  		{[]interface{}{"abcde", "a"}, false, false, ""},
   406  		{[]interface{}{1234, 3}, false, false, "234"},
   407  		{[]interface{}{12.34, 3}, false, false, ".34"},
   408  		{[]interface{}{types.NewBinaryLiteralFromUint(0x0102, -1), 1}, false, false, string([]byte{0x02})},
   409  		{[]interface{}{errors.New("must err"), 0}, false, true, ""},
   410  	}
   411  	for _, t := range cases {
   412  		f, err := newFunctionForTest(s.ctx, ast.Right, s.primitiveValsToConstants(t.args)...)
   413  		c.Assert(err, IsNil)
   414  		v, err := f.Eval(chunk.Event{})
   415  		if t.getErr {
   416  			c.Assert(err, NotNil)
   417  		} else {
   418  			c.Assert(err, IsNil)
   419  			if t.isNil {
   420  				c.Assert(v.HoTT(), Equals, types.HoTTNull)
   421  			} else {
   422  				c.Assert(v.GetString(), Equals, t.res)
   423  			}
   424  		}
   425  	}
   426  
   427  	_, err := funcs[ast.Right].getFunction(s.ctx, []Expression{varcharCon, int8Con})
   428  	c.Assert(err, IsNil)
   429  }
   430  
   431  func (s *testEvaluatorSuite) TestRepeat(c *C) {
   432  	args := []interface{}{"a", int64(2)}
   433  	fc := funcs[ast.Repeat]
   434  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...)))
   435  	c.Assert(err, IsNil)
   436  	v, err := evalBuiltinFunc(f, chunk.Event{})
   437  	c.Assert(err, IsNil)
   438  	c.Assert(v.GetString(), Equals, "aa")
   439  
   440  	args = []interface{}{"a", uint64(2)}
   441  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...)))
   442  	c.Assert(err, IsNil)
   443  	v, err = evalBuiltinFunc(f, chunk.Event{})
   444  	c.Assert(err, IsNil)
   445  	c.Assert(v.GetString(), Equals, "aa")
   446  
   447  	args = []interface{}{"a", uint64(16777217)}
   448  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...)))
   449  	c.Assert(err, IsNil)
   450  	v, err = evalBuiltinFunc(f, chunk.Event{})
   451  	c.Assert(err, IsNil)
   452  	c.Assert(v.IsNull(), IsTrue)
   453  
   454  	args = []interface{}{"a", uint64(16777216)}
   455  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...)))
   456  	c.Assert(err, IsNil)
   457  	v, err = evalBuiltinFunc(f, chunk.Event{})
   458  	c.Assert(err, IsNil)
   459  	c.Assert(v.IsNull(), IsFalse)
   460  
   461  	args = []interface{}{"a", int64(-1)}
   462  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...)))
   463  	c.Assert(err, IsNil)
   464  	v, err = evalBuiltinFunc(f, chunk.Event{})
   465  	c.Assert(err, IsNil)
   466  	c.Assert(v.GetString(), Equals, "")
   467  
   468  	args = []interface{}{"a", int64(0)}
   469  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...)))
   470  	c.Assert(err, IsNil)
   471  	v, err = evalBuiltinFunc(f, chunk.Event{})
   472  	c.Assert(err, IsNil)
   473  	c.Assert(v.GetString(), Equals, "")
   474  
   475  	args = []interface{}{"a", uint64(0)}
   476  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...)))
   477  	c.Assert(err, IsNil)
   478  	v, err = evalBuiltinFunc(f, chunk.Event{})
   479  	c.Assert(err, IsNil)
   480  	c.Assert(v.GetString(), Equals, "")
   481  }
   482  
   483  func (s *testEvaluatorSuite) TestRepeatSig(c *C) {
   484  	defCausTypes := []*types.FieldType{
   485  		{Tp: allegrosql.TypeVarchar},
   486  		{Tp: allegrosql.TypeLonglong},
   487  	}
   488  	resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000}
   489  	args := []Expression{
   490  		&DeferredCauset{Index: 0, RetType: defCausTypes[0]},
   491  		&DeferredCauset{Index: 1, RetType: defCausTypes[1]},
   492  	}
   493  	base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
   494  	repeat := &builtinRepeatSig{base, 1000}
   495  
   496  	cases := []struct {
   497  		args    []interface{}
   498  		warning int
   499  		res     string
   500  	}{
   501  		{[]interface{}{"a", int64(6)}, 0, "aaaaaa"},
   502  		{[]interface{}{"a", int64(10001)}, 1, ""},
   503  		{[]interface{}{"毅", int64(6)}, 0, "毅毅毅毅毅毅"},
   504  		{[]interface{}{"毅", int64(334)}, 2, ""},
   505  	}
   506  
   507  	for _, t := range cases {
   508  		input := chunk.NewChunkWithCapacity(defCausTypes, 10)
   509  		input.AppendString(0, t.args[0].(string))
   510  		input.AppendInt64(1, t.args[1].(int64))
   511  
   512  		res, isNull, err := repeat.evalString(input.GetEvent(0))
   513  		c.Assert(res, Equals, t.res)
   514  		c.Assert(err, IsNil)
   515  		if t.warning == 0 {
   516  			c.Assert(isNull, IsFalse)
   517  		} else {
   518  			c.Assert(isNull, IsTrue)
   519  			c.Assert(err, IsNil)
   520  			warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
   521  			c.Assert(len(warnings), Equals, t.warning)
   522  			lastWarn := warnings[len(warnings)-1]
   523  			c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue)
   524  		}
   525  	}
   526  }
   527  
   528  func (s *testEvaluatorSuite) TestLower(c *C) {
   529  	cases := []struct {
   530  		args   []interface{}
   531  		isNil  bool
   532  		getErr bool
   533  		res    string
   534  	}{
   535  		{[]interface{}{nil}, true, false, ""},
   536  		{[]interface{}{"ab"}, false, false, "ab"},
   537  		{[]interface{}{1}, false, false, "1"},
   538  		{[]interface{}{"one week’s time TEST"}, false, false, "one week’s time test"},
   539  		{[]interface{}{"one week's time TEST"}, false, false, "one week's time test"},
   540  		{[]interface{}{"ABC测试DEF"}, false, false, "abc测试def"},
   541  		{[]interface{}{"ABCテストDEF"}, false, false, "abcテストdef"},
   542  	}
   543  
   544  	for _, t := range cases {
   545  		f, err := newFunctionForTest(s.ctx, ast.Lower, s.primitiveValsToConstants(t.args)...)
   546  		c.Assert(err, IsNil)
   547  		v, err := f.Eval(chunk.Event{})
   548  		if t.getErr {
   549  			c.Assert(err, NotNil)
   550  		} else {
   551  			c.Assert(err, IsNil)
   552  			if t.isNil {
   553  				c.Assert(v.HoTT(), Equals, types.HoTTNull)
   554  			} else {
   555  				c.Assert(v.GetString(), Equals, t.res)
   556  			}
   557  		}
   558  	}
   559  
   560  	_, err := funcs[ast.Lower].getFunction(s.ctx, []Expression{varcharCon})
   561  	c.Assert(err, IsNil)
   562  }
   563  
   564  func (s *testEvaluatorSuite) TestUpper(c *C) {
   565  	cases := []struct {
   566  		args   []interface{}
   567  		isNil  bool
   568  		getErr bool
   569  		res    string
   570  	}{
   571  		{[]interface{}{nil}, true, false, ""},
   572  		{[]interface{}{"ab"}, false, false, "ab"},
   573  		{[]interface{}{1}, false, false, "1"},
   574  		{[]interface{}{"one week’s time TEST"}, false, false, "ONE WEEK’S TIME TEST"},
   575  		{[]interface{}{"one week's time TEST"}, false, false, "ONE WEEK'S TIME TEST"},
   576  		{[]interface{}{"abc测试def"}, false, false, "ABC测试DEF"},
   577  		{[]interface{}{"abcテストdef"}, false, false, "ABCテストDEF"},
   578  	}
   579  
   580  	for _, t := range cases {
   581  		f, err := newFunctionForTest(s.ctx, ast.Upper, s.primitiveValsToConstants(t.args)...)
   582  		c.Assert(err, IsNil)
   583  		v, err := f.Eval(chunk.Event{})
   584  		if t.getErr {
   585  			c.Assert(err, NotNil)
   586  		} else {
   587  			c.Assert(err, IsNil)
   588  			if t.isNil {
   589  				c.Assert(v.HoTT(), Equals, types.HoTTNull)
   590  			} else {
   591  				c.Assert(v.GetString(), Equals, strings.ToUpper(t.res))
   592  			}
   593  		}
   594  	}
   595  
   596  	_, err := funcs[ast.Upper].getFunction(s.ctx, []Expression{varcharCon})
   597  	c.Assert(err, IsNil)
   598  }
   599  
   600  func (s *testEvaluatorSuite) TestReverse(c *C) {
   601  	fc := funcs[ast.Reverse]
   602  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   603  	c.Assert(err, IsNil)
   604  	d, err := evalBuiltinFunc(f, chunk.Event{})
   605  	c.Assert(err, IsNil)
   606  	c.Assert(d.HoTT(), Equals, types.HoTTNull)
   607  
   608  	tbl := []struct {
   609  		Input  interface{}
   610  		Expect string
   611  	}{
   612  		{"abc", "cba"},
   613  		{"LIKE", "EKIL"},
   614  		{123, "321"},
   615  		{"", ""},
   616  	}
   617  
   618  	dtbl := tblToDtbl(tbl)
   619  
   620  	for _, t := range dtbl {
   621  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   622  		c.Assert(err, IsNil)
   623  		c.Assert(f, NotNil)
   624  		d, err = evalBuiltinFunc(f, chunk.Event{})
   625  		c.Assert(err, IsNil)
   626  		c.Assert(d, solitonutil.CausetEquals, t["Expect"][0])
   627  	}
   628  }
   629  
   630  func (s *testEvaluatorSuite) TestStrcmp(c *C) {
   631  	cases := []struct {
   632  		args   []interface{}
   633  		isNil  bool
   634  		getErr bool
   635  		res    int64
   636  	}{
   637  		{[]interface{}{"123", "123"}, false, false, 0},
   638  		{[]interface{}{"123", "1"}, false, false, 1},
   639  		{[]interface{}{"1", "123"}, false, false, -1},
   640  		{[]interface{}{"123", "45"}, false, false, -1},
   641  		{[]interface{}{123, "123"}, false, false, 0},
   642  		{[]interface{}{"12.34", 12.34}, false, false, 0},
   643  		{[]interface{}{nil, "123"}, true, false, 0},
   644  		{[]interface{}{"123", nil}, true, false, 0},
   645  		{[]interface{}{"", "123"}, false, false, -1},
   646  		{[]interface{}{"123", ""}, false, false, 1},
   647  		{[]interface{}{"", ""}, false, false, 0},
   648  		{[]interface{}{"", nil}, true, false, 0},
   649  		{[]interface{}{nil, ""}, true, false, 0},
   650  		{[]interface{}{nil, nil}, true, false, 0},
   651  		{[]interface{}{"123", errors.New("must err")}, false, true, 0},
   652  	}
   653  	for _, t := range cases {
   654  		f, err := newFunctionForTest(s.ctx, ast.Strcmp, s.primitiveValsToConstants(t.args)...)
   655  		c.Assert(err, IsNil)
   656  		d, err := f.Eval(chunk.Event{})
   657  		if t.getErr {
   658  			c.Assert(err, NotNil)
   659  		} else {
   660  			c.Assert(err, IsNil)
   661  			if t.isNil {
   662  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   663  			} else {
   664  				c.Assert(d.GetInt64(), Equals, t.res)
   665  			}
   666  		}
   667  	}
   668  }
   669  
   670  func (s *testEvaluatorSuite) TestReplace(c *C) {
   671  	cases := []struct {
   672  		args   []interface{}
   673  		isNil  bool
   674  		getErr bool
   675  		res    string
   676  		flen   int
   677  	}{
   678  		{[]interface{}{"www.allegrosql.com", "allegrosql", "whtcorpsinc"}, false, false, "www.whtcorpsinc.com", 17},
   679  		{[]interface{}{"www.allegrosql.com", "w", 1}, false, false, "111.allegrosql.com", 260},
   680  		{[]interface{}{1234, 2, 55}, false, false, "15534", 20},
   681  		{[]interface{}{"", "a", "b"}, false, false, "", 0},
   682  		{[]interface{}{"abc", "", "d"}, false, false, "abc", 3},
   683  		{[]interface{}{"aaa", "a", ""}, false, false, "", 3},
   684  		{[]interface{}{nil, "a", "b"}, true, false, "", 0},
   685  		{[]interface{}{"a", nil, "b"}, true, false, "", 1},
   686  		{[]interface{}{"a", "b", nil}, true, false, "", 1},
   687  		{[]interface{}{errors.New("must err"), "a", "b"}, false, true, "", -1},
   688  	}
   689  	for i, t := range cases {
   690  		f, err := newFunctionForTest(s.ctx, ast.Replace, s.primitiveValsToConstants(t.args)...)
   691  		c.Assert(err, IsNil, Commentf("test %v", i))
   692  		c.Assert(f.GetType().Flen, Equals, t.flen, Commentf("test %v", i))
   693  		d, err := f.Eval(chunk.Event{})
   694  		if t.getErr {
   695  			c.Assert(err, NotNil, Commentf("test %v", i))
   696  		} else {
   697  			c.Assert(err, IsNil, Commentf("test %v", i))
   698  			if t.isNil {
   699  				c.Assert(d.HoTT(), Equals, types.HoTTNull, Commentf("test %v", i))
   700  			} else {
   701  				c.Assert(d.GetString(), Equals, t.res, Commentf("test %v", i))
   702  			}
   703  		}
   704  	}
   705  
   706  	_, err := funcs[ast.Replace].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()})
   707  	c.Assert(err, IsNil)
   708  }
   709  
   710  func (s *testEvaluatorSuite) TestSubstring(c *C) {
   711  	cases := []struct {
   712  		args   []interface{}
   713  		isNil  bool
   714  		getErr bool
   715  		res    string
   716  	}{
   717  		{[]interface{}{"Quadratically", 5}, false, false, "ratically"},
   718  		{[]interface{}{"Sakila", 1}, false, false, "Sakila"},
   719  		{[]interface{}{"Sakila", 2}, false, false, "akila"},
   720  		{[]interface{}{"Sakila", -3}, false, false, "ila"},
   721  		{[]interface{}{"Sakila", 0}, false, false, ""},
   722  		{[]interface{}{"Sakila", 100}, false, false, ""},
   723  		{[]interface{}{"Sakila", -100}, false, false, ""},
   724  		{[]interface{}{"Quadratically", 5, 6}, false, false, "ratica"},
   725  		{[]interface{}{"Sakila", -5, 3}, false, false, "aki"},
   726  		{[]interface{}{"Sakila", 2, 0}, false, false, ""},
   727  		{[]interface{}{"Sakila", 2, -1}, false, false, ""},
   728  		{[]interface{}{"Sakila", 2, 100}, false, false, "akila"},
   729  		{[]interface{}{nil, 2, 3}, true, false, ""},
   730  		{[]interface{}{"Sakila", nil, 3}, true, false, ""},
   731  		{[]interface{}{"Sakila", 2, nil}, true, false, ""},
   732  		{[]interface{}{errors.New("must error"), 2, 3}, false, true, ""},
   733  	}
   734  	for _, t := range cases {
   735  		f, err := newFunctionForTest(s.ctx, ast.Substring, s.primitiveValsToConstants(t.args)...)
   736  		c.Assert(err, IsNil)
   737  		d, err := f.Eval(chunk.Event{})
   738  		if t.getErr {
   739  			c.Assert(err, NotNil)
   740  		} else {
   741  			c.Assert(err, IsNil)
   742  			if t.isNil {
   743  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   744  			} else {
   745  				c.Assert(d.GetString(), Equals, t.res)
   746  			}
   747  		}
   748  	}
   749  
   750  	_, err := funcs[ast.Substring].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()})
   751  	c.Assert(err, IsNil)
   752  
   753  	_, err = funcs[ast.Substring].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
   754  	c.Assert(err, IsNil)
   755  }
   756  
   757  func (s *testEvaluatorSuite) TestConvert(c *C) {
   758  	tbl := []struct {
   759  		str           interface{}
   760  		cs            string
   761  		result        string
   762  		hasBinaryFlag bool
   763  	}{
   764  		{"haha", "utf8", "haha", false},
   765  		{"haha", "ascii", "haha", false},
   766  		{"haha", "binary", "haha", true},
   767  		{"haha", "bInAry", "haha", true},
   768  		{types.NewBinaryLiteralFromUint(0x7e, -1), "BiNarY", "~", true},
   769  		{types.NewBinaryLiteralFromUint(0xe4b8ade696870a, -1), "uTf8", "中文\n", false},
   770  	}
   771  	for _, v := range tbl {
   772  		fc := funcs[ast.Convert]
   773  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(v.str, v.cs)))
   774  		c.Assert(err, IsNil)
   775  		c.Assert(f, NotNil)
   776  		retType := f.getRetTp()
   777  		c.Assert(retType.Charset, Equals, strings.ToLower(v.cs))
   778  		defCauslate, err := charset.GetDefaultDefCauslation(strings.ToLower(v.cs))
   779  		c.Assert(err, IsNil)
   780  		c.Assert(retType.DefCauslate, Equals, defCauslate)
   781  		c.Assert(allegrosql.HasBinaryFlag(retType.Flag), Equals, v.hasBinaryFlag)
   782  
   783  		r, err := evalBuiltinFunc(f, chunk.Event{})
   784  		c.Assert(err, IsNil)
   785  		c.Assert(r.HoTT(), Equals, types.HoTTString)
   786  		c.Assert(r.GetString(), Equals, v.result)
   787  	}
   788  
   789  	// Test case for getFunction() error
   790  	errTbl := []struct {
   791  		str interface{}
   792  		cs  string
   793  		err string
   794  	}{
   795  		{"haha", "wrongcharset", "[memex:1115]Unknown character set: 'wrongcharset'"},
   796  		{"haha", "cp866", "[memex:1115]Unknown character set: 'cp866'"},
   797  	}
   798  	for _, v := range errTbl {
   799  		fc := funcs[ast.Convert]
   800  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(v.str, v.cs)))
   801  		c.Assert(err.Error(), Equals, v.err)
   802  		c.Assert(f, IsNil)
   803  	}
   804  
   805  	// Test wrong charset while evaluating.
   806  	fc := funcs[ast.Convert]
   807  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets("haha", "utf8")))
   808  	c.Assert(err, IsNil)
   809  	c.Assert(f, NotNil)
   810  	wrongFunction := f.(*builtinConvertSig)
   811  	wrongFunction.tp.Charset = "wrongcharset"
   812  	_, err = evalBuiltinFunc(wrongFunction, chunk.Event{})
   813  	c.Assert(err.Error(), Equals, "[memex:1115]Unknown character set: 'wrongcharset'")
   814  }
   815  
   816  func (s *testEvaluatorSuite) TestSubstringIndex(c *C) {
   817  	cases := []struct {
   818  		args   []interface{}
   819  		isNil  bool
   820  		getErr bool
   821  		res    string
   822  	}{
   823  		{[]interface{}{"www.whtcorpsinc.com", ".", 2}, false, false, "www.whtcorpsinc"},
   824  		{[]interface{}{"www.whtcorpsinc.com", ".", -2}, false, false, "whtcorpsinc.com"},
   825  		{[]interface{}{"www.whtcorpsinc.com", ".", 0}, false, false, ""},
   826  		{[]interface{}{"www.whtcorpsinc.com", ".", 100}, false, false, "www.whtcorpsinc.com"},
   827  		{[]interface{}{"www.whtcorpsinc.com", ".", -100}, false, false, "www.whtcorpsinc.com"},
   828  		{[]interface{}{"www.whtcorpsinc.com", "d", 0}, false, false, ""},
   829  		{[]interface{}{"www.whtcorpsinc.com", "d", 1}, false, false, "www.whtcorpsinc.com"},
   830  		{[]interface{}{"www.whtcorpsinc.com", "d", -1}, false, false, "www.whtcorpsinc.com"},
   831  		{[]interface{}{"www.whtcorpsinc.com", "", 0}, false, false, ""},
   832  		{[]interface{}{"www.whtcorpsinc.com", "", 1}, false, false, ""},
   833  		{[]interface{}{"www.whtcorpsinc.com", "", -1}, false, false, ""},
   834  		{[]interface{}{"", ".", 0}, false, false, ""},
   835  		{[]interface{}{"", ".", 1}, false, false, ""},
   836  		{[]interface{}{"", ".", -1}, false, false, ""},
   837  		{[]interface{}{nil, ".", 1}, true, false, ""},
   838  		{[]interface{}{"www.whtcorpsinc.com", nil, 1}, true, false, ""},
   839  		{[]interface{}{"www.whtcorpsinc.com", ".", nil}, true, false, ""},
   840  		{[]interface{}{errors.New("must error"), ".", 1}, false, true, ""},
   841  	}
   842  	for _, t := range cases {
   843  		f, err := newFunctionForTest(s.ctx, ast.SubstringIndex, s.primitiveValsToConstants(t.args)...)
   844  		c.Assert(err, IsNil)
   845  		d, err := f.Eval(chunk.Event{})
   846  		if t.getErr {
   847  			c.Assert(err, NotNil)
   848  		} else {
   849  			c.Assert(err, IsNil)
   850  			if t.isNil {
   851  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   852  			} else {
   853  				c.Assert(d.GetString(), Equals, t.res)
   854  			}
   855  		}
   856  	}
   857  
   858  	_, err := funcs[ast.SubstringIndex].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()})
   859  	c.Assert(err, IsNil)
   860  }
   861  
   862  func (s *testEvaluatorSuite) TestSpace(c *C) {
   863  	stmtCtx := s.ctx.GetStochastikVars().StmtCtx
   864  	origin := stmtCtx.IgnoreTruncate
   865  	stmtCtx.IgnoreTruncate = true
   866  	defer func() {
   867  		stmtCtx.IgnoreTruncate = origin
   868  	}()
   869  
   870  	cases := []struct {
   871  		arg    interface{}
   872  		isNil  bool
   873  		getErr bool
   874  		res    string
   875  	}{
   876  		{0, false, false, ""},
   877  		{3, false, false, "   "},
   878  		{allegrosql.MaxBlobWidth + 1, true, false, ""},
   879  		{-1, false, false, ""},
   880  		{"abc", false, false, ""},
   881  		{"3", false, false, "   "},
   882  		{1.2, false, false, " "},
   883  		{1.9, false, false, "  "},
   884  		{nil, true, false, ""},
   885  		{errors.New("must error"), false, true, ""},
   886  	}
   887  	for _, t := range cases {
   888  		f, err := newFunctionForTest(s.ctx, ast.Space, s.primitiveValsToConstants([]interface{}{t.arg})...)
   889  		c.Assert(err, IsNil)
   890  		d, err := f.Eval(chunk.Event{})
   891  		if t.getErr {
   892  			c.Assert(err, NotNil)
   893  		} else {
   894  			c.Assert(err, IsNil)
   895  			if t.isNil {
   896  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   897  			} else {
   898  				c.Assert(d.GetString(), Equals, t.res)
   899  			}
   900  		}
   901  	}
   902  
   903  	_, err := funcs[ast.Space].getFunction(s.ctx, []Expression{NewZero()})
   904  	c.Assert(err, IsNil)
   905  }
   906  
   907  func (s *testEvaluatorSuite) TestSpaceSig(c *C) {
   908  	defCausTypes := []*types.FieldType{
   909  		{Tp: allegrosql.TypeLonglong},
   910  	}
   911  	resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000}
   912  	args := []Expression{
   913  		&DeferredCauset{Index: 0, RetType: defCausTypes[0]},
   914  	}
   915  	base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
   916  	space := &builtinSpaceSig{base, 1000}
   917  	input := chunk.NewChunkWithCapacity(defCausTypes, 10)
   918  	input.AppendInt64(0, 6)
   919  	input.AppendInt64(0, 1001)
   920  	res, isNull, err := space.evalString(input.GetEvent(0))
   921  	c.Assert(res, Equals, "      ")
   922  	c.Assert(isNull, IsFalse)
   923  	c.Assert(err, IsNil)
   924  	res, isNull, err = space.evalString(input.GetEvent(1))
   925  	c.Assert(res, Equals, "")
   926  	c.Assert(isNull, IsTrue)
   927  	c.Assert(err, IsNil)
   928  	warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
   929  	c.Assert(len(warnings), Equals, 1)
   930  	lastWarn := warnings[len(warnings)-1]
   931  	c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue, Commentf("err %v", lastWarn.Err))
   932  }
   933  
   934  func (s *testEvaluatorSuite) TestLocate(c *C) {
   935  	// 1. Test LOCATE without binary input.
   936  	tbl := []struct {
   937  		Args []interface{}
   938  		Want interface{}
   939  	}{
   940  		{[]interface{}{"bar", "foobarbar"}, 4},
   941  		{[]interface{}{"xbar", "foobar"}, 0},
   942  		{[]interface{}{"", "foobar"}, 1},
   943  		{[]interface{}{"foobar", ""}, 0},
   944  		{[]interface{}{"", ""}, 1},
   945  		{[]interface{}{"好世", "你好世界"}, 2},
   946  		{[]interface{}{"界面", "你好世界"}, 0},
   947  		{[]interface{}{"b", "中a英b文"}, 4},
   948  		{[]interface{}{"bAr", "foobArbar"}, 4},
   949  		{[]interface{}{nil, "foobar"}, nil},
   950  		{[]interface{}{"bar", nil}, nil},
   951  		{[]interface{}{"bar", "foobarbar", 5}, 7},
   952  		{[]interface{}{"xbar", "foobar", 1}, 0},
   953  		{[]interface{}{"", "foobar", 2}, 2},
   954  		{[]interface{}{"foobar", "", 1}, 0},
   955  		{[]interface{}{"", "", 2}, 0},
   956  		{[]interface{}{"A", "大A写的A", 0}, 0},
   957  		{[]interface{}{"A", "大A写的A", 1}, 2},
   958  		{[]interface{}{"A", "大A写的A", 2}, 2},
   959  		{[]interface{}{"A", "大A写的A", 3}, 5},
   960  		{[]interface{}{"BaR", "foobarBaR", 5}, 7},
   961  		{[]interface{}{nil, nil}, nil},
   962  		{[]interface{}{"", nil}, nil},
   963  		{[]interface{}{nil, ""}, nil},
   964  		{[]interface{}{nil, nil, 1}, nil},
   965  		{[]interface{}{"", nil, 1}, nil},
   966  		{[]interface{}{nil, "", 1}, nil},
   967  		{[]interface{}{"foo", nil, -1}, nil},
   968  		{[]interface{}{nil, "bar", 0}, nil},
   969  	}
   970  	Dtbl := tblToDtbl(tbl)
   971  	instr := funcs[ast.Locate]
   972  	for i, t := range Dtbl {
   973  		f, err := instr.getFunction(s.ctx, s.datumsToConstants(t["Args"]))
   974  		c.Assert(err, IsNil)
   975  		got, err := evalBuiltinFunc(f, chunk.Event{})
   976  		c.Assert(err, IsNil)
   977  		c.Assert(f, NotNil)
   978  		c.Assert(got, DeepEquals, t["Want"][0], Commentf("[%d]: args: %v", i, t["Args"]))
   979  	}
   980  	// 2. Test LOCATE with binary input
   981  	tbl2 := []struct {
   982  		Args []interface{}
   983  		Want interface{}
   984  	}{
   985  		{[]interface{}{[]byte("BaR"), "foobArbar"}, 0},
   986  		{[]interface{}{"BaR", []byte("foobArbar")}, 0},
   987  		{[]interface{}{[]byte("bAr"), "foobarBaR", 5}, 0},
   988  		{[]interface{}{"bAr", []byte("foobarBaR"), 5}, 0},
   989  		{[]interface{}{"bAr", []byte("foobarbAr"), 5}, 7},
   990  	}
   991  	Dtbl2 := tblToDtbl(tbl2)
   992  	for i, t := range Dtbl2 {
   993  		exprs := s.datumsToConstants(t["Args"])
   994  		types.SetBinChsClnFlag(exprs[0].GetType())
   995  		types.SetBinChsClnFlag(exprs[1].GetType())
   996  		f, err := instr.getFunction(s.ctx, exprs)
   997  		c.Assert(err, IsNil)
   998  		got, err := evalBuiltinFunc(f, chunk.Event{})
   999  		c.Assert(err, IsNil)
  1000  		c.Assert(f, NotNil)
  1001  		c.Assert(got, DeepEquals, t["Want"][0], Commentf("[%d]: args: %v", i, t["Args"]))
  1002  	}
  1003  }
  1004  
  1005  func (s *testEvaluatorSuite) TestTrim(c *C) {
  1006  	cases := []struct {
  1007  		args   []interface{}
  1008  		isNil  bool
  1009  		getErr bool
  1010  		res    string
  1011  	}{
  1012  		{[]interface{}{"   bar   "}, false, false, "bar"},
  1013  		{[]interface{}{"\t   bar   \n"}, false, false, "\t   bar   \n"},
  1014  		{[]interface{}{"\r   bar   \t"}, false, false, "\r   bar   \t"},
  1015  		{[]interface{}{"   \tbar\n     "}, false, false, "\tbar\n"},
  1016  		{[]interface{}{""}, false, false, ""},
  1017  		{[]interface{}{nil}, true, false, ""},
  1018  		{[]interface{}{"xxxbarxxx", "x"}, false, false, "bar"},
  1019  		{[]interface{}{"bar", "x"}, false, false, "bar"},
  1020  		{[]interface{}{"   bar   ", ""}, false, false, "   bar   "},
  1021  		{[]interface{}{"", "x"}, false, false, ""},
  1022  		{[]interface{}{"bar", nil}, true, false, ""},
  1023  		{[]interface{}{nil, "x"}, true, false, ""},
  1024  		{[]interface{}{"xxxbarxxx", "x", int(ast.TrimLeading)}, false, false, "barxxx"},
  1025  		{[]interface{}{"barxxyz", "xyz", int(ast.TrimTrailing)}, false, false, "barx"},
  1026  		{[]interface{}{"xxxbarxxx", "x", int(ast.TrimBoth)}, false, false, "bar"},
  1027  		// FIXME: the result for this test shuold be nil, current is "bar"
  1028  		{[]interface{}{"bar", nil, int(ast.TrimLeading)}, false, false, "bar"},
  1029  		{[]interface{}{errors.New("must error")}, false, true, ""},
  1030  	}
  1031  	for _, t := range cases {
  1032  		f, err := newFunctionForTest(s.ctx, ast.Trim, s.primitiveValsToConstants(t.args)...)
  1033  		c.Assert(err, IsNil)
  1034  		d, err := f.Eval(chunk.Event{})
  1035  		if t.getErr {
  1036  			c.Assert(err, NotNil)
  1037  		} else {
  1038  			c.Assert(err, IsNil)
  1039  			if t.isNil {
  1040  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  1041  			} else {
  1042  				c.Assert(d.GetString(), Equals, t.res)
  1043  			}
  1044  		}
  1045  	}
  1046  
  1047  	_, err := funcs[ast.Trim].getFunction(s.ctx, []Expression{NewZero()})
  1048  	c.Assert(err, IsNil)
  1049  
  1050  	_, err = funcs[ast.Trim].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
  1051  	c.Assert(err, IsNil)
  1052  
  1053  	_, err = funcs[ast.Trim].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()})
  1054  	c.Assert(err, IsNil)
  1055  }
  1056  
  1057  func (s *testEvaluatorSuite) TestLTrim(c *C) {
  1058  	cases := []struct {
  1059  		arg    interface{}
  1060  		isNil  bool
  1061  		getErr bool
  1062  		res    string
  1063  	}{
  1064  		{"   bar   ", false, false, "bar   "},
  1065  		{"\t   bar   ", false, false, "\t   bar   "},
  1066  		{"   \tbar   ", false, false, "\tbar   "},
  1067  		{"\t   bar   ", false, false, "\t   bar   "},
  1068  		{"   \tbar   ", false, false, "\tbar   "},
  1069  		{"\r   bar   ", false, false, "\r   bar   "},
  1070  		{"   \rbar   ", false, false, "\rbar   "},
  1071  		{"\n   bar   ", false, false, "\n   bar   "},
  1072  		{"   \nbar   ", false, false, "\nbar   "},
  1073  		{"bar", false, false, "bar"},
  1074  		{"", false, false, ""},
  1075  		{nil, true, false, ""},
  1076  		{errors.New("must error"), false, true, ""},
  1077  	}
  1078  	for _, t := range cases {
  1079  		f, err := newFunctionForTest(s.ctx, ast.LTrim, s.primitiveValsToConstants([]interface{}{t.arg})...)
  1080  		c.Assert(err, IsNil)
  1081  		d, err := f.Eval(chunk.Event{})
  1082  		if t.getErr {
  1083  			c.Assert(err, NotNil)
  1084  		} else {
  1085  			c.Assert(err, IsNil)
  1086  			if t.isNil {
  1087  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  1088  			} else {
  1089  				c.Assert(d.GetString(), Equals, t.res)
  1090  			}
  1091  		}
  1092  	}
  1093  
  1094  	_, err := funcs[ast.LTrim].getFunction(s.ctx, []Expression{NewZero()})
  1095  	c.Assert(err, IsNil)
  1096  }
  1097  
  1098  func (s *testEvaluatorSuite) TestRTrim(c *C) {
  1099  	cases := []struct {
  1100  		arg    interface{}
  1101  		isNil  bool
  1102  		getErr bool
  1103  		res    string
  1104  	}{
  1105  		{"   bar   ", false, false, "   bar"},
  1106  		{"bar", false, false, "bar"},
  1107  		{"bar     \n", false, false, "bar     \n"},
  1108  		{"bar\n     ", false, false, "bar\n"},
  1109  		{"bar     \r", false, false, "bar     \r"},
  1110  		{"bar\r     ", false, false, "bar\r"},
  1111  		{"bar     \t", false, false, "bar     \t"},
  1112  		{"bar\t     ", false, false, "bar\t"},
  1113  		{"", false, false, ""},
  1114  		{nil, true, false, ""},
  1115  		{errors.New("must error"), false, true, ""},
  1116  	}
  1117  	for _, t := range cases {
  1118  		f, err := newFunctionForTest(s.ctx, ast.RTrim, s.primitiveValsToConstants([]interface{}{t.arg})...)
  1119  		c.Assert(err, IsNil)
  1120  		d, err := f.Eval(chunk.Event{})
  1121  		if t.getErr {
  1122  			c.Assert(err, NotNil)
  1123  		} else {
  1124  			c.Assert(err, IsNil)
  1125  			if t.isNil {
  1126  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  1127  			} else {
  1128  				c.Assert(d.GetString(), Equals, t.res)
  1129  			}
  1130  		}
  1131  	}
  1132  
  1133  	_, err := funcs[ast.RTrim].getFunction(s.ctx, []Expression{NewZero()})
  1134  	c.Assert(err, IsNil)
  1135  }
  1136  
  1137  func (s *testEvaluatorSuite) TestHexFunc(c *C) {
  1138  	cases := []struct {
  1139  		arg    interface{}
  1140  		isNil  bool
  1141  		getErr bool
  1142  		res    string
  1143  	}{
  1144  		{"abc", false, false, "616263"},
  1145  		{"你好", false, false, "E4BDA0E5A5BD"},
  1146  		{12, false, false, "C"},
  1147  		{12.3, false, false, "C"},
  1148  		{12.8, false, false, "D"},
  1149  		{-1, false, false, "FFFFFFFFFFFFFFFF"},
  1150  		{-12.3, false, false, "FFFFFFFFFFFFFFF4"},
  1151  		{-12.8, false, false, "FFFFFFFFFFFFFFF3"},
  1152  		{types.NewBinaryLiteralFromUint(0xC, -1), false, false, "C"},
  1153  		{0x12, false, false, "12"},
  1154  		{nil, true, false, ""},
  1155  		{errors.New("must err"), false, true, ""},
  1156  	}
  1157  	for _, t := range cases {
  1158  		f, err := newFunctionForTest(s.ctx, ast.Hex, s.primitiveValsToConstants([]interface{}{t.arg})...)
  1159  		c.Assert(err, IsNil)
  1160  		d, err := f.Eval(chunk.Event{})
  1161  		if t.getErr {
  1162  			c.Assert(err, NotNil)
  1163  		} else {
  1164  			c.Assert(err, IsNil)
  1165  			if t.isNil {
  1166  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  1167  			} else {
  1168  				c.Assert(d.GetString(), Equals, t.res)
  1169  			}
  1170  		}
  1171  	}
  1172  
  1173  	_, err := funcs[ast.Hex].getFunction(s.ctx, []Expression{int8Con})
  1174  	c.Assert(err, IsNil)
  1175  
  1176  	_, err = funcs[ast.Hex].getFunction(s.ctx, []Expression{varcharCon})
  1177  	c.Assert(err, IsNil)
  1178  }
  1179  
  1180  func (s *testEvaluatorSuite) TestUnhexFunc(c *C) {
  1181  	cases := []struct {
  1182  		arg    interface{}
  1183  		isNil  bool
  1184  		getErr bool
  1185  		res    string
  1186  	}{
  1187  		{"4D7953514C", false, false, "MyALLEGROSQL"},
  1188  		{"1267", false, false, string([]byte{0x12, 0x67})},
  1189  		{"126", false, false, string([]byte{0x01, 0x26})},
  1190  		{"", false, false, ""},
  1191  		{1267, false, false, string([]byte{0x12, 0x67})},
  1192  		{126, false, false, string([]byte{0x01, 0x26})},
  1193  		{1267.3, true, false, ""},
  1194  		{"string", true, false, ""},
  1195  		{"你好", true, false, ""},
  1196  		{nil, true, false, ""},
  1197  		{errors.New("must error"), false, true, ""},
  1198  	}
  1199  	for _, t := range cases {
  1200  		f, err := newFunctionForTest(s.ctx, ast.Unhex, s.primitiveValsToConstants([]interface{}{t.arg})...)
  1201  		c.Assert(err, IsNil)
  1202  		d, err := f.Eval(chunk.Event{})
  1203  		if t.getErr {
  1204  			c.Assert(err, NotNil)
  1205  		} else {
  1206  			c.Assert(err, IsNil)
  1207  			if t.isNil {
  1208  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  1209  			} else {
  1210  				c.Assert(d.GetString(), Equals, t.res)
  1211  			}
  1212  		}
  1213  	}
  1214  
  1215  	_, err := funcs[ast.Unhex].getFunction(s.ctx, []Expression{NewZero()})
  1216  	c.Assert(err, IsNil)
  1217  }
  1218  
  1219  func (s *testEvaluatorSuite) TestBitLength(c *C) {
  1220  	cases := []struct {
  1221  		args     interface{}
  1222  		expected int64
  1223  		isNil    bool
  1224  		getErr   bool
  1225  	}{
  1226  		{"hi", 16, false, false},
  1227  		{"你好", 48, false, false},
  1228  		{"", 0, false, false},
  1229  	}
  1230  
  1231  	for _, t := range cases {
  1232  		f, err := newFunctionForTest(s.ctx, ast.BitLength, s.primitiveValsToConstants([]interface{}{t.args})...)
  1233  		c.Assert(err, IsNil)
  1234  		d, err := f.Eval(chunk.Event{})
  1235  		if t.getErr {
  1236  			c.Assert(err, NotNil)
  1237  		} else {
  1238  			c.Assert(err, IsNil)
  1239  			if t.isNil {
  1240  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  1241  			} else {
  1242  				c.Assert(d.GetInt64(), Equals, t.expected)
  1243  			}
  1244  		}
  1245  	}
  1246  
  1247  	_, err := funcs[ast.BitLength].getFunction(s.ctx, []Expression{NewZero()})
  1248  	c.Assert(err, IsNil)
  1249  }
  1250  
  1251  func (s *testEvaluatorSuite) TestChar(c *C) {
  1252  	stmtCtx := s.ctx.GetStochastikVars().StmtCtx
  1253  	origin := stmtCtx.IgnoreTruncate
  1254  	stmtCtx.IgnoreTruncate = true
  1255  	defer func() {
  1256  		stmtCtx.IgnoreTruncate = origin
  1257  	}()
  1258  
  1259  	tbl := []struct {
  1260  		str    string
  1261  		iNum   int64
  1262  		fNum   float64
  1263  		result string
  1264  	}{
  1265  		{"65", 66, 67.5, "ABD"},                  // float
  1266  		{"65", 16740, 67.5, "AAdD"},              // large num
  1267  		{"65", -1, 67.5, "A\xff\xff\xff\xffD"},   // nagtive int
  1268  		{"a", -1, 67.5, "\x00\xff\xff\xff\xffD"}, // invalid 'a'
  1269  	}
  1270  	for _, v := range tbl {
  1271  		for _, char := range []interface{}{"utf8", nil} {
  1272  			fc := funcs[ast.CharFunc]
  1273  			f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(v.str, v.iNum, v.fNum, char)))
  1274  			c.Assert(err, IsNil)
  1275  			c.Assert(f, NotNil)
  1276  			r, err := evalBuiltinFunc(f, chunk.Event{})
  1277  			c.Assert(err, IsNil, Commentf("err: %v", err))
  1278  			c.Assert(r, solitonutil.CausetEquals, types.NewCauset(v.result))
  1279  		}
  1280  	}
  1281  
  1282  	fc := funcs[ast.CharFunc]
  1283  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets("65", 66, nil)))
  1284  	c.Assert(err, IsNil)
  1285  	r, err := evalBuiltinFunc(f, chunk.Event{})
  1286  	c.Assert(err, IsNil)
  1287  	c.Assert(r, solitonutil.CausetEquals, types.NewCauset("AB"))
  1288  }
  1289  
  1290  func (s *testEvaluatorSuite) TestCharLength(c *C) {
  1291  	tbl := []struct {
  1292  		input  interface{}
  1293  		result interface{}
  1294  	}{
  1295  		{"33", 2},  // string
  1296  		{"你好", 2},  // mb string
  1297  		{33, 2},    // int
  1298  		{3.14, 4},  // float
  1299  		{nil, nil}, // nil
  1300  	}
  1301  	for _, v := range tbl {
  1302  		fc := funcs[ast.CharLength]
  1303  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(v.input)))
  1304  		c.Assert(err, IsNil)
  1305  		r, err := evalBuiltinFunc(f, chunk.Event{})
  1306  		c.Assert(err, IsNil)
  1307  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(v.result))
  1308  	}
  1309  
  1310  	// Test binary string
  1311  	tbl = []struct {
  1312  		input  interface{}
  1313  		result interface{}
  1314  	}{
  1315  		{"33", 2},   // string
  1316  		{"你好", 6},   // mb string
  1317  		{"CAFÉ", 5}, // mb string
  1318  		{"", 0},     // mb string
  1319  		{nil, nil},  // nil
  1320  	}
  1321  	for _, v := range tbl {
  1322  		fc := funcs[ast.CharLength]
  1323  		arg := s.datumsToConstants(types.MakeCausets(v.input))
  1324  		tp := arg[0].GetType()
  1325  		tp.Tp = allegrosql.TypeVarString
  1326  		tp.Charset = charset.CharsetBin
  1327  		tp.DefCauslate = charset.DefCauslationBin
  1328  		tp.Flen = types.UnspecifiedLength
  1329  		tp.Flag = allegrosql.BinaryFlag
  1330  		f, err := fc.getFunction(s.ctx, arg)
  1331  		c.Assert(err, IsNil)
  1332  		r, err := evalBuiltinFunc(f, chunk.Event{})
  1333  		c.Assert(err, IsNil)
  1334  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(v.result))
  1335  	}
  1336  }
  1337  
  1338  func (s *testEvaluatorSuite) TestFindInSet(c *C) {
  1339  	for _, t := range []struct {
  1340  		str    interface{}
  1341  		strlst interface{}
  1342  		ret    interface{}
  1343  	}{
  1344  		{"foo", "foo,bar", 1},
  1345  		{"foo", "foobar,bar", 0},
  1346  		{" foo ", "foo, foo ", 2},
  1347  		{"", "foo,bar,", 3},
  1348  		{"", "", 0},
  1349  		{1, 1, 1},
  1350  		{1, "1", 1},
  1351  		{"1", 1, 1},
  1352  		{"a,b", "a,b,c", 0},
  1353  		{"foo", nil, nil},
  1354  		{nil, "bar", nil},
  1355  	} {
  1356  		fc := funcs[ast.FindInSet]
  1357  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.str, t.strlst)))
  1358  		c.Assert(err, IsNil)
  1359  		r, err := evalBuiltinFunc(f, chunk.Event{})
  1360  		c.Assert(err, IsNil)
  1361  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret), Commentf("FindInSet(%s, %s)", t.str, t.strlst))
  1362  	}
  1363  }
  1364  
  1365  func (s *testEvaluatorSuite) TestField(c *C) {
  1366  	stmtCtx := s.ctx.GetStochastikVars().StmtCtx
  1367  	origin := stmtCtx.IgnoreTruncate
  1368  	stmtCtx.IgnoreTruncate = true
  1369  	defer func() {
  1370  		stmtCtx.IgnoreTruncate = origin
  1371  	}()
  1372  
  1373  	tbl := []struct {
  1374  		argLst []interface{}
  1375  		ret    interface{}
  1376  	}{
  1377  		{[]interface{}{"ej", "Hej", "ej", "Heja", "hej", "foo"}, int64(2)},
  1378  		{[]interface{}{"fo", "Hej", "ej", "Heja", "hej", "foo"}, int64(0)},
  1379  		{[]interface{}{"ej", "Hej", "ej", "Heja", "ej", "hej", "foo"}, int64(2)},
  1380  		{[]interface{}{1, 2, 3, 11, 1}, int64(4)},
  1381  		{[]interface{}{nil, 2, 3, 11, 1}, int64(0)},
  1382  		{[]interface{}{1.1, 2.1, 3.1, 11.1, 1.1}, int64(4)},
  1383  		{[]interface{}{1.1, "2.1", "3.1", "11.1", "1.1"}, int64(4)},
  1384  		{[]interface{}{"1.1a", 2.1, 3.1, 11.1, 1.1}, int64(4)},
  1385  		{[]interface{}{1.10, 0, 11e-1}, int64(2)},
  1386  		{[]interface{}{"abc", 0, 1, 11.1, 1.1}, int64(1)},
  1387  	}
  1388  	for _, t := range tbl {
  1389  		fc := funcs[ast.Field]
  1390  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.argLst...)))
  1391  		c.Assert(err, IsNil)
  1392  		c.Assert(f, NotNil)
  1393  		r, err := evalBuiltinFunc(f, chunk.Event{})
  1394  		c.Assert(err, IsNil)
  1395  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret))
  1396  	}
  1397  }
  1398  
  1399  func (s *testEvaluatorSuite) TestLpad(c *C) {
  1400  	tests := []struct {
  1401  		str    string
  1402  		len    int64
  1403  		padStr string
  1404  		expect interface{}
  1405  	}{
  1406  		{"hi", 5, "?", "???hi"},
  1407  		{"hi", 1, "?", "h"},
  1408  		{"hi", 0, "?", ""},
  1409  		{"hi", -1, "?", nil},
  1410  		{"hi", 1, "", "h"},
  1411  		{"hi", 5, "", nil},
  1412  		{"hi", 5, "ab", "abahi"},
  1413  		{"hi", 6, "ab", "ababhi"},
  1414  	}
  1415  	fc := funcs[ast.Lpad]
  1416  	for _, test := range tests {
  1417  		str := types.NewStringCauset(test.str)
  1418  		length := types.NewIntCauset(test.len)
  1419  		padStr := types.NewStringCauset(test.padStr)
  1420  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, length, padStr}))
  1421  		c.Assert(err, IsNil)
  1422  		c.Assert(f, NotNil)
  1423  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1424  		c.Assert(err, IsNil)
  1425  		if test.expect == nil {
  1426  			c.Assert(result.HoTT(), Equals, types.HoTTNull)
  1427  		} else {
  1428  			expect, _ := test.expect.(string)
  1429  			c.Assert(result.GetString(), Equals, expect)
  1430  		}
  1431  	}
  1432  }
  1433  
  1434  func (s *testEvaluatorSuite) TestRpad(c *C) {
  1435  	tests := []struct {
  1436  		str    string
  1437  		len    int64
  1438  		padStr string
  1439  		expect interface{}
  1440  	}{
  1441  		{"hi", 5, "?", "hi???"},
  1442  		{"hi", 1, "?", "h"},
  1443  		{"hi", 0, "?", ""},
  1444  		{"hi", -1, "?", nil},
  1445  		{"hi", 1, "", "h"},
  1446  		{"hi", 5, "", nil},
  1447  		{"hi", 5, "ab", "hiaba"},
  1448  		{"hi", 6, "ab", "hiabab"},
  1449  	}
  1450  	fc := funcs[ast.Rpad]
  1451  	for _, test := range tests {
  1452  		str := types.NewStringCauset(test.str)
  1453  		length := types.NewIntCauset(test.len)
  1454  		padStr := types.NewStringCauset(test.padStr)
  1455  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, length, padStr}))
  1456  		c.Assert(err, IsNil)
  1457  		c.Assert(f, NotNil)
  1458  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1459  		c.Assert(err, IsNil)
  1460  		if test.expect == nil {
  1461  			c.Assert(result.HoTT(), Equals, types.HoTTNull)
  1462  		} else {
  1463  			expect, _ := test.expect.(string)
  1464  			c.Assert(result.GetString(), Equals, expect)
  1465  		}
  1466  	}
  1467  }
  1468  
  1469  func (s *testEvaluatorSuite) TestRpadSig(c *C) {
  1470  	defCausTypes := []*types.FieldType{
  1471  		{Tp: allegrosql.TypeVarchar},
  1472  		{Tp: allegrosql.TypeLonglong},
  1473  		{Tp: allegrosql.TypeVarchar},
  1474  	}
  1475  	resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000}
  1476  
  1477  	args := []Expression{
  1478  		&DeferredCauset{Index: 0, RetType: defCausTypes[0]},
  1479  		&DeferredCauset{Index: 1, RetType: defCausTypes[1]},
  1480  		&DeferredCauset{Index: 2, RetType: defCausTypes[2]},
  1481  	}
  1482  
  1483  	base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
  1484  	rpad := &builtinRpadUTF8Sig{base, 1000}
  1485  
  1486  	input := chunk.NewChunkWithCapacity(defCausTypes, 10)
  1487  	input.AppendString(0, "abc")
  1488  	input.AppendString(0, "abc")
  1489  	input.AppendInt64(1, 6)
  1490  	input.AppendInt64(1, 10000)
  1491  	input.AppendString(2, "123")
  1492  	input.AppendString(2, "123")
  1493  
  1494  	res, isNull, err := rpad.evalString(input.GetEvent(0))
  1495  	c.Assert(res, Equals, "abc123")
  1496  	c.Assert(isNull, IsFalse)
  1497  	c.Assert(err, IsNil)
  1498  
  1499  	res, isNull, err = rpad.evalString(input.GetEvent(1))
  1500  	c.Assert(res, Equals, "")
  1501  	c.Assert(isNull, IsTrue)
  1502  	c.Assert(err, IsNil)
  1503  
  1504  	warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  1505  	c.Assert(len(warnings), Equals, 1)
  1506  	lastWarn := warnings[len(warnings)-1]
  1507  	c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue, Commentf("err %v", lastWarn.Err))
  1508  }
  1509  
  1510  func (s *testEvaluatorSuite) TestInsertBinarySig(c *C) {
  1511  	defCausTypes := []*types.FieldType{
  1512  		{Tp: allegrosql.TypeVarchar},
  1513  		{Tp: allegrosql.TypeLonglong},
  1514  		{Tp: allegrosql.TypeLonglong},
  1515  		{Tp: allegrosql.TypeVarchar},
  1516  	}
  1517  	resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 3}
  1518  
  1519  	args := []Expression{
  1520  		&DeferredCauset{Index: 0, RetType: defCausTypes[0]},
  1521  		&DeferredCauset{Index: 1, RetType: defCausTypes[1]},
  1522  		&DeferredCauset{Index: 2, RetType: defCausTypes[2]},
  1523  		&DeferredCauset{Index: 3, RetType: defCausTypes[3]},
  1524  	}
  1525  
  1526  	base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
  1527  	insert := &builtinInsertSig{base, 3}
  1528  
  1529  	input := chunk.NewChunkWithCapacity(defCausTypes, 2)
  1530  	input.AppendString(0, "abc")
  1531  	input.AppendString(0, "abc")
  1532  	input.AppendString(0, "abc")
  1533  	input.AppendNull(0)
  1534  	input.AppendString(0, "abc")
  1535  	input.AppendString(0, "abc")
  1536  	input.AppendString(0, "abc")
  1537  	input.AppendInt64(1, 3)
  1538  	input.AppendInt64(1, 3)
  1539  	input.AppendInt64(1, 0)
  1540  	input.AppendInt64(1, 3)
  1541  	input.AppendNull(1)
  1542  	input.AppendInt64(1, 3)
  1543  	input.AppendInt64(1, 3)
  1544  	input.AppendInt64(2, -1)
  1545  	input.AppendInt64(2, -1)
  1546  	input.AppendInt64(2, -1)
  1547  	input.AppendInt64(2, -1)
  1548  	input.AppendInt64(2, -1)
  1549  	input.AppendNull(2)
  1550  	input.AppendInt64(2, -1)
  1551  	input.AppendString(3, "d")
  1552  	input.AppendString(3, "de")
  1553  	input.AppendString(3, "d")
  1554  	input.AppendString(3, "d")
  1555  	input.AppendString(3, "d")
  1556  	input.AppendString(3, "d")
  1557  	input.AppendNull(3)
  1558  
  1559  	res, isNull, err := insert.evalString(input.GetEvent(0))
  1560  	c.Assert(res, Equals, "abd")
  1561  	c.Assert(isNull, IsFalse)
  1562  	c.Assert(err, IsNil)
  1563  
  1564  	res, isNull, err = insert.evalString(input.GetEvent(1))
  1565  	c.Assert(res, Equals, "")
  1566  	c.Assert(isNull, IsTrue)
  1567  	c.Assert(err, IsNil)
  1568  
  1569  	res, isNull, err = insert.evalString(input.GetEvent(2))
  1570  	c.Assert(res, Equals, "abc")
  1571  	c.Assert(isNull, IsFalse)
  1572  	c.Assert(err, IsNil)
  1573  
  1574  	res, isNull, err = insert.evalString(input.GetEvent(3))
  1575  	c.Assert(res, Equals, "")
  1576  	c.Assert(isNull, IsTrue)
  1577  	c.Assert(err, IsNil)
  1578  
  1579  	res, isNull, err = insert.evalString(input.GetEvent(4))
  1580  	c.Assert(res, Equals, "")
  1581  	c.Assert(isNull, IsTrue)
  1582  	c.Assert(err, IsNil)
  1583  
  1584  	res, isNull, err = insert.evalString(input.GetEvent(5))
  1585  	c.Assert(res, Equals, "")
  1586  	c.Assert(isNull, IsTrue)
  1587  	c.Assert(err, IsNil)
  1588  
  1589  	res, isNull, err = insert.evalString(input.GetEvent(6))
  1590  	c.Assert(res, Equals, "")
  1591  	c.Assert(isNull, IsTrue)
  1592  	c.Assert(err, IsNil)
  1593  
  1594  	warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  1595  	c.Assert(len(warnings), Equals, 1)
  1596  	lastWarn := warnings[len(warnings)-1]
  1597  	c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue, Commentf("err %v", lastWarn.Err))
  1598  }
  1599  
  1600  func (s *testEvaluatorSuite) TestInstr(c *C) {
  1601  	tbl := []struct {
  1602  		Args []interface{}
  1603  		Want interface{}
  1604  	}{
  1605  		{[]interface{}{"foobarbar", "bar"}, 4},
  1606  		{[]interface{}{"xbar", "foobar"}, 0},
  1607  
  1608  		{[]interface{}{123456234, 234}, 2},
  1609  		{[]interface{}{123456, 567}, 0},
  1610  		{[]interface{}{1e10, 1e2}, 1},
  1611  		{[]interface{}{1.234, ".234"}, 2},
  1612  		{[]interface{}{1.234, ""}, 1},
  1613  		{[]interface{}{"", 123}, 0},
  1614  		{[]interface{}{"", ""}, 1},
  1615  
  1616  		{[]interface{}{"中文美好", "美好"}, 3},
  1617  		{[]interface{}{"中文美好", "世界"}, 0},
  1618  		{[]interface{}{"中文abc", "a"}, 3},
  1619  
  1620  		{[]interface{}{"live long and prosper", "long"}, 6},
  1621  
  1622  		{[]interface{}{"not binary string", "binary"}, 5},
  1623  		{[]interface{}{"upper case", "upper"}, 1},
  1624  		{[]interface{}{"UPPER CASE", "CASE"}, 7},
  1625  		{[]interface{}{"中文abc", "abc"}, 3},
  1626  
  1627  		{[]interface{}{"foobar", nil}, nil},
  1628  		{[]interface{}{nil, "foobar"}, nil},
  1629  		{[]interface{}{nil, nil}, nil},
  1630  	}
  1631  
  1632  	Dtbl := tblToDtbl(tbl)
  1633  	instr := funcs[ast.Instr]
  1634  	for i, t := range Dtbl {
  1635  		f, err := instr.getFunction(s.ctx, s.datumsToConstants(t["Args"]))
  1636  		c.Assert(err, IsNil)
  1637  		c.Assert(f, NotNil)
  1638  		got, err := evalBuiltinFunc(f, chunk.Event{})
  1639  		c.Assert(err, IsNil)
  1640  		c.Assert(got, DeepEquals, t["Want"][0], Commentf("[%d]: args: %v", i, t["Args"]))
  1641  	}
  1642  }
  1643  
  1644  func (s *testEvaluatorSuite) TestMakeSet(c *C) {
  1645  	tbl := []struct {
  1646  		argList []interface{}
  1647  		ret     interface{}
  1648  	}{
  1649  		{[]interface{}{1, "a", "b", "c"}, "a"},
  1650  		{[]interface{}{1 | 4, "hello", "nice", "world"}, "hello,world"},
  1651  		{[]interface{}{1 | 4, "hello", "nice", nil, "world"}, "hello"},
  1652  		{[]interface{}{0, "a", "b", "c"}, ""},
  1653  		{[]interface{}{nil, "a", "b", "c"}, nil},
  1654  		{[]interface{}{-100 | 4, "hello", "nice", "abc", "world"}, "abc,world"},
  1655  		{[]interface{}{-1, "hello", "nice", "abc", "world"}, "hello,nice,abc,world"},
  1656  	}
  1657  
  1658  	for _, t := range tbl {
  1659  		fc := funcs[ast.MakeSet]
  1660  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.argList...)))
  1661  		c.Assert(err, IsNil)
  1662  		c.Assert(f, NotNil)
  1663  		r, err := evalBuiltinFunc(f, chunk.Event{})
  1664  		c.Assert(err, IsNil)
  1665  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret))
  1666  	}
  1667  }
  1668  
  1669  func (s *testEvaluatorSuite) TestOct(c *C) {
  1670  	octTests := []struct {
  1671  		origin interface{}
  1672  		ret    string
  1673  	}{
  1674  		{"-2.7", "1777777777777777777776"},
  1675  		{-1.5, "1777777777777777777777"},
  1676  		{-1, "1777777777777777777777"},
  1677  		{"0", "0"},
  1678  		{"1", "1"},
  1679  		{"8", "10"},
  1680  		{"12", "14"},
  1681  		{"20", "24"},
  1682  		{"100", "144"},
  1683  		{"1024", "2000"},
  1684  		{"2048", "4000"},
  1685  		{1.0, "1"},
  1686  		{9.5, "11"},
  1687  		{13, "15"},
  1688  		{1025, "2001"},
  1689  		{"8a8", "10"},
  1690  		{"abc", "0"},
  1691  		//overflow uint64
  1692  		{"9999999999999999999999999", "1777777777777777777777"},
  1693  		{"-9999999999999999999999999", "1777777777777777777777"},
  1694  		{types.NewBinaryLiteralFromUint(255, -1), "377"}, // b'11111111'
  1695  		{types.NewBinaryLiteralFromUint(10, -1), "12"},   // b'1010'
  1696  		{types.NewBinaryLiteralFromUint(5, -1), "5"},     // b'0101'
  1697  	}
  1698  	fc := funcs[ast.Oct]
  1699  	for _, tt := range octTests {
  1700  		in := types.NewCauset(tt.origin)
  1701  		f, _ := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{in}))
  1702  		c.Assert(f, NotNil)
  1703  		r, err := evalBuiltinFunc(f, chunk.Event{})
  1704  		c.Assert(err, IsNil)
  1705  		res, err := r.ToString()
  1706  		c.Assert(err, IsNil)
  1707  		c.Assert(res, Equals, tt.ret, Commentf("select oct(%v);", tt.origin))
  1708  	}
  1709  	// tt NULL input for sha
  1710  	var argNull types.Causet
  1711  	f, _ := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{argNull}))
  1712  	r, err := evalBuiltinFunc(f, chunk.Event{})
  1713  	c.Assert(err, IsNil)
  1714  	c.Assert(r.IsNull(), IsTrue)
  1715  }
  1716  
  1717  func (s *testEvaluatorSuite) TestFormat(c *C) {
  1718  	formatTests := []struct {
  1719  		number    interface{}
  1720  		precision interface{}
  1721  		locale    string
  1722  		ret       interface{}
  1723  	}{
  1724  		{12332.12341111111111111111111111111111111111111, 4, "en_US", "12,332.1234"},
  1725  		{nil, 22, "en_US", nil},
  1726  	}
  1727  	formatTests1 := []struct {
  1728  		number    interface{}
  1729  		precision interface{}
  1730  		ret       interface{}
  1731  		warnings  int
  1732  	}{
  1733  		// issue #8796
  1734  		{1.12345, 4, "1.1235", 0},
  1735  		{9.99999, 4, "10.0000", 0},
  1736  		{1.99999, 4, "2.0000", 0},
  1737  		{1.09999, 4, "1.1000", 0},
  1738  		{-2.5000, 0, "-3", 0},
  1739  
  1740  		{12332.123444, 4, "12,332.1234", 0},
  1741  		{12332.123444, 0, "12,332", 0},
  1742  		{12332.123444, -4, "12,332", 0},
  1743  		{-12332.123444, 4, "-12,332.1234", 0},
  1744  		{-12332.123444, 0, "-12,332", 0},
  1745  		{-12332.123444, -4, "-12,332", 0},
  1746  		{"12332.123444", "4", "12,332.1234", 0},
  1747  		{"12332.123444A", "4", "12,332.1234", 1},
  1748  		{"-12332.123444", "4", "-12,332.1234", 0},
  1749  		{"-12332.123444A", "4", "-12,332.1234", 1},
  1750  		{"A123345", "4", "0.0000", 1},
  1751  		{"-A123345", "4", "0.0000", 1},
  1752  		{"-12332.123444", "A", "-12,332", 1},
  1753  		{"12332.123444", "A", "12,332", 1},
  1754  		{"-12332.123444", "4A", "-12,332.1234", 1},
  1755  		{"12332.123444", "4A", "12,332.1234", 1},
  1756  		{"-A12332.123444", "A", "0", 2},
  1757  		{"A12332.123444", "A", "0", 2},
  1758  		{"-A12332.123444", "4A", "0.0000", 2},
  1759  		{"A12332.123444", "4A", "0.0000", 2},
  1760  		{"-.12332.123444", "4A", "-0.1233", 2},
  1761  		{".12332.123444", "4A", "0.1233", 2},
  1762  		{"12332.1234567890123456789012345678901", 22, "12,332.1234567890110000000000", 0},
  1763  		{nil, 22, nil, 0},
  1764  		{1, 1024, "1.000000000000000000000000000000", 0},
  1765  		{"", 1, "0.0", 0},
  1766  		{1, "", "1", 1},
  1767  	}
  1768  	formatTests2 := struct {
  1769  		number    interface{}
  1770  		precision interface{}
  1771  		locale    string
  1772  		ret       interface{}
  1773  	}{-12332.123456, -4, "zh_CN", nil}
  1774  	formatTests3 := struct {
  1775  		number    interface{}
  1776  		precision interface{}
  1777  		locale    string
  1778  		ret       interface{}
  1779  	}{"-12332.123456", "4", "de_GE", nil}
  1780  	formatTests4 := struct {
  1781  		number    interface{}
  1782  		precision interface{}
  1783  		locale    interface{}
  1784  		ret       interface{}
  1785  	}{1, 4, nil, "1.0000"}
  1786  
  1787  	fc := funcs[ast.Format]
  1788  	for _, tt := range formatTests {
  1789  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tt.number, tt.precision, tt.locale)))
  1790  		c.Assert(err, IsNil)
  1791  		c.Assert(f, NotNil)
  1792  		r, err := evalBuiltinFunc(f, chunk.Event{})
  1793  		c.Assert(err, IsNil)
  1794  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(tt.ret))
  1795  	}
  1796  
  1797  	origConfig := s.ctx.GetStochastikVars().StmtCtx.TruncateAsWarning
  1798  	s.ctx.GetStochastikVars().StmtCtx.TruncateAsWarning = true
  1799  	for _, tt := range formatTests1 {
  1800  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tt.number, tt.precision)))
  1801  		c.Assert(err, IsNil)
  1802  		c.Assert(f, NotNil)
  1803  		r, err := evalBuiltinFunc(f, chunk.Event{})
  1804  		c.Assert(err, IsNil)
  1805  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(tt.ret), Commentf("test %v", tt))
  1806  		if tt.warnings > 0 {
  1807  			warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  1808  			c.Assert(len(warnings), Equals, tt.warnings, Commentf("test %v", tt))
  1809  			for i := 0; i < tt.warnings; i++ {
  1810  				c.Assert(terror.ErrorEqual(types.ErrTruncatedWrongVal, warnings[i].Err), IsTrue, Commentf("test %v", tt))
  1811  			}
  1812  			s.ctx.GetStochastikVars().StmtCtx.SetWarnings([]stmtctx.ALLEGROSQLWarn{})
  1813  		}
  1814  	}
  1815  	s.ctx.GetStochastikVars().StmtCtx.TruncateAsWarning = origConfig
  1816  
  1817  	f2, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(formatTests2.number, formatTests2.precision, formatTests2.locale)))
  1818  	c.Assert(err, IsNil)
  1819  	c.Assert(f2, NotNil)
  1820  	r2, err := evalBuiltinFunc(f2, chunk.Event{})
  1821  	c.Assert(types.NewCauset(err), solitonutil.CausetEquals, types.NewCauset(errors.New("not implemented")))
  1822  	c.Assert(r2, solitonutil.CausetEquals, types.NewCauset(formatTests2.ret))
  1823  
  1824  	f3, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(formatTests3.number, formatTests3.precision, formatTests3.locale)))
  1825  	c.Assert(err, IsNil)
  1826  	c.Assert(f3, NotNil)
  1827  	r3, err := evalBuiltinFunc(f3, chunk.Event{})
  1828  	c.Assert(types.NewCauset(err), solitonutil.CausetEquals, types.NewCauset(errors.New("not support for the specific locale")))
  1829  	c.Assert(r3, solitonutil.CausetEquals, types.NewCauset(formatTests3.ret))
  1830  
  1831  	f4, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(formatTests4.number, formatTests4.precision, formatTests4.locale)))
  1832  	c.Assert(err, IsNil)
  1833  	c.Assert(f4, NotNil)
  1834  	r4, err := evalBuiltinFunc(f4, chunk.Event{})
  1835  	c.Assert(err, IsNil)
  1836  	c.Assert(r4, solitonutil.CausetEquals, types.NewCauset(formatTests4.ret))
  1837  	warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  1838  	c.Assert(len(warnings), Equals, 1)
  1839  	c.Assert(terror.ErrorEqual(errUnknownLocale, warnings[0].Err), IsTrue)
  1840  	s.ctx.GetStochastikVars().StmtCtx.SetWarnings([]stmtctx.ALLEGROSQLWarn{})
  1841  }
  1842  
  1843  func (s *testEvaluatorSuite) TestFromBase64(c *C) {
  1844  	tests := []struct {
  1845  		args   interface{}
  1846  		expect interface{}
  1847  	}{
  1848  		{"", ""},
  1849  		{"YWJj", "abc"},
  1850  		{"YWIgYw==", "ab c"},
  1851  		{"YWIKYw==", "ab\nc"},
  1852  		{"YWIJYw==", "ab\tc"},
  1853  		{"cXdlcnR5MTIzNDU2", "qwerty123456"},
  1854  		{
  1855  			"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrL0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4\neXowMTIzNDU2Nzg5Ky9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3Bx\ncnN0dXZ3eHl6MDEyMzQ1Njc4OSsv",
  1856  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  1857  		},
  1858  		{
  1859  			"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==",
  1860  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  1861  		},
  1862  		{
  1863  			"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==",
  1864  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  1865  		},
  1866  		{
  1867  			"QUJDREVGR0hJSkt\tMTU5PUFFSU1RVVld\nYWVphYmNkZ\rWZnaGlqa2xt   bm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==",
  1868  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  1869  		},
  1870  	}
  1871  	fc := funcs[ast.FromBase64]
  1872  	for _, test := range tests {
  1873  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(test.args)))
  1874  		c.Assert(err, IsNil)
  1875  		c.Assert(f, NotNil)
  1876  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1877  		c.Assert(err, IsNil)
  1878  		if test.expect == nil {
  1879  			c.Assert(result.HoTT(), Equals, types.HoTTNull)
  1880  		} else {
  1881  			expect, _ := test.expect.(string)
  1882  			c.Assert(result.GetString(), Equals, expect)
  1883  		}
  1884  	}
  1885  }
  1886  
  1887  func (s *testEvaluatorSuite) TestFromBase64Sig(c *C) {
  1888  	defCausTypes := []*types.FieldType{
  1889  		{Tp: allegrosql.TypeVarchar},
  1890  	}
  1891  
  1892  	tests := []struct {
  1893  		args           string
  1894  		expect         string
  1895  		isNil          bool
  1896  		maxAllowPacket uint64
  1897  	}{
  1898  		{"YWJj", "abc", false, 3},
  1899  		{"YWJj", "", true, 2},
  1900  		{
  1901  			"QUJDREVGR0hJSkt\tMTU5PUFFSU1RVVld\nYWVphYmNkZ\rWZnaGlqa2xt   bm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==",
  1902  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  1903  			false,
  1904  			70,
  1905  		},
  1906  		{
  1907  			"QUJDREVGR0hJSkt\tMTU5PUFFSU1RVVld\nYWVphYmNkZ\rWZnaGlqa2xt   bm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==",
  1908  			"",
  1909  			true,
  1910  			69,
  1911  		},
  1912  	}
  1913  
  1914  	args := []Expression{
  1915  		&DeferredCauset{Index: 0, RetType: defCausTypes[0]},
  1916  	}
  1917  
  1918  	for _, test := range tests {
  1919  		resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: allegrosql.MaxBlobWidth}
  1920  		base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
  1921  		fromBase64 := &builtinFromBase64Sig{base, test.maxAllowPacket}
  1922  
  1923  		input := chunk.NewChunkWithCapacity(defCausTypes, 1)
  1924  		input.AppendString(0, test.args)
  1925  		res, isNull, err := fromBase64.evalString(input.GetEvent(0))
  1926  		c.Assert(err, IsNil)
  1927  		c.Assert(isNull, Equals, test.isNil)
  1928  		if isNull {
  1929  			warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  1930  			c.Assert(len(warnings), Equals, 1)
  1931  			lastWarn := warnings[len(warnings)-1]
  1932  			c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue)
  1933  			s.ctx.GetStochastikVars().StmtCtx.SetWarnings([]stmtctx.ALLEGROSQLWarn{})
  1934  		}
  1935  		c.Assert(res, Equals, test.expect)
  1936  	}
  1937  }
  1938  
  1939  func (s *testEvaluatorSuite) TestInsert(c *C) {
  1940  	tests := []struct {
  1941  		args   []interface{}
  1942  		expect interface{}
  1943  	}{
  1944  		{[]interface{}{"Quadratic", 3, 4, "What"}, "QuWhattic"},
  1945  		{[]interface{}{"Quadratic", -1, 4, "What"}, "Quadratic"},
  1946  		{[]interface{}{"Quadratic", 3, 100, "What"}, "QuWhat"},
  1947  		{[]interface{}{nil, 3, 100, "What"}, nil},
  1948  		{[]interface{}{"Quadratic", nil, 4, "What"}, nil},
  1949  		{[]interface{}{"Quadratic", 3, nil, "What"}, nil},
  1950  		{[]interface{}{"Quadratic", 3, 4, nil}, nil},
  1951  		{[]interface{}{"Quadratic", 3, -1, "What"}, "QuWhat"},
  1952  		{[]interface{}{"Quadratic", 3, 1, "What"}, "QuWhatdratic"},
  1953  		{[]interface{}{"Quadratic", -1, nil, "What"}, nil},
  1954  		{[]interface{}{"Quadratic", -1, 4, nil}, nil},
  1955  
  1956  		{[]interface{}{"我叫小雨呀", 3, 2, "王雨叶"}, "我叫王雨叶呀"},
  1957  		{[]interface{}{"我叫小雨呀", -1, 2, "王雨叶"}, "我叫小雨呀"},
  1958  		{[]interface{}{"我叫小雨呀", 3, 100, "王雨叶"}, "我叫王雨叶"},
  1959  		{[]interface{}{nil, 3, 100, "王雨叶"}, nil},
  1960  		{[]interface{}{"我叫小雨呀", nil, 4, "王雨叶"}, nil},
  1961  		{[]interface{}{"我叫小雨呀", 3, nil, "王雨叶"}, nil},
  1962  		{[]interface{}{"我叫小雨呀", 3, 4, nil}, nil},
  1963  		{[]interface{}{"我叫小雨呀", 3, -1, "王雨叶"}, "我叫王雨叶"},
  1964  		{[]interface{}{"我叫小雨呀", 3, 1, "王雨叶"}, "我叫王雨叶雨呀"},
  1965  		{[]interface{}{"我叫小雨呀", -1, nil, "王雨叶"}, nil},
  1966  		{[]interface{}{"我叫小雨呀", -1, 2, nil}, nil},
  1967  	}
  1968  	fc := funcs[ast.InsertFunc]
  1969  	for _, test := range tests {
  1970  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(test.args...)))
  1971  		c.Assert(err, IsNil)
  1972  		c.Assert(f, NotNil)
  1973  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1974  		c.Assert(err, IsNil)
  1975  		if test.expect == nil {
  1976  			c.Assert(result.HoTT(), Equals, types.HoTTNull)
  1977  		} else {
  1978  			expect, _ := test.expect.(string)
  1979  			c.Assert(result.GetString(), Equals, expect)
  1980  		}
  1981  	}
  1982  }
  1983  
  1984  func (s *testEvaluatorSuite) TestOrd(c *C) {
  1985  	cases := []struct {
  1986  		args     interface{}
  1987  		expected int64
  1988  		isNil    bool
  1989  		getErr   bool
  1990  	}{
  1991  		{"2", 50, false, false},
  1992  		{2, 50, false, false},
  1993  		{"23", 50, false, false},
  1994  		{23, 50, false, false},
  1995  		{2.3, 50, false, false},
  1996  		{nil, 0, true, false},
  1997  		{"", 0, false, false},
  1998  		{"你好", 14990752, false, false},
  1999  		{"にほん", 14909867, false, false},
  2000  		{"한국", 15570332, false, false},
  2001  		{"👍", 4036989325, false, false},
  2002  		{"א", 55184, false, false},
  2003  	}
  2004  	for _, t := range cases {
  2005  		f, err := newFunctionForTest(s.ctx, ast.Ord, s.primitiveValsToConstants([]interface{}{t.args})...)
  2006  		c.Assert(err, IsNil)
  2007  
  2008  		d, err := f.Eval(chunk.Event{})
  2009  		if t.getErr {
  2010  			c.Assert(err, NotNil)
  2011  		} else {
  2012  			c.Assert(err, IsNil)
  2013  			if t.isNil {
  2014  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  2015  			} else {
  2016  				c.Assert(d.GetInt64(), Equals, t.expected)
  2017  			}
  2018  		}
  2019  	}
  2020  	_, err := funcs[ast.Ord].getFunction(s.ctx, []Expression{NewZero()})
  2021  	c.Assert(err, IsNil)
  2022  }
  2023  
  2024  func (s *testEvaluatorSuite) TestElt(c *C) {
  2025  	tbl := []struct {
  2026  		argLst []interface{}
  2027  		ret    interface{}
  2028  	}{
  2029  		{[]interface{}{1, "Hej", "ej", "Heja", "hej", "foo"}, "Hej"},
  2030  		{[]interface{}{9, "Hej", "ej", "Heja", "hej", "foo"}, nil},
  2031  		{[]interface{}{-1, "Hej", "ej", "Heja", "ej", "hej", "foo"}, nil},
  2032  		{[]interface{}{0, 2, 3, 11, 1}, nil},
  2033  		{[]interface{}{3, 2, 3, 11, 1}, "11"},
  2034  		{[]interface{}{1.1, "2.1", "3.1", "11.1", "1.1"}, "2.1"},
  2035  	}
  2036  	for _, t := range tbl {
  2037  		fc := funcs[ast.Elt]
  2038  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.argLst...)))
  2039  		c.Assert(err, IsNil)
  2040  		r, err := evalBuiltinFunc(f, chunk.Event{})
  2041  		c.Assert(err, IsNil)
  2042  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret))
  2043  	}
  2044  }
  2045  
  2046  func (s *testEvaluatorSuite) TestExportSet(c *C) {
  2047  	estd := []struct {
  2048  		argLst []interface{}
  2049  		res    string
  2050  	}{
  2051  		{[]interface{}{-9223372036854775807, "Y", "N", ",", 5}, "Y,N,N,N,N"},
  2052  		{[]interface{}{-6, "Y", "N", ",", 5}, "N,Y,N,Y,Y"},
  2053  		{[]interface{}{5, "Y", "N", ",", 4}, "Y,N,Y,N"},
  2054  		{[]interface{}{5, "Y", "N", ",", 0}, ""},
  2055  		{[]interface{}{5, "Y", "N", ",", 1}, "Y"},
  2056  		{[]interface{}{6, "1", "0", ",", 10}, "0,1,1,0,0,0,0,0,0,0"},
  2057  		{[]interface{}{333333, "Ysss", "sN", "---", 9}, "Ysss---sN---Ysss---sN---Ysss---sN---sN---sN---sN"},
  2058  		{[]interface{}{7, "Y", "N"}, "Y,Y,Y,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N"},
  2059  		{[]interface{}{7, "Y", "N", 6}, "Y6Y6Y6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N"},
  2060  		{[]interface{}{7, "Y", "N", 6, 133}, "Y6Y6Y6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N"},
  2061  	}
  2062  	fc := funcs[ast.ExportSet]
  2063  	for _, t := range estd {
  2064  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.argLst...)))
  2065  		c.Assert(err, IsNil)
  2066  		c.Assert(f, NotNil)
  2067  		exportSetRes, err := evalBuiltinFunc(f, chunk.Event{})
  2068  		c.Assert(err, IsNil)
  2069  		res, err := exportSetRes.ToString()
  2070  		c.Assert(err, IsNil)
  2071  		c.Assert(res, Equals, t.res)
  2072  	}
  2073  }
  2074  
  2075  func (s *testEvaluatorSuite) TestBin(c *C) {
  2076  	tbl := []struct {
  2077  		Input    interface{}
  2078  		Expected interface{}
  2079  	}{
  2080  		{"10", "1010"},
  2081  		{"10.2", "1010"},
  2082  		{"10aa", "1010"},
  2083  		{"10.2aa", "1010"},
  2084  		{"aaa", "0"},
  2085  		{"", nil},
  2086  		{10, "1010"},
  2087  		{10.0, "1010"},
  2088  		{-1, "1111111111111111111111111111111111111111111111111111111111111111"},
  2089  		{"-1", "1111111111111111111111111111111111111111111111111111111111111111"},
  2090  		{nil, nil},
  2091  	}
  2092  	fc := funcs[ast.Bin]
  2093  	dtbl := tblToDtbl(tbl)
  2094  	ctx := mock.NewContext()
  2095  	ctx.GetStochastikVars().StmtCtx.IgnoreTruncate = true
  2096  	for _, t := range dtbl {
  2097  		f, err := fc.getFunction(ctx, s.datumsToConstants(t["Input"]))
  2098  		c.Assert(err, IsNil)
  2099  		c.Assert(f, NotNil)
  2100  		r, err := evalBuiltinFunc(f, chunk.Event{})
  2101  		c.Assert(err, IsNil)
  2102  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t["Expected"][0]))
  2103  	}
  2104  }
  2105  
  2106  func (s *testEvaluatorSuite) TestQuote(c *C) {
  2107  	tbl := []struct {
  2108  		arg interface{}
  2109  		ret interface{}
  2110  	}{
  2111  		{`Don\'t!`, `'Don\\\'t!'`},
  2112  		{`Don't`, `'Don\'t'`},
  2113  		{`Don"`, `'Don"'`},
  2114  		{`Don\"`, `'Don\\"'`},
  2115  		{`\'`, `'\\\''`},
  2116  		{`\"`, `'\\"'`},
  2117  		{`萌萌哒(๑•ᴗ•๑)😊`, `'萌萌哒(๑•ᴗ•๑)😊'`},
  2118  		{`㍿㌍㍑㌫`, `'㍿㌍㍑㌫'`},
  2119  		{string([]byte{0, 26}), `'\0\Z'`},
  2120  		{nil, "NULL"},
  2121  	}
  2122  
  2123  	for _, t := range tbl {
  2124  		fc := funcs[ast.Quote]
  2125  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.arg)))
  2126  		c.Assert(err, IsNil)
  2127  		c.Assert(f, NotNil)
  2128  		r, err := evalBuiltinFunc(f, chunk.Event{})
  2129  		c.Assert(err, IsNil)
  2130  		c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret))
  2131  	}
  2132  }
  2133  
  2134  func (s *testEvaluatorSuite) TestToBase64(c *C) {
  2135  	tests := []struct {
  2136  		args   interface{}
  2137  		expect string
  2138  		isNil  bool
  2139  		getErr bool
  2140  	}{
  2141  		{"", "", false, false},
  2142  		{"abc", "YWJj", false, false},
  2143  		{"ab c", "YWIgYw==", false, false},
  2144  		{1, "MQ==", false, false},
  2145  		{1.1, "MS4x", false, false},
  2146  		{"ab\nc", "YWIKYw==", false, false},
  2147  		{"ab\tc", "YWIJYw==", false, false},
  2148  		{"qwerty123456", "cXdlcnR5MTIzNDU2", false, false},
  2149  		{
  2150  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  2151  			"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrLw==",
  2152  			false,
  2153  			false,
  2154  		},
  2155  		{
  2156  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  2157  			"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrL0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4\neXowMTIzNDU2Nzg5Ky9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3Bx\ncnN0dXZ3eHl6MDEyMzQ1Njc4OSsv",
  2158  			false,
  2159  			false,
  2160  		},
  2161  		{
  2162  			"ABCD  EFGHI\nJKLMNOPQRSTUVWXY\tZabcdefghijklmnopqrstuv  wxyz012\r3456789+/",
  2163  			"QUJDRCAgRUZHSEkKSktMTU5PUFFSU1RVVldYWQlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1diAgd3h5\nejAxMg0zNDU2Nzg5Ky8=",
  2164  			false,
  2165  			false,
  2166  		},
  2167  		{nil, "", true, false},
  2168  	}
  2169  	if strconv.IntSize == 32 {
  2170  		tests = append(tests, struct {
  2171  			args   interface{}
  2172  			expect string
  2173  			isNil  bool
  2174  			getErr bool
  2175  		}{
  2176  			strings.Repeat("a", 1589695687),
  2177  			"",
  2178  			true,
  2179  			false,
  2180  		})
  2181  	}
  2182  
  2183  	for _, test := range tests {
  2184  		f, err := newFunctionForTest(s.ctx, ast.ToBase64, s.primitiveValsToConstants([]interface{}{test.args})...)
  2185  		c.Assert(err, IsNil)
  2186  		d, err := f.Eval(chunk.Event{})
  2187  		if test.getErr {
  2188  			c.Assert(err, NotNil)
  2189  		} else {
  2190  			c.Assert(err, IsNil)
  2191  			if test.isNil {
  2192  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  2193  			} else {
  2194  				c.Assert(d.GetString(), Equals, test.expect)
  2195  			}
  2196  		}
  2197  	}
  2198  
  2199  	_, err := funcs[ast.ToBase64].getFunction(s.ctx, []Expression{NewZero()})
  2200  	c.Assert(err, IsNil)
  2201  }
  2202  
  2203  func (s *testEvaluatorSuite) TestToBase64Sig(c *C) {
  2204  	defCausTypes := []*types.FieldType{
  2205  		{Tp: allegrosql.TypeVarchar},
  2206  	}
  2207  
  2208  	tests := []struct {
  2209  		args           string
  2210  		expect         string
  2211  		isNil          bool
  2212  		maxAllowPacket uint64
  2213  	}{
  2214  		{"abc", "YWJj", false, 4},
  2215  		{"abc", "", true, 3},
  2216  		{
  2217  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  2218  			"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrLw==",
  2219  			false,
  2220  			89,
  2221  		},
  2222  		{
  2223  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  2224  			"",
  2225  			true,
  2226  			88,
  2227  		},
  2228  		{
  2229  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  2230  			"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrL0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4\neXowMTIzNDU2Nzg5Ky9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3Bx\ncnN0dXZ3eHl6MDEyMzQ1Njc4OSsv",
  2231  			false,
  2232  			259,
  2233  		},
  2234  		{
  2235  			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  2236  			"",
  2237  			true,
  2238  			258,
  2239  		},
  2240  	}
  2241  
  2242  	args := []Expression{
  2243  		&DeferredCauset{Index: 0, RetType: defCausTypes[0]},
  2244  	}
  2245  
  2246  	for _, test := range tests {
  2247  		resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: base64NeededEncodedLength(len(test.args))}
  2248  		base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
  2249  		toBase64 := &builtinToBase64Sig{base, test.maxAllowPacket}
  2250  
  2251  		input := chunk.NewChunkWithCapacity(defCausTypes, 1)
  2252  		input.AppendString(0, test.args)
  2253  		res, isNull, err := toBase64.evalString(input.GetEvent(0))
  2254  		c.Assert(err, IsNil)
  2255  		if test.isNil {
  2256  			c.Assert(isNull, IsTrue)
  2257  
  2258  			warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  2259  			c.Assert(len(warnings), Equals, 1)
  2260  			lastWarn := warnings[len(warnings)-1]
  2261  			c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue)
  2262  			s.ctx.GetStochastikVars().StmtCtx.SetWarnings([]stmtctx.ALLEGROSQLWarn{})
  2263  
  2264  		} else {
  2265  			c.Assert(isNull, IsFalse)
  2266  		}
  2267  		c.Assert(res, Equals, test.expect)
  2268  	}
  2269  }
  2270  
  2271  func (s *testEvaluatorSuite) TestStringRight(c *C) {
  2272  	fc := funcs[ast.Right]
  2273  	tests := []struct {
  2274  		str    interface{}
  2275  		length interface{}
  2276  		expect interface{}
  2277  	}{
  2278  		{"helloworld", 5, "world"},
  2279  		{"helloworld", 10, "helloworld"},
  2280  		{"helloworld", 11, "helloworld"},
  2281  		{"helloworld", -1, ""},
  2282  		{"", 2, ""},
  2283  		{nil, 2, nil},
  2284  	}
  2285  
  2286  	for _, test := range tests {
  2287  		str := types.NewCauset(test.str)
  2288  		length := types.NewCauset(test.length)
  2289  		f, _ := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, length}))
  2290  		result, err := evalBuiltinFunc(f, chunk.Event{})
  2291  		c.Assert(err, IsNil)
  2292  		if result.IsNull() {
  2293  			c.Assert(test.expect, IsNil)
  2294  			continue
  2295  		}
  2296  		res, err := result.ToString()
  2297  		c.Assert(err, IsNil)
  2298  		c.Assert(res, Equals, test.expect)
  2299  	}
  2300  }
  2301  
  2302  func (s *testEvaluatorSuite) TestWeightString(c *C) {
  2303  	fc := funcs[ast.WeightString]
  2304  	tests := []struct {
  2305  		expr    interface{}
  2306  		padding string
  2307  		length  int
  2308  		expect  interface{}
  2309  	}{
  2310  		{nil, "NONE", 0, nil},
  2311  		{7, "NONE", 0, nil},
  2312  		{7.0, "NONE", 0, nil},
  2313  		{"a", "NONE", 0, "a"},
  2314  		{"a ", "NONE", 0, "a "},
  2315  		{"中", "NONE", 0, "中"},
  2316  		{"中 ", "NONE", 0, "中 "},
  2317  		{nil, "CHAR", 5, nil},
  2318  		{7, "CHAR", 5, nil},
  2319  		{7.0, "NONE", 0, nil},
  2320  		{"a", "CHAR", 5, "a    "},
  2321  		{"a ", "CHAR", 5, "a    "},
  2322  		{"中", "CHAR", 5, "中    "},
  2323  		{"中 ", "CHAR", 5, "中    "},
  2324  		{nil, "BINARY", 5, nil},
  2325  		{7, "BINARY", 2, "7\x00"},
  2326  		{7.0, "NONE", 0, nil},
  2327  		{"a", "BINARY", 1, "a"},
  2328  		{"ab", "BINARY", 1, "a"},
  2329  		{"a", "BINARY", 5, "a\x00\x00\x00\x00"},
  2330  		{"a ", "BINARY", 5, "a \x00\x00\x00"},
  2331  		{"中", "BINARY", 1, "\xe4"},
  2332  		{"中", "BINARY", 2, "\xe4\xb8"},
  2333  		{"中", "BINARY", 3, "中"},
  2334  		{"中", "BINARY", 5, "中\x00\x00"},
  2335  	}
  2336  
  2337  	for _, test := range tests {
  2338  		str := types.NewCauset(test.expr)
  2339  		var f builtinFunc
  2340  		var err error
  2341  		if test.padding == "NONE" {
  2342  			f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str}))
  2343  		} else {
  2344  			padding := types.NewCauset(test.padding)
  2345  			length := types.NewCauset(test.length)
  2346  			f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, padding, length}))
  2347  		}
  2348  		c.Assert(err, IsNil)
  2349  		// Reset warnings.
  2350  		s.ctx.GetStochastikVars().StmtCtx.ResetForRetry()
  2351  		result, err := evalBuiltinFunc(f, chunk.Event{})
  2352  		c.Assert(err, IsNil)
  2353  		if result.IsNull() {
  2354  			c.Assert(test.expect, IsNil)
  2355  			continue
  2356  		}
  2357  		res, err := result.ToString()
  2358  		c.Assert(err, IsNil)
  2359  		c.Assert(res, Equals, test.expect)
  2360  		if test.expr == nil {
  2361  			continue
  2362  		}
  2363  		strExpr := fmt.Sprintf("%v", test.expr)
  2364  		if test.padding == "BINARY" && test.length < len(strExpr) {
  2365  			expectWarn := fmt.Sprintf("[memex:1292]Truncated incorrect BINARY(%d) value: '%s'", test.length, strExpr)
  2366  			obtainedWarns := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  2367  			c.Assert(len(obtainedWarns), Equals, 1)
  2368  			c.Assert(obtainedWarns[0].Level, Equals, "Warning")
  2369  			c.Assert(obtainedWarns[0].Err.Error(), Equals, expectWarn)
  2370  		}
  2371  	}
  2372  }
  2373  
  2374  func (s *testEvaluatorSerialSuites) TestCIWeightString(c *C) {
  2375  	defCauslate.SetNewDefCauslationEnabledForTest(true)
  2376  	defer defCauslate.SetNewDefCauslationEnabledForTest(false)
  2377  
  2378  	type weightStringTest struct {
  2379  		str     string
  2380  		padding string
  2381  		length  int
  2382  		expect  interface{}
  2383  	}
  2384  
  2385  	checkResult := func(defCauslation string, tests []weightStringTest) {
  2386  		fc := funcs[ast.WeightString]
  2387  		for _, test := range tests {
  2388  			str := types.NewDefCauslationStringCauset(test.str, defCauslation, utf8.RuneCountInString(test.str))
  2389  			var f builtinFunc
  2390  			var err error
  2391  			if test.padding == "NONE" {
  2392  				f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str}))
  2393  			} else {
  2394  				padding := types.NewCauset(test.padding)
  2395  				length := types.NewCauset(test.length)
  2396  				f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, padding, length}))
  2397  			}
  2398  			c.Assert(err, IsNil)
  2399  			result, err := evalBuiltinFunc(f, chunk.Event{})
  2400  			c.Assert(err, IsNil)
  2401  			if result.IsNull() {
  2402  				c.Assert(test.expect, IsNil)
  2403  				continue
  2404  			}
  2405  			res, err := result.ToString()
  2406  			c.Assert(err, IsNil)
  2407  			c.Assert(res, Equals, test.expect)
  2408  		}
  2409  	}
  2410  
  2411  	generalTests := []weightStringTest{
  2412  		{"aAÁàãăâ", "NONE", 0, "\x00A\x00A\x00A\x00A\x00A\x00A\x00A"},
  2413  		{"中", "NONE", 0, "\x4E\x2D"},
  2414  		{"a", "CHAR", 5, "\x00A"},
  2415  		{"a ", "CHAR", 5, "\x00A"},
  2416  		{"中", "CHAR", 5, "\x4E\x2D"},
  2417  		{"中 ", "CHAR", 5, "\x4E\x2D"},
  2418  		{"a", "BINARY", 1, "a"},
  2419  		{"ab", "BINARY", 1, "a"},
  2420  		{"a", "BINARY", 5, "a\x00\x00\x00\x00"},
  2421  		{"a ", "BINARY", 5, "a \x00\x00\x00"},
  2422  		{"中", "BINARY", 1, "\xe4"},
  2423  		{"中", "BINARY", 2, "\xe4\xb8"},
  2424  		{"中", "BINARY", 3, "中"},
  2425  		{"中", "BINARY", 5, "中\x00\x00"},
  2426  	}
  2427  
  2428  	unicodeTests := []weightStringTest{
  2429  		{"aAÁàãăâ", "NONE", 0, "\x0e3\x0e3\x0e3\x0e3\x0e3\x0e3\x0e3"},
  2430  		{"中", "NONE", 0, "\xfb\x40\xce\x2d"},
  2431  		{"a", "CHAR", 5, "\x0e3"},
  2432  		{"a ", "CHAR", 5, "\x0e3"},
  2433  		{"中", "CHAR", 5, "\xfb\x40\xce\x2d"},
  2434  		{"中 ", "CHAR", 5, "\xfb\x40\xce\x2d"},
  2435  		{"a", "BINARY", 1, "a"},
  2436  		{"ab", "BINARY", 1, "a"},
  2437  		{"a", "BINARY", 5, "a\x00\x00\x00\x00"},
  2438  		{"a ", "BINARY", 5, "a \x00\x00\x00"},
  2439  		{"中", "BINARY", 1, "\xe4"},
  2440  		{"中", "BINARY", 2, "\xe4\xb8"},
  2441  		{"中", "BINARY", 3, "中"},
  2442  		{"中", "BINARY", 5, "中\x00\x00"},
  2443  	}
  2444  
  2445  	checkResult("utf8mb4_general_ci", generalTests)
  2446  	checkResult("utf8mb4_unicode_ci", unicodeTests)
  2447  }