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 }