github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/constant_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package memex 15 16 import ( 17 "fmt" 18 "sort" 19 "strings" 20 "time" 21 22 . "github.com/whtcorpsinc/check" 23 "github.com/whtcorpsinc/BerolinaSQL/ast" 24 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 25 "github.com/whtcorpsinc/milevadb/types" 26 "github.com/whtcorpsinc/milevadb/types/json" 27 "github.com/whtcorpsinc/milevadb/soliton/chunk" 28 "github.com/whtcorpsinc/milevadb/soliton/mock" 29 ) 30 31 var _ = Suite(&testExpressionSuite{}) 32 33 type testExpressionSuite struct{} 34 35 func newDeferredCauset(id int) *DeferredCauset { 36 return newDeferredCausetWithType(id, types.NewFieldType(allegrosql.TypeLonglong)) 37 } 38 39 func newDeferredCausetWithType(id int, t *types.FieldType) *DeferredCauset { 40 return &DeferredCauset{ 41 UniqueID: int64(id), 42 RetType: t, 43 } 44 } 45 46 func newLonglong(value int64) *Constant { 47 return &Constant{ 48 Value: types.NewIntCauset(value), 49 RetType: types.NewFieldType(allegrosql.TypeLonglong), 50 } 51 } 52 53 func newDate(year, month, day int) *Constant { 54 return newTimeConst(year, month, day, 0, 0, 0, allegrosql.TypeDate) 55 } 56 57 func newTimestamp(yy, mm, dd, hh, min, ss int) *Constant { 58 return newTimeConst(yy, mm, dd, hh, min, ss, allegrosql.TypeTimestamp) 59 } 60 61 func newTimeConst(yy, mm, dd, hh, min, ss int, tp uint8) *Constant { 62 var tmp types.Causet 63 tmp.SetMysqlTime(types.NewTime(types.FromDate(yy, mm, dd, 0, 0, 0, 0), tp, types.DefaultFsp)) 64 return &Constant{ 65 Value: tmp, 66 RetType: types.NewFieldType(tp), 67 } 68 } 69 70 func newFunction(funcName string, args ...Expression) Expression { 71 typeLong := types.NewFieldType(allegrosql.TypeLonglong) 72 return NewFunctionInternal(mock.NewContext(), funcName, typeLong, args...) 73 } 74 75 func (*testExpressionSuite) TestConstantPropagation(c *C) { 76 tests := []struct { 77 solver []PropagateConstantSolver 78 conditions []Expression 79 result string 80 }{ 81 { 82 solver: []PropagateConstantSolver{newPropConstSolver()}, 83 conditions: []Expression{ 84 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 85 newFunction(ast.EQ, newDeferredCauset(1), newDeferredCauset(2)), 86 newFunction(ast.EQ, newDeferredCauset(2), newDeferredCauset(3)), 87 newFunction(ast.EQ, newDeferredCauset(3), newLonglong(1)), 88 newFunction(ast.LogicOr, newLonglong(1), newDeferredCauset(0)), 89 }, 90 result: "1, eq(DeferredCauset#0, 1), eq(DeferredCauset#1, 1), eq(DeferredCauset#2, 1), eq(DeferredCauset#3, 1)", 91 }, 92 { 93 solver: []PropagateConstantSolver{newPropConstSolver()}, 94 conditions: []Expression{ 95 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 96 newFunction(ast.EQ, newDeferredCauset(1), newLonglong(1)), 97 newFunction(ast.NE, newDeferredCauset(2), newLonglong(2)), 98 }, 99 result: "eq(DeferredCauset#0, 1), eq(DeferredCauset#1, 1), ne(DeferredCauset#2, 2)", 100 }, 101 { 102 solver: []PropagateConstantSolver{newPropConstSolver()}, 103 conditions: []Expression{ 104 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 105 newFunction(ast.EQ, newDeferredCauset(1), newLonglong(1)), 106 newFunction(ast.EQ, newDeferredCauset(2), newDeferredCauset(3)), 107 newFunction(ast.GE, newDeferredCauset(2), newLonglong(2)), 108 newFunction(ast.NE, newDeferredCauset(2), newLonglong(4)), 109 newFunction(ast.NE, newDeferredCauset(3), newLonglong(5)), 110 }, 111 result: "eq(DeferredCauset#0, 1), eq(DeferredCauset#1, 1), eq(DeferredCauset#2, DeferredCauset#3), ge(DeferredCauset#2, 2), ge(DeferredCauset#3, 2), ne(DeferredCauset#2, 4), ne(DeferredCauset#2, 5), ne(DeferredCauset#3, 4), ne(DeferredCauset#3, 5)", 112 }, 113 { 114 solver: []PropagateConstantSolver{newPropConstSolver()}, 115 conditions: []Expression{ 116 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 117 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(2)), 118 newFunction(ast.GE, newDeferredCauset(1), newLonglong(0)), 119 }, 120 result: "eq(DeferredCauset#0, DeferredCauset#1), eq(DeferredCauset#0, DeferredCauset#2), ge(DeferredCauset#0, 0), ge(DeferredCauset#1, 0), ge(DeferredCauset#2, 0)", 121 }, 122 { 123 solver: []PropagateConstantSolver{newPropConstSolver()}, 124 conditions: []Expression{ 125 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 126 newFunction(ast.GT, newDeferredCauset(0), newLonglong(2)), 127 newFunction(ast.GT, newDeferredCauset(1), newLonglong(3)), 128 newFunction(ast.LT, newDeferredCauset(0), newLonglong(1)), 129 newFunction(ast.GT, newLonglong(2), newDeferredCauset(1)), 130 }, 131 result: "eq(DeferredCauset#0, DeferredCauset#1), gt(2, DeferredCauset#0), gt(2, DeferredCauset#1), gt(DeferredCauset#0, 2), gt(DeferredCauset#0, 3), gt(DeferredCauset#1, 2), gt(DeferredCauset#1, 3), lt(DeferredCauset#0, 1), lt(DeferredCauset#1, 1)", 132 }, 133 { 134 solver: []PropagateConstantSolver{newPropConstSolver()}, 135 conditions: []Expression{ 136 newFunction(ast.EQ, newLonglong(1), newDeferredCauset(0)), 137 newLonglong(0), 138 }, 139 result: "0", 140 }, 141 { 142 solver: []PropagateConstantSolver{newPropConstSolver()}, 143 conditions: []Expression{ 144 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 145 newFunction(ast.In, newDeferredCauset(0), newLonglong(1), newLonglong(2)), 146 newFunction(ast.In, newDeferredCauset(1), newLonglong(3), newLonglong(4)), 147 }, 148 result: "eq(DeferredCauset#0, DeferredCauset#1), in(DeferredCauset#0, 1, 2), in(DeferredCauset#0, 3, 4), in(DeferredCauset#1, 1, 2), in(DeferredCauset#1, 3, 4)", 149 }, 150 { 151 solver: []PropagateConstantSolver{newPropConstSolver()}, 152 conditions: []Expression{ 153 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 154 newFunction(ast.EQ, newDeferredCauset(0), newFunction(ast.BitLength, newDeferredCauset(2))), 155 }, 156 result: "eq(DeferredCauset#0, DeferredCauset#1), eq(DeferredCauset#0, bit_length(cast(DeferredCauset#2, var_string(20)))), eq(DeferredCauset#1, bit_length(cast(DeferredCauset#2, var_string(20))))", 157 }, 158 { 159 solver: []PropagateConstantSolver{newPropConstSolver()}, 160 conditions: []Expression{ 161 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 162 newFunction(ast.LE, newFunction(ast.Mul, newDeferredCauset(0), newDeferredCauset(0)), newLonglong(50)), 163 }, 164 result: "eq(DeferredCauset#0, DeferredCauset#1), le(mul(DeferredCauset#0, DeferredCauset#0), 50), le(mul(DeferredCauset#1, DeferredCauset#1), 50)", 165 }, 166 { 167 solver: []PropagateConstantSolver{newPropConstSolver()}, 168 conditions: []Expression{ 169 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 170 newFunction(ast.LE, newDeferredCauset(0), newFunction(ast.Plus, newDeferredCauset(1), newLonglong(1))), 171 }, 172 result: "eq(DeferredCauset#0, DeferredCauset#1), le(DeferredCauset#0, plus(DeferredCauset#0, 1)), le(DeferredCauset#0, plus(DeferredCauset#1, 1)), le(DeferredCauset#1, plus(DeferredCauset#1, 1))", 173 }, 174 { 175 solver: []PropagateConstantSolver{newPropConstSolver()}, 176 conditions: []Expression{ 177 newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)), 178 newFunction(ast.LE, newDeferredCauset(0), newFunction(ast.Rand)), 179 }, 180 result: "eq(DeferredCauset#0, DeferredCauset#1), le(cast(DeferredCauset#0, double BINARY), rand())", 181 }, 182 } 183 for _, tt := range tests { 184 for _, solver := range tt.solver { 185 ctx := mock.NewContext() 186 conds := make([]Expression, 0, len(tt.conditions)) 187 for _, cd := range tt.conditions { 188 conds = append(conds, FoldConstant(cd)) 189 } 190 newConds := solver.PropagateConstant(ctx, conds) 191 var result []string 192 for _, v := range newConds { 193 result = append(result, v.String()) 194 } 195 sort.Strings(result) 196 c.Assert(strings.Join(result, ", "), Equals, tt.result, Commentf("different for expr %s", tt.conditions)) 197 } 198 } 199 } 200 201 func (*testExpressionSuite) TestConstantFolding(c *C) { 202 tests := []struct { 203 condition Expression 204 result string 205 }{ 206 { 207 condition: newFunction(ast.LT, newDeferredCauset(0), newFunction(ast.Plus, newLonglong(1), newLonglong(2))), 208 result: "lt(DeferredCauset#0, 3)", 209 }, 210 { 211 condition: newFunction(ast.LT, newDeferredCauset(0), newFunction(ast.Greatest, newLonglong(1), newLonglong(2))), 212 result: "lt(DeferredCauset#0, 2)", 213 }, 214 { 215 condition: newFunction(ast.EQ, newDeferredCauset(0), newFunction(ast.Rand)), 216 result: "eq(cast(DeferredCauset#0, double BINARY), rand())", 217 }, 218 { 219 condition: newFunction(ast.IsNull, newLonglong(1)), 220 result: "0", 221 }, 222 { 223 condition: newFunction(ast.EQ, newDeferredCauset(0), newFunction(ast.UnaryNot, newFunction(ast.Plus, newLonglong(1), newLonglong(1)))), 224 result: "eq(DeferredCauset#0, 0)", 225 }, 226 { 227 condition: newFunction(ast.LT, newDeferredCauset(0), newFunction(ast.Plus, newDeferredCauset(1), newFunction(ast.Plus, newLonglong(2), newLonglong(1)))), 228 result: "lt(DeferredCauset#0, plus(DeferredCauset#1, 3))", 229 }, 230 } 231 for _, tt := range tests { 232 newConds := FoldConstant(tt.condition) 233 c.Assert(newConds.String(), Equals, tt.result, Commentf("different for expr %s", tt.condition)) 234 } 235 } 236 237 func (*testExpressionSuite) TestDeferredExprNullConstantFold(c *C) { 238 nullConst := &Constant{ 239 Value: types.NewCauset(nil), 240 RetType: types.NewFieldType(allegrosql.TypeTiny), 241 DeferredExpr: NewNull(), 242 } 243 tests := []struct { 244 condition Expression 245 deferred string 246 }{ 247 { 248 condition: newFunction(ast.LT, newDeferredCauset(0), nullConst), 249 deferred: "lt(DeferredCauset#0, <nil>)", 250 }, 251 } 252 for _, tt := range tests { 253 comment := Commentf("different for expr %s", tt.condition) 254 sf, ok := tt.condition.(*ScalarFunction) 255 c.Assert(ok, IsTrue, comment) 256 sf.GetCtx().GetStochastikVars().StmtCtx.InNullRejectCheck = true 257 newConds := FoldConstant(tt.condition) 258 newConst, ok := newConds.(*Constant) 259 c.Assert(ok, IsTrue, comment) 260 c.Assert(newConst.DeferredExpr.String(), Equals, tt.deferred, comment) 261 } 262 } 263 264 func (*testExpressionSuite) TestDeferredParamNotNull(c *C) { 265 ctx := mock.NewContext() 266 testTime := time.Now() 267 ctx.GetStochastikVars().PreparedParams = []types.Causet{ 268 types.NewIntCauset(1), 269 types.NewDecimalCauset(types.NewDecFromStringForTest("20170118123950.123")), 270 types.NewTimeCauset(types.NewTime(types.FromGoTime(testTime), allegrosql.TypeTimestamp, 6)), 271 types.NewDurationCauset(types.ZeroDuration), 272 types.NewStringCauset("{}"), 273 types.NewBinaryLiteralCauset([]byte{1}), 274 types.NewBytesCauset([]byte{'b'}), 275 types.NewFloat32Causet(1.1), 276 types.NewFloat64Causet(2.1), 277 types.NewUintCauset(100), 278 types.NewMysqlBitCauset([]byte{1}), 279 types.NewMysqlEnumCauset(types.Enum{Name: "n", Value: 2}), 280 } 281 cstInt := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 0}, RetType: newIntFieldType()} 282 cstDec := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 1}, RetType: newDecimalFieldType()} 283 cstTime := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 2}, RetType: newDateFieldType()} 284 cstDuration := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 3}, RetType: newDurFieldType()} 285 cstJSON := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 4}, RetType: newJSONFieldType()} 286 cstBytes := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 6}, RetType: newBlobFieldType()} 287 cstBinary := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 5}, RetType: newBinaryLiteralFieldType()} 288 cstFloat32 := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 7}, RetType: newFloatFieldType()} 289 cstFloat64 := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 8}, RetType: newFloatFieldType()} 290 cstUint := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 9}, RetType: newIntFieldType()} 291 cstBit := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 10}, RetType: newBinaryLiteralFieldType()} 292 cstEnum := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 11}, RetType: newEnumFieldType()} 293 294 c.Assert(allegrosql.TypeVarString, Equals, cstJSON.GetType().Tp) 295 c.Assert(allegrosql.TypeNewDecimal, Equals, cstDec.GetType().Tp) 296 c.Assert(allegrosql.TypeLonglong, Equals, cstInt.GetType().Tp) 297 c.Assert(allegrosql.TypeLonglong, Equals, cstUint.GetType().Tp) 298 c.Assert(allegrosql.TypeTimestamp, Equals, cstTime.GetType().Tp) 299 c.Assert(allegrosql.TypeDuration, Equals, cstDuration.GetType().Tp) 300 c.Assert(allegrosql.TypeBlob, Equals, cstBytes.GetType().Tp) 301 c.Assert(allegrosql.TypeBit, Equals, cstBinary.GetType().Tp) 302 c.Assert(allegrosql.TypeBit, Equals, cstBit.GetType().Tp) 303 c.Assert(allegrosql.TypeFloat, Equals, cstFloat32.GetType().Tp) 304 c.Assert(allegrosql.TypeDouble, Equals, cstFloat64.GetType().Tp) 305 c.Assert(allegrosql.TypeEnum, Equals, cstEnum.GetType().Tp) 306 307 d, _, err := cstInt.EvalInt(ctx, chunk.Event{}) 308 c.Assert(err, IsNil) 309 c.Assert(d, Equals, int64(1)) 310 r, _, err := cstFloat64.EvalReal(ctx, chunk.Event{}) 311 c.Assert(err, IsNil) 312 c.Assert(r, Equals, float64(2.1)) 313 de, _, err := cstDec.EvalDecimal(ctx, chunk.Event{}) 314 c.Assert(err, IsNil) 315 c.Assert(de.String(), Equals, "20170118123950.123") 316 s, _, err := cstBytes.EvalString(ctx, chunk.Event{}) 317 c.Assert(err, IsNil) 318 c.Assert(s, Equals, "b") 319 t, _, err := cstTime.EvalTime(ctx, chunk.Event{}) 320 c.Assert(err, IsNil) 321 c.Assert(t.Compare(ctx.GetStochastikVars().PreparedParams[2].GetMysqlTime()), Equals, 0) 322 dur, _, err := cstDuration.EvalDuration(ctx, chunk.Event{}) 323 c.Assert(err, IsNil) 324 c.Assert(dur.Duration, Equals, types.ZeroDuration.Duration) 325 json, _, err := cstJSON.EvalJSON(ctx, chunk.Event{}) 326 c.Assert(err, IsNil) 327 c.Assert(json, NotNil) 328 } 329 330 func (*testExpressionSuite) TestDeferredExprNotNull(c *C) { 331 m := &MockExpr{} 332 ctx := mock.NewContext() 333 cst := &Constant{DeferredExpr: m, RetType: newIntFieldType()} 334 m.i, m.err = nil, fmt.Errorf("ERROR") 335 _, _, err := cst.EvalInt(ctx, chunk.Event{}) 336 c.Assert(err, NotNil) 337 _, _, err = cst.EvalReal(ctx, chunk.Event{}) 338 c.Assert(err, NotNil) 339 _, _, err = cst.EvalDecimal(ctx, chunk.Event{}) 340 c.Assert(err, NotNil) 341 _, _, err = cst.EvalString(ctx, chunk.Event{}) 342 c.Assert(err, NotNil) 343 _, _, err = cst.EvalTime(ctx, chunk.Event{}) 344 c.Assert(err, NotNil) 345 _, _, err = cst.EvalDuration(ctx, chunk.Event{}) 346 c.Assert(err, NotNil) 347 _, _, err = cst.EvalJSON(ctx, chunk.Event{}) 348 c.Assert(err, NotNil) 349 350 m.i, m.err = nil, nil 351 _, isNull, err := cst.EvalInt(ctx, chunk.Event{}) 352 c.Assert(err, IsNil) 353 c.Assert(isNull, IsTrue) 354 _, isNull, err = cst.EvalReal(ctx, chunk.Event{}) 355 c.Assert(err, IsNil) 356 c.Assert(isNull, IsTrue) 357 _, isNull, err = cst.EvalDecimal(ctx, chunk.Event{}) 358 c.Assert(err, IsNil) 359 c.Assert(isNull, IsTrue) 360 _, isNull, err = cst.EvalString(ctx, chunk.Event{}) 361 c.Assert(err, IsNil) 362 c.Assert(isNull, IsTrue) 363 _, isNull, err = cst.EvalTime(ctx, chunk.Event{}) 364 c.Assert(err, IsNil) 365 c.Assert(isNull, IsTrue) 366 _, isNull, err = cst.EvalDuration(ctx, chunk.Event{}) 367 c.Assert(err, IsNil) 368 c.Assert(isNull, IsTrue) 369 _, isNull, err = cst.EvalJSON(ctx, chunk.Event{}) 370 c.Assert(err, IsNil) 371 c.Assert(isNull, IsTrue) 372 373 m.i = int64(2333) 374 xInt, _, _ := cst.EvalInt(ctx, chunk.Event{}) 375 c.Assert(xInt, Equals, int64(2333)) 376 377 m.i = float64(123.45) 378 xFlo, _, _ := cst.EvalReal(ctx, chunk.Event{}) 379 c.Assert(xFlo, Equals, float64(123.45)) 380 381 m.i = "abc" 382 xStr, _, _ := cst.EvalString(ctx, chunk.Event{}) 383 c.Assert(xStr, Equals, "abc") 384 385 m.i = &types.MyDecimal{} 386 xDec, _, _ := cst.EvalDecimal(ctx, chunk.Event{}) 387 c.Assert(xDec.Compare(m.i.(*types.MyDecimal)), Equals, 0) 388 389 m.i = types.ZeroTime 390 xTim, _, _ := cst.EvalTime(ctx, chunk.Event{}) 391 c.Assert(xTim.Compare(m.i.(types.Time)), Equals, 0) 392 393 m.i = types.Duration{} 394 xDur, _, _ := cst.EvalDuration(ctx, chunk.Event{}) 395 c.Assert(xDur.Compare(m.i.(types.Duration)), Equals, 0) 396 397 m.i = json.BinaryJSON{} 398 xJsn, _, _ := cst.EvalJSON(ctx, chunk.Event{}) 399 c.Assert(m.i.(json.BinaryJSON).String(), Equals, xJsn.String()) 400 401 cln := cst.Clone().(*Constant) 402 c.Assert(cln.DeferredExpr, Equals, cst.DeferredExpr) 403 } 404 405 func (*testExpressionSuite) TestVectorizedConstant(c *C) { 406 // fixed-length type with/without Sel 407 for _, cst := range []*Constant{ 408 {RetType: newIntFieldType(), Value: types.NewIntCauset(2333)}, 409 {RetType: newIntFieldType(), DeferredExpr: &Constant{RetType: newIntFieldType(), Value: types.NewIntCauset(2333)}}} { 410 chk := chunk.New([]*types.FieldType{newIntFieldType()}, 1024, 1024) 411 for i := 0; i < 1024; i++ { 412 chk.AppendInt64(0, int64(i)) 413 } 414 defCaus := chunk.NewDeferredCauset(newIntFieldType(), 1024) 415 ctx := mock.NewContext() 416 c.Assert(cst.VecEvalInt(ctx, chk, defCaus), IsNil) 417 i64s := defCaus.Int64s() 418 c.Assert(len(i64s), Equals, 1024) 419 for _, v := range i64s { 420 c.Assert(v, Equals, int64(2333)) 421 } 422 423 // fixed-length type with Sel 424 sel := []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29} 425 chk.SetSel(sel) 426 c.Assert(cst.VecEvalInt(ctx, chk, defCaus), IsNil) 427 i64s = defCaus.Int64s() 428 for i := range sel { 429 c.Assert(i64s[i], Equals, int64(2333)) 430 } 431 } 432 433 // var-length type with/without Sel 434 for _, cst := range []*Constant{ 435 {RetType: newStringFieldType(), Value: types.NewStringCauset("hello")}, 436 {RetType: newStringFieldType(), DeferredExpr: &Constant{RetType: newStringFieldType(), Value: types.NewStringCauset("hello")}}} { 437 chk := chunk.New([]*types.FieldType{newIntFieldType()}, 1024, 1024) 438 for i := 0; i < 1024; i++ { 439 chk.AppendInt64(0, int64(i)) 440 } 441 cst = &Constant{DeferredExpr: nil, RetType: newStringFieldType(), Value: types.NewStringCauset("hello")} 442 chk.SetSel(nil) 443 defCaus := chunk.NewDeferredCauset(newStringFieldType(), 1024) 444 ctx := mock.NewContext() 445 c.Assert(cst.VecEvalString(ctx, chk, defCaus), IsNil) 446 for i := 0; i < 1024; i++ { 447 c.Assert(defCaus.GetString(i), Equals, "hello") 448 } 449 450 // var-length type with Sel 451 sel := []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29} 452 chk.SetSel(sel) 453 c.Assert(cst.VecEvalString(ctx, chk, defCaus), IsNil) 454 for i := range sel { 455 c.Assert(defCaus.GetString(i), Equals, "hello") 456 } 457 } 458 } 459 460 func (*testExpressionSuite) TestGetTypeThreadSafe(c *C) { 461 ctx := mock.NewContext() 462 ctx.GetStochastikVars().PreparedParams = []types.Causet{ 463 types.NewIntCauset(1), 464 } 465 con := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 0}, RetType: newStringFieldType()} 466 ft1 := con.GetType() 467 ft2 := con.GetType() 468 c.Assert(ft1, Not(Equals), ft2) 469 }