github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/expr_to_pb_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  	"encoding/json"
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/gogo/protobuf/proto"
    22  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    23  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    24  	"github.com/whtcorpsinc/BerolinaSQL/charset"
    25  	. "github.com/whtcorpsinc/check"
    26  	"github.com/whtcorpsinc/errors"
    27  	"github.com/whtcorpsinc/failpoint"
    28  	"github.com/whtcorpsinc/fidelpb/go-fidelpb"
    29  	"github.com/whtcorpsinc/milevadb/ekv"
    30  	"github.com/whtcorpsinc/milevadb/soliton/defCauslate"
    31  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    32  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    33  	"github.com/whtcorpsinc/milevadb/types"
    34  )
    35  
    36  func init() {
    37  	fpname := "github.com/whtcorpsinc/milevadb/memex/PanicIfPbCodeUnspecified"
    38  	err := failpoint.Enable(fpname, "return(true)")
    39  	if err != nil {
    40  		panic(errors.Errorf("enable global failpoint `%s` failed: %v", fpname, err))
    41  	}
    42  }
    43  
    44  type dataGen4Expr2PbTest struct {
    45  }
    46  
    47  func (dg *dataGen4Expr2PbTest) genDeferredCauset(tp byte, id int64) *DeferredCauset {
    48  	return &DeferredCauset{
    49  		RetType: types.NewFieldType(tp),
    50  		ID:      id,
    51  		Index:   int(id),
    52  	}
    53  }
    54  
    55  func (s *testEvaluatorSuite) TestConstant2Pb(c *C) {
    56  	c.Skip("constant pb has changed")
    57  	var constExprs []Expression
    58  	sc := new(stmtctx.StatementContext)
    59  	client := new(mock.Client)
    60  
    61  	// can be transformed
    62  	constValue := new(Constant)
    63  	constValue.Value = types.NewCauset(nil)
    64  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTNull)
    65  	constExprs = append(constExprs, constValue)
    66  
    67  	constValue = new(Constant)
    68  	constValue.Value = types.NewCauset(int64(100))
    69  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTInt64)
    70  	constExprs = append(constExprs, constValue)
    71  
    72  	constValue = new(Constant)
    73  	constValue.Value = types.NewCauset(uint64(100))
    74  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTUint64)
    75  	constExprs = append(constExprs, constValue)
    76  
    77  	constValue = new(Constant)
    78  	constValue.Value = types.NewCauset("100")
    79  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTString)
    80  	constExprs = append(constExprs, constValue)
    81  
    82  	constValue = new(Constant)
    83  	constValue.Value = types.NewCauset([]byte{'1', '2', '4', 'c'})
    84  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTBytes)
    85  	constExprs = append(constExprs, constValue)
    86  
    87  	constValue = new(Constant)
    88  	constValue.Value = types.NewCauset(types.NewDecFromInt(110))
    89  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTMysqlDecimal)
    90  	constExprs = append(constExprs, constValue)
    91  
    92  	constValue = new(Constant)
    93  	constValue.Value = types.NewCauset(types.Duration{})
    94  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTMysqlDuration)
    95  	constExprs = append(constExprs, constValue)
    96  
    97  	// can not be transformed
    98  	constValue = new(Constant)
    99  	constValue.Value = types.NewCauset(float32(100))
   100  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTFloat32)
   101  	constExprs = append(constExprs, constValue)
   102  
   103  	constValue = new(Constant)
   104  	constValue.Value = types.NewCauset(float64(100))
   105  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTFloat64)
   106  	constExprs = append(constExprs, constValue)
   107  
   108  	constValue = new(Constant)
   109  	constValue.Value = types.NewCauset(types.Enum{Name: "A", Value: 19})
   110  	c.Assert(constValue.Value.HoTT(), Equals, types.HoTTMysqlEnum)
   111  	constExprs = append(constExprs, constValue)
   112  
   113  	pushed, remained := PushDownExprs(sc, constExprs, client, ekv.UnSpecified)
   114  	c.Assert(len(pushed), Equals, len(constExprs)-3)
   115  	c.Assert(len(remained), Equals, 3)
   116  
   117  	pbExprs, err := ExpressionsToPBList(sc, constExprs, client)
   118  	c.Assert(err, IsNil)
   119  	jsons := []string{
   120  		"{\"tp\":0,\"sig\":0}",
   121  		"{\"tp\":1,\"val\":\"gAAAAAAAAGQ=\",\"sig\":0}",
   122  		"{\"tp\":2,\"val\":\"AAAAAAAAAGQ=\",\"sig\":0}",
   123  		"{\"tp\":5,\"val\":\"MTAw\",\"sig\":0}",
   124  		"{\"tp\":6,\"val\":\"MTI0Yw==\",\"sig\":0}",
   125  		"{\"tp\":102,\"val\":\"AwCAbg==\",\"sig\":0}",
   126  		"{\"tp\":103,\"val\":\"gAAAAAAAAAA=\",\"sig\":0}",
   127  	}
   128  	for i, pbExpr := range pbExprs {
   129  		if i+3 < len(pbExprs) {
   130  			js, err := json.Marshal(pbExpr)
   131  			c.Assert(err, IsNil)
   132  			c.Assert(string(js), Equals, jsons[i])
   133  		} else {
   134  			c.Assert(pbExpr, IsNil)
   135  		}
   136  	}
   137  }
   138  
   139  func (s *testEvaluatorSuite) TestDeferredCauset2Pb(c *C) {
   140  	var defCausExprs []Expression
   141  	sc := new(stmtctx.StatementContext)
   142  	client := new(mock.Client)
   143  	dg := new(dataGen4Expr2PbTest)
   144  
   145  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeBit, 1))
   146  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeSet, 2))
   147  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeEnum, 3))
   148  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeGeometry, 4))
   149  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeUnspecified, 5))
   150  
   151  	pushed, remained := PushDownExprs(sc, defCausExprs, client, ekv.UnSpecified)
   152  	c.Assert(len(pushed), Equals, 0)
   153  	c.Assert(len(remained), Equals, len(defCausExprs))
   154  
   155  	for _, defCaus := range defCausExprs { // cannot be pushed down
   156  		_, err := ExpressionsToPBList(sc, []Expression{defCaus}, client)
   157  		c.Assert(err, NotNil)
   158  	}
   159  
   160  	defCausExprs = defCausExprs[:0]
   161  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeTiny, 1))
   162  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeShort, 2))
   163  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeLong, 3))
   164  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeFloat, 4))
   165  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeDouble, 5))
   166  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeNull, 6))
   167  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeTimestamp, 7))
   168  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeLonglong, 8))
   169  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeInt24, 9))
   170  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeDate, 10))
   171  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeDuration, 11))
   172  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeDatetime, 12))
   173  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeYear, 13))
   174  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeVarchar, 15))
   175  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeJSON, 16))
   176  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeNewDecimal, 17))
   177  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeTinyBlob, 18))
   178  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeMediumBlob, 19))
   179  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeLongBlob, 20))
   180  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeBlob, 21))
   181  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeVarString, 22))
   182  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeString, 23))
   183  	pushed, remained = PushDownExprs(sc, defCausExprs, client, ekv.UnSpecified)
   184  	c.Assert(len(pushed), Equals, len(defCausExprs))
   185  	c.Assert(len(remained), Equals, 0)
   186  
   187  	pbExprs, err := ExpressionsToPBList(sc, defCausExprs, client)
   188  	c.Assert(err, IsNil)
   189  	jsons := []string{
   190  		"{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":1,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   191  		"{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":2,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   192  		"{\"tp\":201,\"val\":\"gAAAAAAAAAM=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   193  		"{\"tp\":201,\"val\":\"gAAAAAAAAAQ=\",\"sig\":0,\"field_type\":{\"tp\":4,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   194  		"{\"tp\":201,\"val\":\"gAAAAAAAAAU=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   195  		"{\"tp\":201,\"val\":\"gAAAAAAAAAY=\",\"sig\":0,\"field_type\":{\"tp\":6,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   196  		"{\"tp\":201,\"val\":\"gAAAAAAAAAc=\",\"sig\":0,\"field_type\":{\"tp\":7,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   197  		"{\"tp\":201,\"val\":\"gAAAAAAAAAg=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   198  		"{\"tp\":201,\"val\":\"gAAAAAAAAAk=\",\"sig\":0,\"field_type\":{\"tp\":9,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   199  		"{\"tp\":201,\"val\":\"gAAAAAAAAAo=\",\"sig\":0,\"field_type\":{\"tp\":10,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   200  		"{\"tp\":201,\"val\":\"gAAAAAAAAAs=\",\"sig\":0,\"field_type\":{\"tp\":11,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   201  		"{\"tp\":201,\"val\":\"gAAAAAAAAAw=\",\"sig\":0,\"field_type\":{\"tp\":12,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   202  		"{\"tp\":201,\"val\":\"gAAAAAAAAA0=\",\"sig\":0,\"field_type\":{\"tp\":13,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   203  		"{\"tp\":201,\"val\":\"gAAAAAAAAA8=\",\"sig\":0,\"field_type\":{\"tp\":15,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":46,\"charset\":\"\"}}",
   204  		"{\"tp\":201,\"val\":\"gAAAAAAAABA=\",\"sig\":0,\"field_type\":{\"tp\":245,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   205  		"{\"tp\":201,\"val\":\"gAAAAAAAABE=\",\"sig\":0,\"field_type\":{\"tp\":246,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   206  		"{\"tp\":201,\"val\":\"gAAAAAAAABI=\",\"sig\":0,\"field_type\":{\"tp\":249,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   207  		"{\"tp\":201,\"val\":\"gAAAAAAAABM=\",\"sig\":0,\"field_type\":{\"tp\":250,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   208  		"{\"tp\":201,\"val\":\"gAAAAAAAABQ=\",\"sig\":0,\"field_type\":{\"tp\":251,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   209  		"{\"tp\":201,\"val\":\"gAAAAAAAABU=\",\"sig\":0,\"field_type\":{\"tp\":252,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   210  		"{\"tp\":201,\"val\":\"gAAAAAAAABY=\",\"sig\":0,\"field_type\":{\"tp\":253,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":46,\"charset\":\"\"}}",
   211  		"{\"tp\":201,\"val\":\"gAAAAAAAABc=\",\"sig\":0,\"field_type\":{\"tp\":254,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":46,\"charset\":\"\"}}",
   212  	}
   213  	for i, pbExpr := range pbExprs {
   214  		c.Assert(pbExprs, NotNil)
   215  		js, err := json.Marshal(pbExpr)
   216  		c.Assert(err, IsNil)
   217  		c.Assert(string(js), Equals, jsons[i], Commentf("%v\n", i))
   218  	}
   219  
   220  	for _, expr := range defCausExprs {
   221  		expr.(*DeferredCauset).ID = 0
   222  		expr.(*DeferredCauset).Index = 0
   223  	}
   224  
   225  	pushed, remained = PushDownExprs(sc, defCausExprs, client, ekv.UnSpecified)
   226  	c.Assert(len(pushed), Equals, len(defCausExprs))
   227  	c.Assert(len(remained), Equals, 0)
   228  }
   229  
   230  func (s *testEvaluatorSuite) TestCompareFunc2Pb(c *C) {
   231  	var compareExprs = make([]Expression, 0)
   232  	sc := new(stmtctx.StatementContext)
   233  	client := new(mock.Client)
   234  	dg := new(dataGen4Expr2PbTest)
   235  
   236  	funcNames := []string{ast.LT, ast.LE, ast.GT, ast.GE, ast.EQ, ast.NE, ast.NullEQ}
   237  	for _, funcName := range funcNames {
   238  		fc, err := NewFunction(mock.NewContext(), funcName, types.NewFieldType(allegrosql.TypeUnspecified), dg.genDeferredCauset(allegrosql.TypeLonglong, 1), dg.genDeferredCauset(allegrosql.TypeLonglong, 2))
   239  		c.Assert(err, IsNil)
   240  		compareExprs = append(compareExprs, fc)
   241  	}
   242  
   243  	pushed, remained := PushDownExprs(sc, compareExprs, client, ekv.UnSpecified)
   244  	c.Assert(len(pushed), Equals, len(compareExprs))
   245  	c.Assert(len(remained), Equals, 0)
   246  
   247  	pbExprs, err := ExpressionsToPBList(sc, compareExprs, client)
   248  	c.Assert(err, IsNil)
   249  	c.Assert(len(pbExprs), Equals, len(compareExprs))
   250  	jsons := []string{
   251  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":100,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   252  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":110,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   253  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":120,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   254  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":130,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   255  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":140,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   256  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":150,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   257  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":8,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":160,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   258  	}
   259  	for i, pbExpr := range pbExprs {
   260  		c.Assert(pbExprs, NotNil)
   261  		js, err := json.Marshal(pbExpr)
   262  		c.Assert(err, IsNil)
   263  		c.Assert(string(js), Equals, jsons[i])
   264  	}
   265  }
   266  
   267  func (s *testEvaluatorSuite) TestLikeFunc2Pb(c *C) {
   268  	var likeFuncs []Expression
   269  	sc := new(stmtctx.StatementContext)
   270  	client := new(mock.Client)
   271  
   272  	retTp := types.NewFieldType(allegrosql.TypeString)
   273  	retTp.Charset = charset.CharsetUTF8
   274  	retTp.DefCauslate = charset.DefCauslationUTF8
   275  	args := []Expression{
   276  		&Constant{RetType: retTp, Value: types.NewCauset("string")},
   277  		&Constant{RetType: retTp, Value: types.NewCauset("pattern")},
   278  		&Constant{RetType: retTp, Value: types.NewCauset(`%abc%`)},
   279  		&Constant{RetType: retTp, Value: types.NewCauset("\\")},
   280  	}
   281  	ctx := mock.NewContext()
   282  	retTp = types.NewFieldType(allegrosql.TypeUnspecified)
   283  	fc, err := NewFunction(ctx, ast.Like, retTp, args[0], args[1], args[3])
   284  	c.Assert(err, IsNil)
   285  	likeFuncs = append(likeFuncs, fc)
   286  
   287  	fc, err = NewFunction(ctx, ast.Like, retTp, args[0], args[2], args[3])
   288  	c.Assert(err, IsNil)
   289  	likeFuncs = append(likeFuncs, fc)
   290  
   291  	pbExprs, err := ExpressionsToPBList(sc, likeFuncs, client)
   292  	c.Assert(err, IsNil)
   293  	results := []string{
   294  		`{"tp":10000,"children":[{"tp":5,"val":"c3RyaW5n","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"defCauslate":83,"charset":"utf8"}},{"tp":5,"val":"cGF0dGVybg==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"defCauslate":83,"charset":"utf8"}},{"tp":10000,"val":"CAA=","children":[{"tp":5,"val":"XA==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"defCauslate":83,"charset":"utf8"}}],"sig":30,"field_type":{"tp":8,"flag":128,"flen":-1,"decimal":0,"defCauslate":63,"charset":"binary"}}],"sig":4310,"field_type":{"tp":8,"flag":128,"flen":1,"decimal":0,"defCauslate":63,"charset":"binary"}}`,
   295  		`{"tp":10000,"children":[{"tp":5,"val":"c3RyaW5n","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"defCauslate":83,"charset":"utf8"}},{"tp":5,"val":"JWFiYyU=","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"defCauslate":83,"charset":"utf8"}},{"tp":10000,"val":"CAA=","children":[{"tp":5,"val":"XA==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"defCauslate":83,"charset":"utf8"}}],"sig":30,"field_type":{"tp":8,"flag":128,"flen":-1,"decimal":0,"defCauslate":63,"charset":"binary"}}],"sig":4310,"field_type":{"tp":8,"flag":128,"flen":1,"decimal":0,"defCauslate":63,"charset":"binary"}}`,
   296  	}
   297  	for i, pbExpr := range pbExprs {
   298  		js, err := json.Marshal(pbExpr)
   299  		c.Assert(err, IsNil)
   300  		c.Assert(string(js), Equals, results[i])
   301  	}
   302  }
   303  
   304  func (s *testEvaluatorSuite) TestArithmeticalFunc2Pb(c *C) {
   305  	var arithmeticalFuncs = make([]Expression, 0)
   306  	sc := new(stmtctx.StatementContext)
   307  	client := new(mock.Client)
   308  	dg := new(dataGen4Expr2PbTest)
   309  
   310  	funcNames := []string{ast.Plus, ast.Minus, ast.Mul, ast.Div}
   311  	for _, funcName := range funcNames {
   312  		fc, err := NewFunction(
   313  			mock.NewContext(),
   314  			funcName,
   315  			types.NewFieldType(allegrosql.TypeUnspecified),
   316  			dg.genDeferredCauset(allegrosql.TypeDouble, 1),
   317  			dg.genDeferredCauset(allegrosql.TypeDouble, 2))
   318  		c.Assert(err, IsNil)
   319  		arithmeticalFuncs = append(arithmeticalFuncs, fc)
   320  	}
   321  
   322  	jsons := make(map[string]string)
   323  	jsons[ast.Plus] = "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":200,\"field_type\":{\"tp\":5,\"flag\":128,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"binary\"}}"
   324  	jsons[ast.Minus] = "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":204,\"field_type\":{\"tp\":5,\"flag\":128,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"binary\"}}"
   325  	jsons[ast.Mul] = "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":208,\"field_type\":{\"tp\":5,\"flag\":128,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"binary\"}}"
   326  	jsons[ast.Div] = "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":211,\"field_type\":{\"tp\":5,\"flag\":128,\"flen\":23,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"binary\"}}"
   327  
   328  	pbExprs, err := ExpressionsToPBList(sc, arithmeticalFuncs, client)
   329  	c.Assert(err, IsNil)
   330  	for i, pbExpr := range pbExprs {
   331  		c.Assert(pbExpr, NotNil)
   332  		js, err := json.Marshal(pbExpr)
   333  		c.Assert(err, IsNil)
   334  		c.Assert(string(js), Equals, jsons[funcNames[i]], Commentf("%v\n", funcNames[i]))
   335  	}
   336  
   337  	funcNames = []string{ast.Mod, ast.IntDiv} // cannot be pushed down
   338  	for _, funcName := range funcNames {
   339  		fc, err := NewFunction(
   340  			mock.NewContext(),
   341  			funcName,
   342  			types.NewFieldType(allegrosql.TypeUnspecified),
   343  			dg.genDeferredCauset(allegrosql.TypeDouble, 1),
   344  			dg.genDeferredCauset(allegrosql.TypeDouble, 2))
   345  		c.Assert(err, IsNil)
   346  		_, err = ExpressionsToPBList(sc, []Expression{fc}, client)
   347  		c.Assert(err, NotNil)
   348  	}
   349  }
   350  
   351  func (s *testEvaluatorSuite) TestDateFunc2Pb(c *C) {
   352  	sc := new(stmtctx.StatementContext)
   353  	client := new(mock.Client)
   354  	dg := new(dataGen4Expr2PbTest)
   355  	fc, err := NewFunction(
   356  		mock.NewContext(),
   357  		ast.DateFormat,
   358  		types.NewFieldType(allegrosql.TypeUnspecified),
   359  		dg.genDeferredCauset(allegrosql.TypeDatetime, 1),
   360  		dg.genDeferredCauset(allegrosql.TypeString, 2))
   361  	c.Assert(err, IsNil)
   362  	funcs := []Expression{fc}
   363  	pbExprs, err := ExpressionsToPBList(sc, funcs, client)
   364  	c.Assert(err, IsNil)
   365  	c.Assert(pbExprs[0], NotNil)
   366  	js, err := json.Marshal(pbExprs[0])
   367  	c.Assert(err, IsNil)
   368  	c.Assert(string(js), Equals, "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":12,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":254,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":46,\"charset\":\"\"}}],\"sig\":6001,\"field_type\":{\"tp\":253,\"flag\":0,\"flen\":0,\"decimal\":-1,\"defCauslate\":46,\"charset\":\"utf8mb4\"}}")
   369  }
   370  
   371  func (s *testEvaluatorSuite) TestLogicalFunc2Pb(c *C) {
   372  	var logicalFuncs = make([]Expression, 0)
   373  	sc := new(stmtctx.StatementContext)
   374  	client := new(mock.Client)
   375  	dg := new(dataGen4Expr2PbTest)
   376  
   377  	funcNames := []string{ast.LogicAnd, ast.LogicOr, ast.LogicXor, ast.UnaryNot}
   378  	for i, funcName := range funcNames {
   379  		args := []Expression{dg.genDeferredCauset(allegrosql.TypeTiny, 1)}
   380  		if i+1 < len(funcNames) {
   381  			args = append(args, dg.genDeferredCauset(allegrosql.TypeTiny, 2))
   382  		}
   383  		fc, err := NewFunction(
   384  			mock.NewContext(),
   385  			funcName,
   386  			types.NewFieldType(allegrosql.TypeUnspecified),
   387  			args...,
   388  		)
   389  		c.Assert(err, IsNil)
   390  		logicalFuncs = append(logicalFuncs, fc)
   391  	}
   392  
   393  	pbExprs, err := ExpressionsToPBList(sc, logicalFuncs, client)
   394  	c.Assert(err, IsNil)
   395  	jsons := []string{
   396  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":1,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":1,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3101,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   397  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":1,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":1,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3102,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   398  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":1,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":1,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3103,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   399  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":1,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3104,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   400  	}
   401  	for i, pbExpr := range pbExprs {
   402  		js, err := json.Marshal(pbExpr)
   403  		c.Assert(err, IsNil)
   404  		c.Assert(string(js), Equals, jsons[i])
   405  	}
   406  }
   407  
   408  func (s *testEvaluatorSuite) TestBitwiseFunc2Pb(c *C) {
   409  	var bitwiseFuncs = make([]Expression, 0)
   410  	sc := new(stmtctx.StatementContext)
   411  	client := new(mock.Client)
   412  	dg := new(dataGen4Expr2PbTest)
   413  
   414  	funcNames := []string{ast.And, ast.Or, ast.Xor, ast.LeftShift, ast.RightShift, ast.BitNeg}
   415  	for i, funcName := range funcNames {
   416  		args := []Expression{dg.genDeferredCauset(allegrosql.TypeLong, 1)}
   417  		if i+1 < len(funcNames) {
   418  			args = append(args, dg.genDeferredCauset(allegrosql.TypeLong, 2))
   419  		}
   420  		fc, err := NewFunction(
   421  			mock.NewContext(),
   422  			funcName,
   423  			types.NewFieldType(allegrosql.TypeUnspecified),
   424  			args...,
   425  		)
   426  		c.Assert(err, IsNil)
   427  		bitwiseFuncs = append(bitwiseFuncs, fc)
   428  	}
   429  
   430  	pbExprs, err := ExpressionsToPBList(sc, bitwiseFuncs, client)
   431  	c.Assert(err, IsNil)
   432  	jsons := []string{
   433  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3118,\"field_type\":{\"tp\":8,\"flag\":160,\"flen\":20,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   434  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3119,\"field_type\":{\"tp\":8,\"flag\":160,\"flen\":20,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   435  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3120,\"field_type\":{\"tp\":8,\"flag\":160,\"flen\":20,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   436  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3129,\"field_type\":{\"tp\":8,\"flag\":160,\"flen\":20,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   437  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3130,\"field_type\":{\"tp\":8,\"flag\":160,\"flen\":20,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   438  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3121,\"field_type\":{\"tp\":8,\"flag\":160,\"flen\":20,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   439  	}
   440  	for i, pbExpr := range pbExprs {
   441  		js, err := json.Marshal(pbExpr)
   442  		c.Assert(err, IsNil)
   443  		c.Assert(string(js), Equals, jsons[i])
   444  	}
   445  }
   446  
   447  func (s *testEvaluatorSerialSuites) TestPanicIfPbCodeUnspecified(c *C) {
   448  	dg := new(dataGen4Expr2PbTest)
   449  	args := []Expression{dg.genDeferredCauset(allegrosql.TypeLong, 1), dg.genDeferredCauset(allegrosql.TypeLong, 2)}
   450  	fc, err := NewFunction(
   451  		mock.NewContext(),
   452  		ast.And,
   453  		types.NewFieldType(allegrosql.TypeUnspecified),
   454  		args...,
   455  	)
   456  	c.Assert(err, IsNil)
   457  	fn := fc.(*ScalarFunction)
   458  	fn.Function.setPbCode(fidelpb.ScalarFuncSig_Unspecified)
   459  	c.Assert(fn.Function.PbCode(), Equals, fidelpb.ScalarFuncSig_Unspecified)
   460  
   461  	pc := PbConverter{client: new(mock.Client), sc: new(stmtctx.StatementContext)}
   462  	c.Assert(func() { pc.ExprToPB(fn) }, PanicMatches, "unspecified PbCode: .*")
   463  }
   464  
   465  func (s *testEvaluatorSerialSuites) TestPushDownSwitcher(c *C) {
   466  	var funcs = make([]Expression, 0)
   467  	sc := new(stmtctx.StatementContext)
   468  	client := new(mock.Client)
   469  	dg := new(dataGen4Expr2PbTest)
   470  
   471  	cases := []struct {
   472  		name   string
   473  		sig    fidelpb.ScalarFuncSig
   474  		enable bool
   475  	}{
   476  		// Note that so far ScalarFuncSigs here are not be pushed down when the failpoint PushDownTestSwitcher
   477  		// is disable, which is the prerequisite to pass this test.
   478  		// Need to be replaced with other non pushed down ScalarFuncSigs if they are pushed down one day.
   479  		{ast.Sin, fidelpb.ScalarFuncSig_Sin, true},
   480  		{ast.Cos, fidelpb.ScalarFuncSig_Cos, false},
   481  		{ast.Tan, fidelpb.ScalarFuncSig_Tan, true},
   482  	}
   483  	var enabled []string
   484  	for _, funcName := range cases {
   485  		args := []Expression{dg.genDeferredCauset(allegrosql.TypeLong, 1)}
   486  		fc, err := NewFunction(
   487  			mock.NewContext(),
   488  			funcName.name,
   489  			types.NewFieldType(allegrosql.TypeUnspecified),
   490  			args...,
   491  		)
   492  		c.Assert(err, IsNil)
   493  		funcs = append(funcs, fc)
   494  		if funcName.enable {
   495  			enabled = append(enabled, funcName.name)
   496  		}
   497  	}
   498  
   499  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/memex/PushDownTestSwitcher", `return("all")`), IsNil)
   500  	defer func() {
   501  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/memex/PushDownTestSwitcher"), IsNil)
   502  	}()
   503  
   504  	pbExprs, err := ExpressionsToPBList(sc, funcs, client)
   505  	c.Assert(err, IsNil)
   506  	c.Assert(len(pbExprs), Equals, len(cases))
   507  	for i, pbExpr := range pbExprs {
   508  		c.Assert(pbExpr.Sig, Equals, cases[i].sig, Commentf("function: %s, sig: %v", cases[i].name, cases[i].sig))
   509  	}
   510  
   511  	// All disabled
   512  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/memex/PushDownTestSwitcher", `return("")`), IsNil)
   513  	pc := PbConverter{client: client, sc: sc}
   514  	for i := range funcs {
   515  		pbExpr := pc.ExprToPB(funcs[i])
   516  		c.Assert(pbExpr, IsNil, Commentf("function: %s, sig: %v", cases[i].name, cases[i].sig))
   517  	}
   518  
   519  	// Partial enabled
   520  	fpexpr := fmt.Sprintf(`return("%s")`, strings.Join(enabled, ","))
   521  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/memex/PushDownTestSwitcher", fpexpr), IsNil)
   522  	for i := range funcs {
   523  		pbExpr := pc.ExprToPB(funcs[i])
   524  		if !cases[i].enable {
   525  			c.Assert(pbExpr, IsNil, Commentf("function: %s, sig: %v", cases[i].name, cases[i].sig))
   526  			continue
   527  		}
   528  		c.Assert(pbExpr.Sig, Equals, cases[i].sig, Commentf("function: %s, sig: %v", cases[i].name, cases[i].sig))
   529  	}
   530  }
   531  
   532  func (s *testEvaluatorSuite) TestControlFunc2Pb(c *C) {
   533  	var controlFuncs = make([]Expression, 0)
   534  	sc := new(stmtctx.StatementContext)
   535  	client := new(mock.Client)
   536  	dg := new(dataGen4Expr2PbTest)
   537  
   538  	funcNames := []string{
   539  		ast.Case,
   540  		ast.If,
   541  		ast.Ifnull,
   542  	}
   543  	for i, funcName := range funcNames {
   544  		args := []Expression{dg.genDeferredCauset(allegrosql.TypeLong, 1)}
   545  		args = append(args, dg.genDeferredCauset(allegrosql.TypeLong, 2))
   546  		if i < 2 {
   547  			args = append(args, dg.genDeferredCauset(allegrosql.TypeLong, 3))
   548  		}
   549  		fc, err := NewFunction(
   550  			mock.NewContext(),
   551  			funcName,
   552  			types.NewFieldType(allegrosql.TypeUnspecified),
   553  			args...,
   554  		)
   555  		c.Assert(err, IsNil)
   556  		controlFuncs = append(controlFuncs, fc)
   557  	}
   558  
   559  	pbExprs, err := ExpressionsToPBList(sc, controlFuncs, client)
   560  	c.Assert(err, IsNil)
   561  	jsons := []string{
   562  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAM=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":4208,\"field_type\":{\"tp\":3,\"flag\":128,\"flen\":-1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"\"}}",
   563  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAM=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":4107,\"field_type\":{\"tp\":3,\"flag\":128,\"flen\":-1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   564  		"{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":4101,\"field_type\":{\"tp\":3,\"flag\":128,\"flen\":-1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   565  		"null",
   566  	}
   567  	for i, pbExpr := range pbExprs {
   568  		js, err := json.Marshal(pbExpr)
   569  		c.Assert(err, IsNil)
   570  		c.Assert(string(js), Equals, jsons[i])
   571  	}
   572  }
   573  
   574  func (s *testEvaluatorSuite) TestOtherFunc2Pb(c *C) {
   575  	var otherFuncs = make([]Expression, 0)
   576  	sc := new(stmtctx.StatementContext)
   577  	client := new(mock.Client)
   578  	dg := new(dataGen4Expr2PbTest)
   579  
   580  	funcNames := []string{ast.Coalesce, ast.IsNull}
   581  	for _, funcName := range funcNames {
   582  		fc, err := NewFunction(
   583  			mock.NewContext(),
   584  			funcName,
   585  			types.NewFieldType(allegrosql.TypeUnspecified),
   586  			dg.genDeferredCauset(allegrosql.TypeLong, 1),
   587  		)
   588  		c.Assert(err, IsNil)
   589  		otherFuncs = append(otherFuncs, fc)
   590  	}
   591  
   592  	pbExprs, err := ExpressionsToPBList(sc, otherFuncs, client)
   593  	c.Assert(err, IsNil)
   594  	jsons := map[string]string{
   595  		ast.Coalesce: "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":4201,\"field_type\":{\"tp\":3,\"flag\":128,\"flen\":0,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}",
   596  		ast.IsNull:   "{\"tp\":10000,\"children\":[{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":3,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}}],\"sig\":3116,\"field_type\":{\"tp\":8,\"flag\":128,\"flen\":1,\"decimal\":0,\"defCauslate\":63,\"charset\":\"binary\"}}",
   597  	}
   598  	for i, pbExpr := range pbExprs {
   599  		js, err := json.Marshal(pbExpr)
   600  		c.Assert(err, IsNil)
   601  		c.Assert(string(js), Equals, jsons[funcNames[i]])
   602  	}
   603  }
   604  
   605  func (s *testEvaluatorSuite) TestExprPushDownToFlash(c *C) {
   606  	sc := new(stmtctx.StatementContext)
   607  	client := new(mock.Client)
   608  	dg := new(dataGen4Expr2PbTest)
   609  	exprs := make([]Expression, 0)
   610  
   611  	jsonDeferredCauset := dg.genDeferredCauset(allegrosql.TypeJSON, 1)
   612  	intDeferredCauset := dg.genDeferredCauset(allegrosql.TypeLonglong, 2)
   613  	function, err := NewFunction(mock.NewContext(), ast.JSONLength, types.NewFieldType(allegrosql.TypeLonglong), jsonDeferredCauset)
   614  	c.Assert(err, IsNil)
   615  	exprs = append(exprs, function)
   616  
   617  	function, err = NewFunction(mock.NewContext(), ast.If, types.NewFieldType(allegrosql.TypeLonglong), intDeferredCauset, intDeferredCauset, intDeferredCauset)
   618  	c.Assert(err, IsNil)
   619  	exprs = append(exprs, function)
   620  
   621  	function, err = NewFunction(mock.NewContext(), ast.BitNeg, types.NewFieldType(allegrosql.TypeLonglong), intDeferredCauset)
   622  	c.Assert(err, IsNil)
   623  	exprs = append(exprs, function)
   624  
   625  	function, err = NewFunction(mock.NewContext(), ast.Xor, types.NewFieldType(allegrosql.TypeLonglong), intDeferredCauset, intDeferredCauset)
   626  	c.Assert(err, IsNil)
   627  	exprs = append(exprs, function)
   628  
   629  	canPush := CanExprsPushDown(sc, exprs, client, ekv.TiFlash)
   630  	c.Assert(canPush, Equals, true)
   631  
   632  	function, err = NewFunction(mock.NewContext(), ast.JSONDepth, types.NewFieldType(allegrosql.TypeLonglong), jsonDeferredCauset)
   633  	c.Assert(err, IsNil)
   634  	exprs = append(exprs, function)
   635  	pushed, remained := PushDownExprs(sc, exprs, client, ekv.TiFlash)
   636  	c.Assert(len(pushed), Equals, len(exprs)-1)
   637  	c.Assert(len(remained), Equals, 1)
   638  }
   639  
   640  func (s *testEvaluatorSuite) TestExprOnlyPushDownToFlash(c *C) {
   641  	sc := new(stmtctx.StatementContext)
   642  	client := new(mock.Client)
   643  	dg := new(dataGen4Expr2PbTest)
   644  	function, err := NewFunction(mock.NewContext(), ast.TimestamFIDeliff, types.NewFieldType(allegrosql.TypeLonglong),
   645  		dg.genDeferredCauset(allegrosql.TypeString, 1), dg.genDeferredCauset(allegrosql.TypeDatetime, 2), dg.genDeferredCauset(allegrosql.TypeDatetime, 3))
   646  	c.Assert(err, IsNil)
   647  	var exprs = make([]Expression, 0)
   648  	exprs = append(exprs, function)
   649  
   650  	pushed, remained := PushDownExprs(sc, exprs, client, ekv.UnSpecified)
   651  	c.Assert(len(pushed), Equals, 1)
   652  	c.Assert(len(remained), Equals, 0)
   653  
   654  	canPush := CanExprsPushDown(sc, exprs, client, ekv.TiFlash)
   655  	c.Assert(canPush, Equals, true)
   656  	canPush = CanExprsPushDown(sc, exprs, client, ekv.EinsteinDB)
   657  	c.Assert(canPush, Equals, false)
   658  
   659  	pushed, remained = PushDownExprs(sc, exprs, client, ekv.TiFlash)
   660  	c.Assert(len(pushed), Equals, 1)
   661  	c.Assert(len(remained), Equals, 0)
   662  
   663  	pushed, remained = PushDownExprs(sc, exprs, client, ekv.EinsteinDB)
   664  	c.Assert(len(pushed), Equals, 0)
   665  	c.Assert(len(remained), Equals, 1)
   666  }
   667  
   668  func (s *testEvaluatorSuite) TestExprOnlyPushDownToEinsteinDB(c *C) {
   669  	sc := new(stmtctx.StatementContext)
   670  	client := new(mock.Client)
   671  	dg := new(dataGen4Expr2PbTest)
   672  	function, err := NewFunction(mock.NewContext(), "dayofyear", types.NewFieldType(allegrosql.TypeLonglong), dg.genDeferredCauset(allegrosql.TypeDatetime, 1))
   673  	c.Assert(err, IsNil)
   674  	var exprs = make([]Expression, 0)
   675  	exprs = append(exprs, function)
   676  
   677  	pushed, remained := PushDownExprs(sc, exprs, client, ekv.UnSpecified)
   678  	c.Assert(len(pushed), Equals, 1)
   679  	c.Assert(len(remained), Equals, 0)
   680  
   681  	canPush := CanExprsPushDown(sc, exprs, client, ekv.TiFlash)
   682  	c.Assert(canPush, Equals, false)
   683  	canPush = CanExprsPushDown(sc, exprs, client, ekv.EinsteinDB)
   684  	c.Assert(canPush, Equals, true)
   685  
   686  	pushed, remained = PushDownExprs(sc, exprs, client, ekv.TiFlash)
   687  	c.Assert(len(pushed), Equals, 0)
   688  	c.Assert(len(remained), Equals, 1)
   689  	pushed, remained = PushDownExprs(sc, exprs, client, ekv.EinsteinDB)
   690  	c.Assert(len(pushed), Equals, 1)
   691  	c.Assert(len(remained), Equals, 0)
   692  }
   693  
   694  func (s *testEvaluatorSuite) TestGroupByItem2Pb(c *C) {
   695  	sc := new(stmtctx.StatementContext)
   696  	client := new(mock.Client)
   697  	dg := new(dataGen4Expr2PbTest)
   698  	item := dg.genDeferredCauset(allegrosql.TypeDouble, 0)
   699  	pbByItem := GroupByItemToPB(sc, client, item)
   700  	js, err := json.Marshal(pbByItem)
   701  	c.Assert(err, IsNil)
   702  	c.Assert(string(js), Equals, "{\"expr\":{\"tp\":201,\"val\":\"gAAAAAAAAAA=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},\"desc\":false}")
   703  
   704  	item = dg.genDeferredCauset(allegrosql.TypeDouble, 1)
   705  	pbByItem = GroupByItemToPB(sc, client, item)
   706  	js, err = json.Marshal(pbByItem)
   707  	c.Assert(err, IsNil)
   708  	c.Assert(string(js), Equals, "{\"expr\":{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},\"desc\":false}")
   709  }
   710  
   711  func (s *testEvaluatorSuite) TestSortByItem2Pb(c *C) {
   712  	sc := new(stmtctx.StatementContext)
   713  	client := new(mock.Client)
   714  	dg := new(dataGen4Expr2PbTest)
   715  	item := dg.genDeferredCauset(allegrosql.TypeDouble, 0)
   716  	pbByItem := SortByItemToPB(sc, client, item, false)
   717  	js, err := json.Marshal(pbByItem)
   718  	c.Assert(err, IsNil)
   719  	c.Assert(string(js), Equals, "{\"expr\":{\"tp\":201,\"val\":\"gAAAAAAAAAA=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},\"desc\":false}")
   720  
   721  	item = dg.genDeferredCauset(allegrosql.TypeDouble, 1)
   722  	pbByItem = SortByItemToPB(sc, client, item, false)
   723  	js, err = json.Marshal(pbByItem)
   724  	c.Assert(err, IsNil)
   725  	c.Assert(string(js), Equals, "{\"expr\":{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},\"desc\":false}")
   726  
   727  	item = dg.genDeferredCauset(allegrosql.TypeDouble, 1)
   728  	pbByItem = SortByItemToPB(sc, client, item, true)
   729  	js, err = json.Marshal(pbByItem)
   730  	c.Assert(err, IsNil)
   731  	c.Assert(string(js), Equals, "{\"expr\":{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":63,\"charset\":\"\"}},\"desc\":true}")
   732  }
   733  
   734  func (s *testEvaluatorSerialSuites) TestMetadata(c *C) {
   735  	sc := new(stmtctx.StatementContext)
   736  	client := new(mock.Client)
   737  	dg := new(dataGen4Expr2PbTest)
   738  
   739  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/memex/PushDownTestSwitcher", `return("all")`), IsNil)
   740  	defer func() {
   741  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/memex/PushDownTestSwitcher"), IsNil)
   742  	}()
   743  
   744  	pc := PbConverter{client: client, sc: sc}
   745  
   746  	spacetimedata := new(fidelpb.InUnionMetadata)
   747  	var err error
   748  	// InUnion flag is false in `BuildCastFunction` when `ScalarFuncSig_CastStringAsInt`
   749  	cast := BuildCastFunction(mock.NewContext(), dg.genDeferredCauset(allegrosql.TypeString, 1), types.NewFieldType(allegrosql.TypeLonglong))
   750  	c.Assert(cast.(*ScalarFunction).Function.spacetimedata(), DeepEquals, &fidelpb.InUnionMetadata{InUnion: false})
   751  	expr := pc.ExprToPB(cast)
   752  	c.Assert(expr.Sig, Equals, fidelpb.ScalarFuncSig_CastStringAsInt)
   753  	c.Assert(len(expr.Val), Greater, 0)
   754  	err = proto.Unmarshal(expr.Val, spacetimedata)
   755  	c.Assert(err, IsNil)
   756  	c.Assert(spacetimedata.InUnion, Equals, false)
   757  
   758  	// InUnion flag is nil in `BuildCastFunction4Union` when `ScalarFuncSig_CastIntAsString`
   759  	castInUnion := BuildCastFunction4Union(mock.NewContext(), dg.genDeferredCauset(allegrosql.TypeLonglong, 1), types.NewFieldType(allegrosql.TypeString))
   760  	c.Assert(castInUnion.(*ScalarFunction).Function.spacetimedata(), IsNil)
   761  	expr = pc.ExprToPB(castInUnion)
   762  	c.Assert(expr.Sig, Equals, fidelpb.ScalarFuncSig_CastIntAsString)
   763  	c.Assert(len(expr.Val), Equals, 0)
   764  
   765  	// InUnion flag is true in `BuildCastFunction4Union` when `ScalarFuncSig_CastStringAsInt`
   766  	castInUnion = BuildCastFunction4Union(mock.NewContext(), dg.genDeferredCauset(allegrosql.TypeString, 1), types.NewFieldType(allegrosql.TypeLonglong))
   767  	c.Assert(castInUnion.(*ScalarFunction).Function.spacetimedata(), DeepEquals, &fidelpb.InUnionMetadata{InUnion: true})
   768  	expr = pc.ExprToPB(castInUnion)
   769  	c.Assert(expr.Sig, Equals, fidelpb.ScalarFuncSig_CastStringAsInt)
   770  	c.Assert(len(expr.Val), Greater, 0)
   771  	err = proto.Unmarshal(expr.Val, spacetimedata)
   772  	c.Assert(err, IsNil)
   773  	c.Assert(spacetimedata.InUnion, Equals, true)
   774  }
   775  
   776  func defCausumnDefCauslation(c *DeferredCauset, defCausl string) *DeferredCauset {
   777  	c.RetType.DefCauslate = defCausl
   778  	return c
   779  }
   780  
   781  func (s *testEvaluatorSerialSuites) TestNewDefCauslationsEnabled(c *C) {
   782  	defCauslate.SetNewDefCauslationEnabledForTest(true)
   783  	defer defCauslate.SetNewDefCauslationEnabledForTest(false)
   784  	var defCausExprs []Expression
   785  	sc := new(stmtctx.StatementContext)
   786  	client := new(mock.Client)
   787  	dg := new(dataGen4Expr2PbTest)
   788  
   789  	defCausExprs = defCausExprs[:0]
   790  	defCausExprs = append(defCausExprs, dg.genDeferredCauset(allegrosql.TypeVarchar, 1))
   791  	defCausExprs = append(defCausExprs, defCausumnDefCauslation(dg.genDeferredCauset(allegrosql.TypeVarchar, 2), "some_invalid_defCauslation"))
   792  	defCausExprs = append(defCausExprs, defCausumnDefCauslation(dg.genDeferredCauset(allegrosql.TypeVarString, 3), "utf8mb4_general_ci"))
   793  	defCausExprs = append(defCausExprs, defCausumnDefCauslation(dg.genDeferredCauset(allegrosql.TypeString, 4), "utf8mb4_0900_ai_ci"))
   794  	defCausExprs = append(defCausExprs, defCausumnDefCauslation(dg.genDeferredCauset(allegrosql.TypeVarchar, 5), "utf8_bin"))
   795  	defCausExprs = append(defCausExprs, defCausumnDefCauslation(dg.genDeferredCauset(allegrosql.TypeVarchar, 6), "utf8_unicode_ci"))
   796  	pushed, _ := PushDownExprs(sc, defCausExprs, client, ekv.UnSpecified)
   797  	c.Assert(len(pushed), Equals, len(defCausExprs))
   798  	pbExprs, err := ExpressionsToPBList(sc, defCausExprs, client)
   799  	c.Assert(err, IsNil)
   800  	jsons := []string{
   801  		"{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":15,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":-46,\"charset\":\"\"}}",
   802  		"{\"tp\":201,\"val\":\"gAAAAAAAAAI=\",\"sig\":0,\"field_type\":{\"tp\":15,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":-46,\"charset\":\"\"}}",
   803  		"{\"tp\":201,\"val\":\"gAAAAAAAAAM=\",\"sig\":0,\"field_type\":{\"tp\":253,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":-45,\"charset\":\"\"}}",
   804  		"{\"tp\":201,\"val\":\"gAAAAAAAAAQ=\",\"sig\":0,\"field_type\":{\"tp\":254,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":-255,\"charset\":\"\"}}",
   805  		"{\"tp\":201,\"val\":\"gAAAAAAAAAU=\",\"sig\":0,\"field_type\":{\"tp\":15,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":-83,\"charset\":\"\"}}",
   806  		"{\"tp\":201,\"val\":\"gAAAAAAAAAY=\",\"sig\":0,\"field_type\":{\"tp\":15,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":-192,\"charset\":\"\"}}",
   807  	}
   808  	for i, pbExpr := range pbExprs {
   809  		c.Assert(pbExprs, NotNil)
   810  		js, err := json.Marshal(pbExpr)
   811  		c.Assert(err, IsNil)
   812  		c.Assert(string(js), Equals, jsons[i], Commentf("%v\n", i))
   813  	}
   814  
   815  	item := defCausumnDefCauslation(dg.genDeferredCauset(allegrosql.TypeDouble, 0), "utf8mb4_0900_ai_ci")
   816  	pbByItem := GroupByItemToPB(sc, client, item)
   817  	js, err := json.Marshal(pbByItem)
   818  	c.Assert(err, IsNil)
   819  	c.Assert(string(js), Equals, "{\"expr\":{\"tp\":201,\"val\":\"gAAAAAAAAAA=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"defCauslate\":-255,\"charset\":\"\"}},\"desc\":false}")
   820  }
   821  
   822  func (s *testEvalSerialSuite) TestPushDefCauslationDown(c *C) {
   823  	defCauslate.SetNewDefCauslationEnabledForTest(true)
   824  	defer defCauslate.SetNewDefCauslationEnabledForTest(false)
   825  
   826  	dg := new(dataGen4Expr2PbTest)
   827  	fc, err := NewFunction(mock.NewContext(), ast.EQ, types.NewFieldType(allegrosql.TypeUnspecified), dg.genDeferredCauset(allegrosql.TypeVarchar, 0), dg.genDeferredCauset(allegrosql.TypeVarchar, 1))
   828  	c.Assert(err, IsNil)
   829  	client := new(mock.Client)
   830  	sc := new(stmtctx.StatementContext)
   831  
   832  	tps := []*types.FieldType{types.NewFieldType(allegrosql.TypeVarchar), types.NewFieldType(allegrosql.TypeVarchar)}
   833  	for _, defCausl := range []string{charset.DefCauslationBin, charset.DefCauslationLatin1, charset.DefCauslationUTF8, charset.DefCauslationUTF8MB4} {
   834  		fc.SetCharsetAndDefCauslation("binary", defCausl) // only defCauslation matters
   835  		pbExpr, err := ExpressionsToPBList(sc, []Expression{fc}, client)
   836  		c.Assert(err, IsNil)
   837  		expr, err := PBToExpr(pbExpr[0], tps, sc)
   838  		c.Assert(err, IsNil)
   839  		_, eDefCausl := expr.CharsetAndDefCauslation(nil)
   840  		c.Assert(eDefCausl, Equals, defCausl)
   841  	}
   842  }