github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/evaluator_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 "sync/atomic" 18 "testing" 19 "time" 20 21 . "github.com/whtcorpsinc/check" 22 "github.com/whtcorpsinc/BerolinaSQL" 23 "github.com/whtcorpsinc/BerolinaSQL/ast" 24 "github.com/whtcorpsinc/BerolinaSQL/charset" 25 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 26 "github.com/whtcorpsinc/milevadb/stochastikctx" 27 "github.com/whtcorpsinc/milevadb/types" 28 "github.com/whtcorpsinc/milevadb/soliton/chunk" 29 "github.com/whtcorpsinc/milevadb/soliton/mock" 30 "github.com/whtcorpsinc/milevadb/soliton/testleak" 31 "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 32 ) 33 34 var _ = SerialSuites(&testEvaluatorSerialSuites{}) 35 var _ = Suite(&testEvaluatorSuite{}) 36 var _ = Suite(&testVectorizeSuite1{}) 37 var _ = Suite(&testVectorizeSuite2{}) 38 39 func TestT(t *testing.T) { 40 testleak.BeforeTest() 41 defer testleak.AfterTestT(t)() 42 43 CustomVerboseFlag = true 44 *CustomParallelSuiteFlag = true 45 TestingT(t) 46 } 47 48 type testEvaluatorSuiteBase struct { 49 *BerolinaSQL.BerolinaSQL 50 ctx stochastikctx.Context 51 } 52 53 type testEvaluatorSuite struct { 54 testEvaluatorSuiteBase 55 } 56 57 type testVectorizeSuite1 struct { 58 testEvaluatorSuiteBase 59 } 60 61 type testVectorizeSuite2 struct { 62 testEvaluatorSuiteBase 63 } 64 65 type testEvaluatorSerialSuites struct { 66 testEvaluatorSuiteBase 67 } 68 69 func (s *testEvaluatorSuiteBase) SetUpSuite(c *C) { 70 s.BerolinaSQL = BerolinaSQL.New() 71 } 72 73 func (s *testEvaluatorSuiteBase) TearDownSuite(c *C) { 74 } 75 76 func (s *testEvaluatorSuiteBase) SetUpTest(c *C) { 77 s.ctx = mock.NewContext() 78 s.ctx.GetStochastikVars().StmtCtx.TimeZone = time.Local 79 sc := s.ctx.GetStochastikVars().StmtCtx 80 sc.TruncateAsWarning = true 81 s.ctx.GetStochastikVars().SetSystemVar("max_allowed_packet", "67108864") 82 s.ctx.GetStochastikVars().CausetDeferredCausetID = 0 83 } 84 85 func (s *testEvaluatorSuiteBase) TearDownTest(c *C) { 86 s.ctx.GetStochastikVars().StmtCtx.SetWarnings(nil) 87 } 88 89 func (s *testEvaluatorSuiteBase) HoTTToFieldType(HoTT byte) types.FieldType { 90 ft := types.FieldType{} 91 switch HoTT { 92 case types.HoTTNull: 93 ft.Tp = allegrosql.TypeNull 94 case types.HoTTInt64: 95 ft.Tp = allegrosql.TypeLonglong 96 case types.HoTTUint64: 97 ft.Tp = allegrosql.TypeLonglong 98 ft.Flag |= allegrosql.UnsignedFlag 99 case types.HoTTMinNotNull: 100 ft.Tp = allegrosql.TypeLonglong 101 case types.HoTTMaxValue: 102 ft.Tp = allegrosql.TypeLonglong 103 case types.HoTTFloat32: 104 ft.Tp = allegrosql.TypeDouble 105 case types.HoTTFloat64: 106 ft.Tp = allegrosql.TypeDouble 107 case types.HoTTString: 108 ft.Tp = allegrosql.TypeVarString 109 case types.HoTTBytes: 110 ft.Tp = allegrosql.TypeVarString 111 case types.HoTTMysqlEnum: 112 ft.Tp = allegrosql.TypeEnum 113 case types.HoTTMysqlSet: 114 ft.Tp = allegrosql.TypeSet 115 case types.HoTTInterface: 116 ft.Tp = allegrosql.TypeVarString 117 case types.HoTTMysqlDecimal: 118 ft.Tp = allegrosql.TypeNewDecimal 119 case types.HoTTMysqlDuration: 120 ft.Tp = allegrosql.TypeDuration 121 case types.HoTTMysqlTime: 122 ft.Tp = allegrosql.TypeDatetime 123 case types.HoTTBinaryLiteral: 124 ft.Tp = allegrosql.TypeVarString 125 ft.Charset = charset.CharsetBin 126 ft.DefCauslate = charset.DefCauslationBin 127 case types.HoTTMysqlBit: 128 ft.Tp = allegrosql.TypeBit 129 case types.HoTTMysqlJSON: 130 ft.Tp = allegrosql.TypeJSON 131 } 132 return ft 133 } 134 135 func (s *testEvaluatorSuiteBase) datumsToConstants(datums []types.Causet) []Expression { 136 constants := make([]Expression, 0, len(datums)) 137 for _, d := range datums { 138 ft := s.HoTTToFieldType(d.HoTT()) 139 if types.IsNonBinaryStr(&ft) { 140 ft.DefCauslate = d.DefCauslation() 141 } 142 ft.Flen, ft.Decimal = types.UnspecifiedLength, types.UnspecifiedLength 143 constants = append(constants, &Constant{Value: d, RetType: &ft}) 144 } 145 return constants 146 } 147 148 func (s *testEvaluatorSuiteBase) primitiveValsToConstants(args []interface{}) []Expression { 149 cons := s.datumsToConstants(types.MakeCausets(args...)) 150 char, defCaus := s.ctx.GetStochastikVars().GetCharsetInfo() 151 for i, arg := range args { 152 types.DefaultTypeForValue(arg, cons[i].GetType(), char, defCaus) 153 } 154 return cons 155 } 156 157 func (s *testEvaluatorSuite) TestSleep(c *C) { 158 ctx := mock.NewContext() 159 sessVars := ctx.GetStochastikVars() 160 161 fc := funcs[ast.Sleep] 162 // non-strict perceptron 163 sessVars.StrictALLEGROSQLMode = false 164 d := make([]types.Causet, 1) 165 f, err := fc.getFunction(ctx, s.datumsToConstants(d)) 166 c.Assert(err, IsNil) 167 ret, isNull, err := f.evalInt(chunk.Row{}) 168 c.Assert(err, IsNil) 169 c.Assert(isNull, IsFalse) 170 c.Assert(ret, Equals, int64(0)) 171 d[0].SetInt64(-1) 172 f, err = fc.getFunction(ctx, s.datumsToConstants(d)) 173 c.Assert(err, IsNil) 174 ret, isNull, err = f.evalInt(chunk.Row{}) 175 c.Assert(err, IsNil) 176 c.Assert(isNull, IsFalse) 177 c.Assert(ret, Equals, int64(0)) 178 179 // for error case under the strict perceptron 180 sessVars.StrictALLEGROSQLMode = true 181 d[0].SetNull() 182 _, err = fc.getFunction(ctx, s.datumsToConstants(d)) 183 c.Assert(err, IsNil) 184 _, isNull, err = f.evalInt(chunk.Row{}) 185 c.Assert(err, NotNil) 186 c.Assert(isNull, IsFalse) 187 d[0].SetFloat64(-2.5) 188 _, err = fc.getFunction(ctx, s.datumsToConstants(d)) 189 c.Assert(err, IsNil) 190 _, isNull, err = f.evalInt(chunk.Row{}) 191 c.Assert(err, NotNil) 192 c.Assert(isNull, IsFalse) 193 194 // strict perceptron 195 d[0].SetFloat64(0.5) 196 start := time.Now() 197 f, err = fc.getFunction(ctx, s.datumsToConstants(d)) 198 c.Assert(err, IsNil) 199 ret, isNull, err = f.evalInt(chunk.Row{}) 200 c.Assert(err, IsNil) 201 c.Assert(isNull, IsFalse) 202 c.Assert(ret, Equals, int64(0)) 203 sub := time.Since(start) 204 c.Assert(sub.Nanoseconds(), GreaterEqual, int64(0.5*1e9)) 205 206 d[0].SetFloat64(3) 207 f, err = fc.getFunction(ctx, s.datumsToConstants(d)) 208 c.Assert(err, IsNil) 209 start = time.Now() 210 go func() { 211 time.Sleep(1 * time.Second) 212 atomic.CompareAndSwapUint32(&ctx.GetStochastikVars().Killed, 0, 1) 213 }() 214 ret, isNull, err = f.evalInt(chunk.Row{}) 215 sub = time.Since(start) 216 c.Assert(err, IsNil) 217 c.Assert(isNull, IsFalse) 218 c.Assert(ret, Equals, int64(1)) 219 c.Assert(sub.Nanoseconds(), LessEqual, int64(2*1e9)) 220 c.Assert(sub.Nanoseconds(), GreaterEqual, int64(1*1e9)) 221 } 222 223 func (s *testEvaluatorSuite) TestBinopComparison(c *C) { 224 tbl := []struct { 225 lhs interface{} 226 op string 227 rhs interface{} 228 result int64 // 0 for false, 1 for true 229 }{ 230 // test EQ 231 {1, ast.EQ, 2, 0}, 232 {false, ast.EQ, false, 1}, 233 {false, ast.EQ, true, 0}, 234 {true, ast.EQ, true, 1}, 235 {true, ast.EQ, false, 0}, 236 {"1", ast.EQ, true, 1}, 237 {"1", ast.EQ, false, 0}, 238 239 // test NEQ 240 {1, ast.NE, 2, 1}, 241 {false, ast.NE, false, 0}, 242 {false, ast.NE, true, 1}, 243 {true, ast.NE, true, 0}, 244 {"1", ast.NE, true, 0}, 245 {"1", ast.NE, false, 1}, 246 247 // test GT, GE 248 {1, ast.GT, 0, 1}, 249 {1, ast.GT, 1, 0}, 250 {1, ast.GE, 1, 1}, 251 {3.14, ast.GT, 3, 1}, 252 {3.14, ast.GE, 3.14, 1}, 253 254 // test LT, LE 255 {1, ast.LT, 2, 1}, 256 {1, ast.LT, 1, 0}, 257 {1, ast.LE, 1, 1}, 258 } 259 for _, t := range tbl { 260 fc := funcs[t.op] 261 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.lhs, t.rhs))) 262 c.Assert(err, IsNil) 263 v, err := evalBuiltinFunc(f, chunk.Row{}) 264 c.Assert(err, IsNil) 265 val, err := v.ToBool(s.ctx.GetStochastikVars().StmtCtx) 266 c.Assert(err, IsNil) 267 c.Assert(val, Equals, t.result) 268 } 269 270 // test nil 271 nilTbl := []struct { 272 lhs interface{} 273 op string 274 rhs interface{} 275 }{ 276 {nil, ast.EQ, nil}, 277 {nil, ast.EQ, 1}, 278 {nil, ast.NE, nil}, 279 {nil, ast.NE, 1}, 280 {nil, ast.LT, nil}, 281 {nil, ast.LT, 1}, 282 {nil, ast.LE, nil}, 283 {nil, ast.LE, 1}, 284 {nil, ast.GT, nil}, 285 {nil, ast.GT, 1}, 286 {nil, ast.GE, nil}, 287 {nil, ast.GE, 1}, 288 } 289 290 for _, t := range nilTbl { 291 fc := funcs[t.op] 292 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.lhs, t.rhs))) 293 c.Assert(err, IsNil) 294 v, err := evalBuiltinFunc(f, chunk.Row{}) 295 c.Assert(err, IsNil) 296 c.Assert(v.HoTT(), Equals, types.HoTTNull) 297 } 298 } 299 300 func (s *testEvaluatorSuite) TestBinopLogic(c *C) { 301 tbl := []struct { 302 lhs interface{} 303 op string 304 rhs interface{} 305 ret interface{} 306 }{ 307 {nil, ast.LogicAnd, 1, nil}, 308 {nil, ast.LogicAnd, 0, 0}, 309 {nil, ast.LogicOr, 1, 1}, 310 {nil, ast.LogicOr, 0, nil}, 311 {nil, ast.LogicXor, 1, nil}, 312 {nil, ast.LogicXor, 0, nil}, 313 {1, ast.LogicAnd, 0, 0}, 314 {1, ast.LogicAnd, 1, 1}, 315 {1, ast.LogicOr, 0, 1}, 316 {1, ast.LogicOr, 1, 1}, 317 {0, ast.LogicOr, 0, 0}, 318 {1, ast.LogicXor, 0, 1}, 319 {1, ast.LogicXor, 1, 0}, 320 {0, ast.LogicXor, 0, 0}, 321 {0, ast.LogicXor, 1, 1}, 322 } 323 for _, t := range tbl { 324 fc := funcs[t.op] 325 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.lhs, t.rhs))) 326 c.Assert(err, IsNil) 327 v, err := evalBuiltinFunc(f, chunk.Row{}) 328 c.Assert(err, IsNil) 329 switch x := t.ret.(type) { 330 case nil: 331 c.Assert(v.HoTT(), Equals, types.HoTTNull) 332 case int: 333 c.Assert(v, solitonutil.CausetEquals, types.NewCauset(int64(x))) 334 } 335 } 336 } 337 338 func (s *testEvaluatorSuite) TestBinopBitop(c *C) { 339 tbl := []struct { 340 lhs interface{} 341 op string 342 rhs interface{} 343 ret interface{} 344 }{ 345 {1, ast.And, 1, 1}, 346 {1, ast.Or, 1, 1}, 347 {1, ast.Xor, 1, 0}, 348 {1, ast.LeftShift, 1, 2}, 349 {2, ast.RightShift, 1, 1}, 350 {nil, ast.And, 1, nil}, 351 {1, ast.And, nil, nil}, 352 {nil, ast.Or, 1, nil}, 353 {nil, ast.Xor, 1, nil}, 354 {nil, ast.LeftShift, 1, nil}, 355 {nil, ast.RightShift, 1, nil}, 356 } 357 358 for _, t := range tbl { 359 fc := funcs[t.op] 360 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.lhs, t.rhs))) 361 c.Assert(err, IsNil) 362 v, err := evalBuiltinFunc(f, chunk.Row{}) 363 c.Assert(err, IsNil) 364 365 switch x := t.ret.(type) { 366 case nil: 367 c.Assert(v.HoTT(), Equals, types.HoTTNull) 368 case int: 369 c.Assert(v, solitonutil.CausetEquals, types.NewCauset(uint64(x))) 370 } 371 } 372 } 373 374 func (s *testEvaluatorSuite) TestBinopNumeric(c *C) { 375 tbl := []struct { 376 lhs interface{} 377 op string 378 rhs interface{} 379 ret interface{} 380 }{ 381 // plus 382 {1, ast.Plus, 1, 2}, 383 {1, ast.Plus, uint64(1), 2}, 384 {1, ast.Plus, "1", 2}, 385 {1, ast.Plus, types.NewDecFromInt(1), 2}, 386 {uint64(1), ast.Plus, 1, 2}, 387 {uint64(1), ast.Plus, uint64(1), 2}, 388 {uint64(1), ast.Plus, -1, 0}, 389 {1, ast.Plus, []byte("1"), 2}, 390 {1, ast.Plus, types.NewBinaryLiteralFromUint(1, -1), 2}, 391 {1, ast.Plus, types.Enum{Name: "a", Value: 1}, 2}, 392 {1, ast.Plus, types.Set{Name: "a", Value: 1}, 2}, 393 394 // minus 395 {1, ast.Minus, 1, 0}, 396 {1, ast.Minus, uint64(1), 0}, 397 {1, ast.Minus, float64(1), 0}, 398 {1, ast.Minus, types.NewDecFromInt(1), 0}, 399 {uint64(1), ast.Minus, 1, 0}, 400 {uint64(1), ast.Minus, uint64(1), 0}, 401 {types.NewDecFromInt(1), ast.Minus, 1, 0}, 402 {"1", ast.Minus, []byte("1"), 0}, 403 404 // mul 405 {1, ast.Mul, 1, 1}, 406 {1, ast.Mul, uint64(1), 1}, 407 {1, ast.Mul, float64(1), 1}, 408 {1, ast.Mul, types.NewDecFromInt(1), 1}, 409 {uint64(1), ast.Mul, 1, 1}, 410 {uint64(1), ast.Mul, uint64(1), 1}, 411 {types.NewTime(types.FromDate(0, 0, 0, 0, 0, 0, 0), 0, 0), ast.Mul, 0, 0}, 412 {types.ZeroDuration, ast.Mul, 0, 0}, 413 {types.NewTime(types.FromGoTime(time.Now()), allegrosql.TypeDatetime, 0), ast.Mul, 0, 0}, 414 {types.NewTime(types.FromGoTime(time.Now()), allegrosql.TypeDatetime, 6), ast.Mul, 0, 0}, 415 {types.Duration{Duration: 100000000, Fsp: 6}, ast.Mul, 0, 0}, 416 417 // div 418 {1, ast.Div, float64(1), 1}, 419 {1, ast.Div, float64(0), nil}, 420 {1, ast.Div, 2, 0.5}, 421 {1, ast.Div, 0, nil}, 422 423 // int div 424 {1, ast.IntDiv, 2, 0}, 425 {1, ast.IntDiv, uint64(2), 0}, 426 {1, ast.IntDiv, 0, nil}, 427 {1, ast.IntDiv, uint64(0), nil}, 428 {uint64(1), ast.IntDiv, 2, 0}, 429 {uint64(1), ast.IntDiv, uint64(2), 0}, 430 {uint64(1), ast.IntDiv, 0, nil}, 431 {uint64(1), ast.IntDiv, uint64(0), nil}, 432 {1.0, ast.IntDiv, 2.0, 0}, 433 434 // mod 435 {10, ast.Mod, 2, 0}, 436 {10, ast.Mod, uint64(2), 0}, 437 {10, ast.Mod, 0, nil}, 438 {10, ast.Mod, uint64(0), nil}, 439 {-10, ast.Mod, uint64(2), 0}, 440 {uint64(10), ast.Mod, 2, 0}, 441 {uint64(10), ast.Mod, uint64(2), 0}, 442 {uint64(10), ast.Mod, 0, nil}, 443 {uint64(10), ast.Mod, uint64(0), nil}, 444 {uint64(10), ast.Mod, -2, 0}, 445 {float64(10), ast.Mod, 2, 0}, 446 {float64(10), ast.Mod, 0, nil}, 447 {types.NewDecFromInt(10), ast.Mod, 2, 0}, 448 {types.NewDecFromInt(10), ast.Mod, 0, nil}, 449 } 450 451 for _, t := range tbl { 452 fc := funcs[t.op] 453 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.lhs, t.rhs))) 454 c.Assert(err, IsNil) 455 v, err := evalBuiltinFunc(f, chunk.Row{}) 456 c.Assert(err, IsNil) 457 switch v.HoTT() { 458 case types.HoTTNull: 459 c.Assert(t.ret, IsNil) 460 default: 461 // we use float64 as the result type check for all. 462 sc := s.ctx.GetStochastikVars().StmtCtx 463 f, err := v.ToFloat64(sc) 464 c.Assert(err, IsNil) 465 d := types.NewCauset(t.ret) 466 r, err := d.ToFloat64(sc) 467 c.Assert(err, IsNil) 468 c.Assert(r, Equals, f) 469 } 470 } 471 472 testcases := []struct { 473 lhs interface{} 474 op string 475 rhs interface{} 476 }{ 477 // div 478 {1, ast.Div, float64(0)}, 479 {1, ast.Div, 0}, 480 // int div 481 {1, ast.IntDiv, 0}, 482 {1, ast.IntDiv, uint64(0)}, 483 {uint64(1), ast.IntDiv, 0}, 484 {uint64(1), ast.IntDiv, uint64(0)}, 485 // mod 486 {10, ast.Mod, 0}, 487 {10, ast.Mod, uint64(0)}, 488 {uint64(10), ast.Mod, 0}, 489 {uint64(10), ast.Mod, uint64(0)}, 490 {float64(10), ast.Mod, 0}, 491 {types.NewDecFromInt(10), ast.Mod, 0}, 492 } 493 494 oldInSelectStmt := s.ctx.GetStochastikVars().StmtCtx.InSelectStmt 495 s.ctx.GetStochastikVars().StmtCtx.InSelectStmt = false 496 oldALLEGROSQLMode := s.ctx.GetStochastikVars().ALLEGROSQLMode 497 s.ctx.GetStochastikVars().ALLEGROSQLMode |= allegrosql.ModeErrorForDivisionByZero 498 oldInInsertStmt := s.ctx.GetStochastikVars().StmtCtx.InInsertStmt 499 s.ctx.GetStochastikVars().StmtCtx.InInsertStmt = true 500 for _, t := range testcases { 501 fc := funcs[t.op] 502 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.lhs, t.rhs))) 503 c.Assert(err, IsNil) 504 _, err = evalBuiltinFunc(f, chunk.Row{}) 505 c.Assert(err, NotNil) 506 } 507 508 oldDividedByZeroAsWarning := s.ctx.GetStochastikVars().StmtCtx.DividedByZeroAsWarning 509 s.ctx.GetStochastikVars().StmtCtx.DividedByZeroAsWarning = true 510 for _, t := range testcases { 511 fc := funcs[t.op] 512 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.lhs, t.rhs))) 513 c.Assert(err, IsNil) 514 v, err := evalBuiltinFunc(f, chunk.Row{}) 515 c.Assert(err, IsNil) 516 c.Assert(v.HoTT(), Equals, types.HoTTNull) 517 } 518 519 s.ctx.GetStochastikVars().StmtCtx.InSelectStmt = oldInSelectStmt 520 s.ctx.GetStochastikVars().ALLEGROSQLMode = oldALLEGROSQLMode 521 s.ctx.GetStochastikVars().StmtCtx.InInsertStmt = oldInInsertStmt 522 s.ctx.GetStochastikVars().StmtCtx.DividedByZeroAsWarning = oldDividedByZeroAsWarning 523 } 524 525 func (s *testEvaluatorSuite) TestExtract(c *C) { 526 str := "2011-11-11 10:10:10.123456" 527 tbl := []struct { 528 Unit string 529 Expect int64 530 }{ 531 {"MICROSECOND", 123456}, 532 {"SECOND", 10}, 533 {"MINUTE", 10}, 534 {"HOUR", 10}, 535 {"DAY", 11}, 536 {"WEEK", 45}, 537 {"MONTH", 11}, 538 {"QUARTER", 4}, 539 {"YEAR", 2011}, 540 {"SECOND_MICROSECOND", 10123456}, 541 {"MINUTE_MICROSECOND", 1010123456}, 542 {"MINUTE_SECOND", 1010}, 543 {"HOUR_MICROSECOND", 101010123456}, 544 {"HOUR_SECOND", 101010}, 545 {"HOUR_MINUTE", 1010}, 546 {"DAY_MICROSECOND", 11101010123456}, 547 {"DAY_SECOND", 11101010}, 548 {"DAY_MINUTE", 111010}, 549 {"DAY_HOUR", 1110}, 550 {"YEAR_MONTH", 201111}, 551 } 552 for _, t := range tbl { 553 fc := funcs[ast.Extract] 554 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.Unit, str))) 555 c.Assert(err, IsNil) 556 v, err := evalBuiltinFunc(f, chunk.Row{}) 557 c.Assert(err, IsNil) 558 c.Assert(v, solitonutil.CausetEquals, types.NewCauset(t.Expect)) 559 } 560 561 // Test nil 562 fc := funcs[ast.Extract] 563 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets("SECOND", nil))) 564 c.Assert(err, IsNil) 565 v, err := evalBuiltinFunc(f, chunk.Row{}) 566 c.Assert(err, IsNil) 567 c.Assert(v.HoTT(), Equals, types.HoTTNull) 568 } 569 570 func (s *testEvaluatorSuite) TestUnaryOp(c *C) { 571 tbl := []struct { 572 arg interface{} 573 op string 574 result interface{} 575 }{ 576 // test NOT. 577 {1, ast.UnaryNot, int64(0)}, 578 {0, ast.UnaryNot, int64(1)}, 579 {nil, ast.UnaryNot, nil}, 580 {types.NewBinaryLiteralFromUint(0, -1), ast.UnaryNot, int64(1)}, 581 {types.NewBinaryLiteralFromUint(1, -1), ast.UnaryNot, int64(0)}, 582 {types.Enum{Name: "a", Value: 1}, ast.UnaryNot, int64(0)}, 583 {types.Set{Name: "a", Value: 1}, ast.UnaryNot, int64(0)}, 584 585 // test BitNeg. 586 {nil, ast.BitNeg, nil}, 587 {-1, ast.BitNeg, uint64(0)}, 588 589 // test Minus. 590 {nil, ast.UnaryMinus, nil}, 591 {float64(1.0), ast.UnaryMinus, float64(-1.0)}, 592 {int64(1), ast.UnaryMinus, int64(-1)}, 593 {int64(1), ast.UnaryMinus, int64(-1)}, 594 {uint64(1), ast.UnaryMinus, -int64(1)}, 595 {"1.0", ast.UnaryMinus, -1.0}, 596 {[]byte("1.0"), ast.UnaryMinus, -1.0}, 597 {types.NewBinaryLiteralFromUint(1, -1), ast.UnaryMinus, -1.0}, 598 {true, ast.UnaryMinus, int64(-1)}, 599 {false, ast.UnaryMinus, int64(0)}, 600 {types.Enum{Name: "a", Value: 1}, ast.UnaryMinus, -1.0}, 601 {types.Set{Name: "a", Value: 1}, ast.UnaryMinus, -1.0}, 602 } 603 for i, t := range tbl { 604 fc := funcs[t.op] 605 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.arg))) 606 c.Assert(err, IsNil) 607 result, err := evalBuiltinFunc(f, chunk.Row{}) 608 c.Assert(err, IsNil) 609 c.Assert(result, solitonutil.CausetEquals, types.NewCauset(t.result), Commentf("%d", i)) 610 } 611 612 tbl = []struct { 613 arg interface{} 614 op string 615 result interface{} 616 }{ 617 {types.NewDecFromInt(1), ast.UnaryMinus, types.NewDecFromInt(-1)}, 618 {types.ZeroDuration, ast.UnaryMinus, new(types.MyDecimal)}, 619 {types.NewTime(types.FromGoTime(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)), allegrosql.TypeDatetime, 0), ast.UnaryMinus, types.NewDecFromInt(-20091110230000)}, 620 } 621 622 for _, t := range tbl { 623 fc := funcs[t.op] 624 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.arg))) 625 c.Assert(err, IsNil) 626 c.Assert(f, NotNil) 627 result, err := evalBuiltinFunc(f, chunk.Row{}) 628 c.Assert(err, IsNil) 629 630 expect := types.NewCauset(t.result) 631 ret, err := result.CompareCauset(s.ctx.GetStochastikVars().StmtCtx, &expect) 632 c.Assert(err, IsNil) 633 c.Assert(ret, Equals, 0, Commentf("%v %s", t.arg, t.op)) 634 } 635 } 636 637 func (s *testEvaluatorSuite) TestMod(c *C) { 638 fc := funcs[ast.Mod] 639 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(234, 10))) 640 c.Assert(err, IsNil) 641 r, err := evalBuiltinFunc(f, chunk.Row{}) 642 c.Assert(err, IsNil) 643 c.Assert(r, solitonutil.CausetEquals, types.NewIntCauset(4)) 644 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(29, 9))) 645 c.Assert(err, IsNil) 646 r, err = evalBuiltinFunc(f, chunk.Row{}) 647 c.Assert(err, IsNil) 648 c.Assert(r, solitonutil.CausetEquals, types.NewIntCauset(2)) 649 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(34.5, 3))) 650 c.Assert(err, IsNil) 651 r, err = evalBuiltinFunc(f, chunk.Row{}) 652 c.Assert(err, IsNil) 653 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(1.5)) 654 }