github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_math_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 "math" 18 "runtime" 19 "time" 20 21 . "github.com/whtcorpsinc/check" 22 "github.com/whtcorpsinc/BerolinaSQL/ast" 23 "github.com/whtcorpsinc/BerolinaSQL/charset" 24 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 25 "github.com/whtcorpsinc/milevadb/types" 26 "github.com/whtcorpsinc/milevadb/soliton/chunk" 27 "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 28 "github.com/whtcorpsinc/fidelpb/go-fidelpb" 29 ) 30 31 func (s *testEvaluatorSuite) TestAbs(c *C) { 32 tbl := []struct { 33 Arg interface{} 34 Ret interface{} 35 }{ 36 {nil, nil}, 37 {int64(1), int64(1)}, 38 {uint64(1), uint64(1)}, 39 {int64(-1), int64(1)}, 40 {float64(3.14), float64(3.14)}, 41 {float64(-3.14), float64(3.14)}, 42 } 43 44 Dtbl := tblToDtbl(tbl) 45 46 for _, t := range Dtbl { 47 fc := funcs[ast.Abs] 48 f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"])) 49 c.Assert(err, IsNil) 50 v, err := evalBuiltinFunc(f, chunk.Event{}) 51 c.Assert(err, IsNil) 52 c.Assert(v, solitonutil.CausetEquals, t["Ret"][0]) 53 } 54 } 55 56 func (s *testEvaluatorSuite) TestCeil(c *C) { 57 sc := s.ctx.GetStochastikVars().StmtCtx 58 tmpIT := sc.IgnoreTruncate 59 sc.IgnoreTruncate = true 60 defer func() { 61 sc.IgnoreTruncate = tmpIT 62 }() 63 64 type testCase struct { 65 arg interface{} 66 expect interface{} 67 isNil bool 68 getErr bool 69 } 70 71 cases := []testCase{ 72 {nil, nil, true, false}, 73 {int64(1), int64(1), false, false}, 74 {float64(1.23), float64(2), false, false}, 75 {float64(-1.23), float64(-1), false, false}, 76 {"1.23", float64(2), false, false}, 77 {"-1.23", float64(-1), false, false}, 78 {"milevadb", float64(0), false, false}, 79 {"1milevadb", float64(1), false, false}} 80 81 memexs := []Expression{ 82 &Constant{ 83 Value: types.NewCauset(0), 84 RetType: types.NewFieldType(allegrosql.TypeTiny), 85 }, 86 &Constant{ 87 Value: types.NewFloat64Causet(float64(12.34)), 88 RetType: types.NewFieldType(allegrosql.TypeFloat), 89 }, 90 } 91 92 runCasesOn := func(funcName string, cases []testCase, exps []Expression) { 93 for _, test := range cases { 94 f, err := newFunctionForTest(s.ctx, funcName, s.primitiveValsToConstants([]interface{}{test.arg})...) 95 c.Assert(err, IsNil) 96 97 result, err := f.Eval(chunk.Event{}) 98 if test.getErr { 99 c.Assert(err, NotNil) 100 } else { 101 c.Assert(err, IsNil) 102 if test.isNil { 103 c.Assert(result.HoTT(), Equals, types.HoTTNull) 104 } else { 105 c.Assert(result, solitonutil.CausetEquals, types.NewCauset(test.expect)) 106 } 107 } 108 } 109 110 for _, exp := range exps { 111 _, err := funcs[funcName].getFunction(s.ctx, []Expression{exp}) 112 c.Assert(err, IsNil) 113 } 114 } 115 116 runCasesOn(ast.Ceil, cases, memexs) 117 runCasesOn(ast.Ceiling, cases, memexs) 118 } 119 120 func (s *testEvaluatorSuite) TestExp(c *C) { 121 tests := []struct { 122 args interface{} 123 expect float64 124 isNil bool 125 getWarning bool 126 errMsg string 127 }{ 128 {nil, 0, true, false, ""}, 129 {int64(1), 2.718281828459045, false, false, ""}, 130 {float64(1.23), 3.4212295362896734, false, false, ""}, 131 {float64(-1.23), 0.2922925776808594, false, false, ""}, 132 {float64(0), 1, false, false, ""}, 133 {"0", 1, false, false, ""}, 134 {"milevadb", 0, false, true, ""}, 135 {float64(100000), 0, false, true, "[types:1690]DOUBLE value is out of range in 'exp(100000)'"}, 136 } 137 138 if runtime.GOARCH == "ppc64le" { 139 tests[1].expect = 2.7182818284590455 140 } 141 142 for _, test := range tests { 143 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 144 f, err := newFunctionForTest(s.ctx, ast.Exp, s.primitiveValsToConstants([]interface{}{test.args})...) 145 c.Assert(err, IsNil) 146 147 result, err := f.Eval(chunk.Event{}) 148 if test.getWarning { 149 if test.errMsg != "" { 150 c.Assert(err, NotNil) 151 c.Assert(err.Error(), Equals, test.errMsg) 152 } else { 153 c.Assert(err, IsNil) 154 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1) 155 } 156 } else { 157 c.Assert(err, IsNil) 158 if test.isNil { 159 c.Assert(result.HoTT(), Equals, types.HoTTNull) 160 } else { 161 c.Assert(result.GetFloat64(), Equals, test.expect) 162 } 163 } 164 } 165 166 _, err := funcs[ast.Exp].getFunction(s.ctx, []Expression{NewZero()}) 167 c.Assert(err, IsNil) 168 } 169 170 func (s *testEvaluatorSuite) TestFloor(c *C) { 171 sc := s.ctx.GetStochastikVars().StmtCtx 172 tmpIT := sc.IgnoreTruncate 173 sc.IgnoreTruncate = true 174 defer func() { 175 sc.IgnoreTruncate = tmpIT 176 }() 177 178 genDuration := func(h, m, s int64) types.Duration { 179 duration := time.Duration(h)*time.Hour + 180 time.Duration(m)*time.Minute + 181 time.Duration(s)*time.Second 182 183 return types.Duration{Duration: duration, Fsp: types.DefaultFsp} 184 } 185 186 genTime := func(y, m, d int) types.Time { 187 return types.NewTime(types.FromDate(y, m, d, 0, 0, 0, 0), allegrosql.TypeDatetime, types.DefaultFsp) 188 } 189 190 for _, test := range []struct { 191 arg interface{} 192 expect interface{} 193 isNil bool 194 getErr bool 195 }{ 196 {nil, nil, true, false}, 197 {int64(1), int64(1), false, false}, 198 {float64(1.23), float64(1), false, false}, 199 {float64(-1.23), float64(-2), false, false}, 200 {"1.23", float64(1), false, false}, 201 {"-1.23", float64(-2), false, false}, 202 {"-1.b23", float64(-1), false, false}, 203 {"abce", float64(0), false, false}, 204 {genDuration(12, 59, 59), float64(125959), false, false}, 205 {genDuration(0, 12, 34), float64(1234), false, false}, 206 {genTime(2020, 7, 19), float64(20170719000000), false, false}, 207 } { 208 f, err := newFunctionForTest(s.ctx, ast.Floor, s.primitiveValsToConstants([]interface{}{test.arg})...) 209 c.Assert(err, IsNil) 210 211 result, err := f.Eval(chunk.Event{}) 212 if test.getErr { 213 c.Assert(err, NotNil) 214 } else { 215 c.Assert(err, IsNil) 216 if test.isNil { 217 c.Assert(result.HoTT(), Equals, types.HoTTNull) 218 } else { 219 c.Assert(result, solitonutil.CausetEquals, types.NewCauset(test.expect)) 220 } 221 } 222 } 223 224 for _, exp := range []Expression{ 225 &Constant{ 226 Value: types.NewCauset(0), 227 RetType: types.NewFieldType(allegrosql.TypeTiny), 228 }, 229 &Constant{ 230 Value: types.NewFloat64Causet(float64(12.34)), 231 RetType: types.NewFieldType(allegrosql.TypeFloat), 232 }, 233 } { 234 _, err := funcs[ast.Floor].getFunction(s.ctx, []Expression{exp}) 235 c.Assert(err, IsNil) 236 } 237 } 238 239 func (s *testEvaluatorSuite) TestLog(c *C) { 240 tests := []struct { 241 args []interface{} 242 expect float64 243 isNil bool 244 warningCount uint16 245 }{ 246 {[]interface{}{nil}, 0, true, 0}, 247 {[]interface{}{nil, nil}, 0, true, 0}, 248 {[]interface{}{int64(100)}, 4.605170185988092, false, 0}, 249 {[]interface{}{float64(100)}, 4.605170185988092, false, 0}, 250 {[]interface{}{int64(10), int64(100)}, 2, false, 0}, 251 {[]interface{}{float64(10), float64(100)}, 2, false, 0}, 252 {[]interface{}{float64(-1)}, 0, true, 1}, 253 {[]interface{}{float64(2), float64(-1)}, 0, true, 1}, 254 {[]interface{}{float64(-1), float64(2)}, 0, true, 1}, 255 {[]interface{}{float64(1), float64(2)}, 0, true, 1}, 256 {[]interface{}{float64(0.5), float64(0.25)}, 2, false, 0}, 257 {[]interface{}{"abc"}, 0, true, 2}, 258 } 259 260 for _, test := range tests { 261 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 262 f, err := newFunctionForTest(s.ctx, ast.Log, s.primitiveValsToConstants(test.args)...) 263 c.Assert(err, IsNil) 264 265 result, err := f.Eval(chunk.Event{}) 266 c.Assert(err, IsNil) 267 if test.warningCount > 0 { 268 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+test.warningCount) 269 } 270 if test.isNil { 271 c.Assert(result.HoTT(), Equals, types.HoTTNull) 272 } else { 273 c.Assert(result.GetFloat64(), Equals, test.expect) 274 } 275 } 276 277 _, err := funcs[ast.Log].getFunction(s.ctx, []Expression{NewZero()}) 278 c.Assert(err, IsNil) 279 } 280 281 func (s *testEvaluatorSuite) TestLog2(c *C) { 282 tests := []struct { 283 args interface{} 284 expect float64 285 isNil bool 286 warningCount uint16 287 }{ 288 {nil, 0, true, 0}, 289 {int64(16), 4, false, 0}, 290 {float64(16), 4, false, 0}, 291 {int64(5), 2.321928094887362, false, 0}, 292 {int64(-1), 0, true, 1}, 293 {"4abc", 2, false, 1}, 294 {"abc", 0, true, 2}, 295 } 296 297 for _, test := range tests { 298 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 299 f, err := newFunctionForTest(s.ctx, ast.Log2, s.primitiveValsToConstants([]interface{}{test.args})...) 300 c.Assert(err, IsNil) 301 302 result, err := f.Eval(chunk.Event{}) 303 c.Assert(err, IsNil) 304 if test.warningCount > 0 { 305 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+test.warningCount) 306 } 307 if test.isNil { 308 c.Assert(result.HoTT(), Equals, types.HoTTNull) 309 } else { 310 c.Assert(result.GetFloat64(), Equals, test.expect) 311 } 312 } 313 314 _, err := funcs[ast.Log2].getFunction(s.ctx, []Expression{NewZero()}) 315 c.Assert(err, IsNil) 316 } 317 318 func (s *testEvaluatorSuite) TestLog10(c *C) { 319 tests := []struct { 320 args interface{} 321 expect float64 322 isNil bool 323 warningCount uint16 324 }{ 325 {nil, 0, true, 0}, 326 {int64(100), 2, false, 0}, 327 {float64(100), 2, false, 0}, 328 {int64(101), 2.0043213737826426, false, 0}, 329 {int64(-1), 0, true, 1}, 330 {"100abc", 2, false, 1}, 331 {"abc", 0, true, 2}, 332 } 333 334 for _, test := range tests { 335 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 336 f, err := newFunctionForTest(s.ctx, ast.Log10, s.primitiveValsToConstants([]interface{}{test.args})...) 337 c.Assert(err, IsNil) 338 339 result, err := f.Eval(chunk.Event{}) 340 c.Assert(err, IsNil) 341 if test.warningCount > 0 { 342 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+test.warningCount) 343 } 344 if test.isNil { 345 c.Assert(result.HoTT(), Equals, types.HoTTNull) 346 } else { 347 c.Assert(result.GetFloat64(), Equals, test.expect) 348 } 349 } 350 351 _, err := funcs[ast.Log10].getFunction(s.ctx, []Expression{NewZero()}) 352 c.Assert(err, IsNil) 353 } 354 355 func (s *testEvaluatorSuite) TestRand(c *C) { 356 fc := funcs[ast.Rand] 357 f, err := fc.getFunction(s.ctx, nil) 358 c.Assert(err, IsNil) 359 v, err := evalBuiltinFunc(f, chunk.Event{}) 360 c.Assert(err, IsNil) 361 c.Assert(v.GetFloat64(), Less, float64(1)) 362 c.Assert(v.GetFloat64(), GreaterEqual, float64(0)) 363 364 // issue 3211 365 f2, err := fc.getFunction(s.ctx, []Expression{&Constant{Value: types.NewIntCauset(20160101), RetType: types.NewFieldType(allegrosql.TypeLonglong)}}) 366 c.Assert(err, IsNil) 367 randGen := NewWithSeed(20160101) 368 for i := 0; i < 3; i++ { 369 v, err = evalBuiltinFunc(f2, chunk.Event{}) 370 c.Assert(err, IsNil) 371 c.Assert(v.GetFloat64(), Equals, randGen.Gen()) 372 } 373 } 374 375 func (s *testEvaluatorSuite) TestPow(c *C) { 376 tbl := []struct { 377 Arg []interface{} 378 Ret float64 379 }{ 380 {[]interface{}{1, 3}, 1}, 381 {[]interface{}{2, 2}, 4}, 382 {[]interface{}{4, 0.5}, 2}, 383 {[]interface{}{4, -2}, 0.0625}, 384 } 385 386 Dtbl := tblToDtbl(tbl) 387 388 for _, t := range Dtbl { 389 fc := funcs[ast.Pow] 390 f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"])) 391 c.Assert(err, IsNil) 392 v, err := evalBuiltinFunc(f, chunk.Event{}) 393 c.Assert(err, IsNil) 394 c.Assert(v, solitonutil.CausetEquals, t["Ret"][0]) 395 } 396 397 errTbl := []struct { 398 Arg []interface{} 399 }{ 400 {[]interface{}{"test", "test"}}, 401 {[]interface{}{1, "test"}}, 402 {[]interface{}{10, 700}}, // added overflow test 403 } 404 405 errDtbl := tblToDtbl(errTbl) 406 for i, t := range errDtbl { 407 fc := funcs[ast.Pow] 408 f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"])) 409 c.Assert(err, IsNil) 410 _, err = evalBuiltinFunc(f, chunk.Event{}) 411 if i == 2 { 412 c.Assert(err, NotNil) 413 c.Assert(err.Error(), Equals, "[types:1690]DOUBLE value is out of range in 'pow(10, 700)'") 414 } else { 415 c.Assert(err, IsNil) 416 } 417 } 418 c.Assert(int(s.ctx.GetStochastikVars().StmtCtx.WarningCount()), Equals, 3) 419 } 420 421 func (s *testEvaluatorSuite) TestRound(c *C) { 422 newDec := types.NewDecFromStringForTest 423 tbl := []struct { 424 Arg []interface{} 425 Ret interface{} 426 }{ 427 {[]interface{}{-1.23}, -1}, 428 {[]interface{}{-1.23, 0}, -1}, 429 {[]interface{}{-1.58}, -2}, 430 {[]interface{}{1.58}, 2}, 431 {[]interface{}{1.298, 1}, 1.3}, 432 {[]interface{}{1.298}, 1}, 433 {[]interface{}{1.298, 0}, 1}, 434 {[]interface{}{23.298, -1}, 20}, 435 {[]interface{}{newDec("-1.23")}, newDec("-1")}, 436 {[]interface{}{newDec("-1.23"), 1}, newDec("-1.2")}, 437 {[]interface{}{newDec("-1.58")}, newDec("-2")}, 438 {[]interface{}{newDec("1.58")}, newDec("2")}, 439 {[]interface{}{newDec("1.58"), 1}, newDec("1.6")}, 440 {[]interface{}{newDec("23.298"), -1}, newDec("20")}, 441 {[]interface{}{nil, 2}, nil}, 442 {[]interface{}{1, -2012}, 0}, 443 {[]interface{}{1, -201299999999999}, 0}, 444 } 445 446 Dtbl := tblToDtbl(tbl) 447 448 for _, t := range Dtbl { 449 fc := funcs[ast.Round] 450 f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"])) 451 c.Assert(err, IsNil) 452 switch f.(type) { 453 case *builtinRoundWithFracIntSig: 454 c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundWithFracInt) 455 case *builtinRoundWithFracDecSig: 456 c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundWithFracDec) 457 case *builtinRoundWithFracRealSig: 458 c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundWithFracReal) 459 case *builtinRoundIntSig: 460 c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundInt) 461 case *builtinRoundDecSig: 462 c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundDec) 463 case *builtinRoundRealSig: 464 c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundReal) 465 } 466 v, err := evalBuiltinFunc(f, chunk.Event{}) 467 c.Assert(err, IsNil) 468 c.Assert(v, solitonutil.CausetEquals, t["Ret"][0]) 469 } 470 } 471 472 func (s *testEvaluatorSuite) TestTruncate(c *C) { 473 newDec := types.NewDecFromStringForTest 474 tbl := []struct { 475 Arg []interface{} 476 Ret interface{} 477 }{ 478 {[]interface{}{-1.23, 0}, -1}, 479 {[]interface{}{1.58, 0}, 1}, 480 {[]interface{}{1.298, 1}, 1.2}, 481 {[]interface{}{123.2, -1}, 120}, 482 {[]interface{}{123.2, 100}, 123.2}, 483 {[]interface{}{123.2, -100}, 0}, 484 {[]interface{}{123.2, -100}, 0}, 485 {[]interface{}{1.797693134862315708145274237317043567981e+308, 2}, 486 1.797693134862315708145274237317043567981e+308}, 487 {[]interface{}{newDec("-1.23"), 0}, newDec("-1")}, 488 {[]interface{}{newDec("-1.23"), 1}, newDec("-1.2")}, 489 {[]interface{}{newDec("-11.23"), -1}, newDec("-10")}, 490 {[]interface{}{newDec("1.58"), 0}, newDec("1")}, 491 {[]interface{}{newDec("1.58"), 1}, newDec("1.5")}, 492 {[]interface{}{newDec("11.58"), -1}, newDec("10")}, 493 {[]interface{}{newDec("23.298"), -1}, newDec("20")}, 494 {[]interface{}{newDec("23.298"), -100}, newDec("0")}, 495 {[]interface{}{newDec("23.298"), 100}, newDec("23.298")}, 496 {[]interface{}{nil, 2}, nil}, 497 {[]interface{}{uint64(9223372036854775808), -10}, 9223372030000000000}, 498 {[]interface{}{9223372036854775807, -7}, 9223372036850000000}, 499 {[]interface{}{uint64(18446744073709551615), -10}, uint64(18446744070000000000)}, 500 } 501 502 Dtbl := tblToDtbl(tbl) 503 504 for _, t := range Dtbl { 505 fc := funcs[ast.Truncate] 506 f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"])) 507 c.Assert(err, IsNil) 508 c.Assert(f, NotNil) 509 v, err := evalBuiltinFunc(f, chunk.Event{}) 510 c.Assert(err, IsNil) 511 c.Assert(v, solitonutil.CausetEquals, t["Ret"][0]) 512 } 513 } 514 515 func (s *testEvaluatorSuite) TestCRC32(c *C) { 516 tbl := []struct { 517 Arg []interface{} 518 Ret interface{} 519 }{ 520 {[]interface{}{nil}, nil}, 521 {[]interface{}{""}, 0}, 522 {[]interface{}{-1}, 808273962}, 523 {[]interface{}{"-1"}, 808273962}, 524 {[]interface{}{"allegrosql"}, 2501908538}, 525 {[]interface{}{"MyALLEGROSQL"}, 3259397556}, 526 {[]interface{}{"hello"}, 907060870}, 527 } 528 529 Dtbl := tblToDtbl(tbl) 530 531 for _, t := range Dtbl { 532 fc := funcs[ast.CRC32] 533 f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"])) 534 c.Assert(err, IsNil) 535 v, err := evalBuiltinFunc(f, chunk.Event{}) 536 c.Assert(err, IsNil) 537 c.Assert(v, solitonutil.CausetEquals, t["Ret"][0]) 538 } 539 } 540 541 func (s *testEvaluatorSuite) TestConv(c *C) { 542 cases := []struct { 543 args []interface{} 544 expected interface{} 545 isNil bool 546 getErr bool 547 }{ 548 {[]interface{}{"a", 16, 2}, "1010", false, false}, 549 {[]interface{}{"6E", 18, 8}, "172", false, false}, 550 {[]interface{}{"-17", 10, -18}, "-H", false, false}, 551 {[]interface{}{"-17", 10, 18}, "2D3FGB0B9CG4BD1H", false, false}, 552 {[]interface{}{nil, 10, 10}, "0", true, false}, 553 {[]interface{}{"+18aZ", 7, 36}, "1", false, false}, 554 {[]interface{}{"18446744073709551615", -10, 16}, "7FFFFFFFFFFFFFFF", false, false}, 555 {[]interface{}{"12F", -10, 16}, "C", false, false}, 556 {[]interface{}{" FF ", 16, 10}, "255", false, false}, 557 {[]interface{}{"MilevaDB", 10, 8}, "0", false, false}, 558 {[]interface{}{"aa", 10, 2}, "0", false, false}, 559 {[]interface{}{" A", -10, 16}, "0", false, false}, 560 {[]interface{}{"a6a", 10, 8}, "0", false, false}, 561 {[]interface{}{"a6a", 1, 8}, "0", true, false}, 562 } 563 564 for _, t := range cases { 565 f, err := newFunctionForTest(s.ctx, ast.Conv, s.primitiveValsToConstants(t.args)...) 566 c.Assert(err, IsNil) 567 tp := f.GetType() 568 c.Assert(tp.Tp, Equals, allegrosql.TypeVarString) 569 c.Assert(tp.Charset, Equals, charset.CharsetUTF8MB4) 570 c.Assert(tp.DefCauslate, Equals, charset.DefCauslationUTF8MB4) 571 c.Assert(tp.Flag, Equals, uint(0)) 572 573 d, err := f.Eval(chunk.Event{}) 574 if t.getErr { 575 c.Assert(err, NotNil) 576 } else { 577 c.Assert(err, IsNil) 578 if t.isNil { 579 c.Assert(d.HoTT(), Equals, types.HoTTNull) 580 } else { 581 c.Assert(d.GetString(), Equals, t.expected) 582 } 583 } 584 } 585 586 v := []struct { 587 s string 588 base int64 589 ret string 590 }{ 591 {"-123456D1f", 5, "-1234"}, 592 {"+12azD", 16, "12a"}, 593 {"+", 12, ""}, 594 } 595 for _, t := range v { 596 r := getValidPrefix(t.s, t.base) 597 c.Assert(r, Equals, t.ret) 598 } 599 600 _, err := funcs[ast.Conv].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()}) 601 c.Assert(err, IsNil) 602 } 603 604 func (s *testEvaluatorSuite) TestSign(c *C) { 605 sc := s.ctx.GetStochastikVars().StmtCtx 606 tmpIT := sc.IgnoreTruncate 607 sc.IgnoreTruncate = true 608 defer func() { 609 sc.IgnoreTruncate = tmpIT 610 }() 611 612 for _, t := range []struct { 613 num []interface{} 614 ret interface{} 615 }{ 616 {[]interface{}{nil}, nil}, 617 {[]interface{}{1}, int64(1)}, 618 {[]interface{}{0}, int64(0)}, 619 {[]interface{}{-1}, int64(-1)}, 620 {[]interface{}{0.4}, int64(1)}, 621 {[]interface{}{-0.4}, int64(-1)}, 622 {[]interface{}{"1"}, int64(1)}, 623 {[]interface{}{"-1"}, int64(-1)}, 624 {[]interface{}{"1a"}, int64(1)}, 625 {[]interface{}{"-1a"}, int64(-1)}, 626 {[]interface{}{"a"}, int64(0)}, 627 {[]interface{}{uint64(9223372036854775808)}, int64(1)}, 628 } { 629 fc := funcs[ast.Sign] 630 f, err := fc.getFunction(s.ctx, s.primitiveValsToConstants(t.num)) 631 c.Assert(err, IsNil, Commentf("%v", t)) 632 v, err := evalBuiltinFunc(f, chunk.Event{}) 633 c.Assert(err, IsNil, Commentf("%v", t)) 634 c.Assert(v, solitonutil.CausetEquals, types.NewCauset(t.ret), Commentf("%v", t)) 635 } 636 } 637 638 func (s *testEvaluatorSuite) TestDegrees(c *C) { 639 sc := s.ctx.GetStochastikVars().StmtCtx 640 sc.IgnoreTruncate = false 641 cases := []struct { 642 args interface{} 643 expected float64 644 isNil bool 645 getWarning bool 646 }{ 647 {nil, 0, true, false}, 648 {int64(0), float64(0), false, false}, 649 {int64(1), float64(57.29577951308232), false, false}, 650 {float64(1), float64(57.29577951308232), false, false}, 651 {float64(math.Pi), float64(180), false, false}, 652 {float64(-math.Pi / 2), float64(-90), false, false}, 653 {"", float64(0), false, false}, 654 {"-2", float64(-114.59155902616465), false, false}, 655 {"abc", float64(0), false, true}, 656 {"+1abc", 57.29577951308232, false, true}, 657 } 658 659 for _, t := range cases { 660 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 661 f, err := newFunctionForTest(s.ctx, ast.Degrees, s.primitiveValsToConstants([]interface{}{t.args})...) 662 c.Assert(err, IsNil) 663 d, err := f.Eval(chunk.Event{}) 664 if t.getWarning { 665 c.Assert(err, IsNil) 666 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1) 667 } else { 668 c.Assert(err, IsNil) 669 if t.isNil { 670 c.Assert(d.HoTT(), Equals, types.HoTTNull) 671 } else { 672 c.Assert(d.GetFloat64(), Equals, t.expected) 673 } 674 } 675 } 676 _, err := funcs[ast.Degrees].getFunction(s.ctx, []Expression{NewZero()}) 677 c.Assert(err, IsNil) 678 } 679 680 func (s *testEvaluatorSuite) TestSqrt(c *C) { 681 tbl := []struct { 682 Arg []interface{} 683 Ret interface{} 684 }{ 685 {[]interface{}{nil}, nil}, 686 {[]interface{}{int64(1)}, float64(1)}, 687 {[]interface{}{float64(4)}, float64(2)}, 688 {[]interface{}{"4"}, float64(2)}, 689 {[]interface{}{"9"}, float64(3)}, 690 {[]interface{}{"-16"}, nil}, 691 } 692 693 for _, t := range tbl { 694 fc := funcs[ast.Sqrt] 695 f, err := fc.getFunction(s.ctx, s.primitiveValsToConstants(t.Arg)) 696 c.Assert(err, IsNil) 697 v, err := evalBuiltinFunc(f, chunk.Event{}) 698 c.Assert(err, IsNil) 699 c.Assert(v, solitonutil.CausetEquals, types.NewCauset(t.Ret), Commentf("%v", t)) 700 } 701 } 702 703 func (s *testEvaluatorSuite) TestPi(c *C) { 704 f, err := funcs[ast.PI].getFunction(s.ctx, nil) 705 c.Assert(err, IsNil) 706 707 pi, err := evalBuiltinFunc(f, chunk.Event{}) 708 c.Assert(err, IsNil) 709 c.Assert(pi, solitonutil.CausetEquals, types.NewCauset(math.Pi)) 710 } 711 712 func (s *testEvaluatorSuite) TestRadians(c *C) { 713 tbl := []struct { 714 Arg interface{} 715 Ret interface{} 716 }{ 717 {nil, nil}, 718 {0, float64(0)}, 719 {float64(180), float64(math.Pi)}, 720 {-360, -2 * float64(math.Pi)}, 721 {"180", float64(math.Pi)}, 722 } 723 724 Dtbl := tblToDtbl(tbl) 725 for _, t := range Dtbl { 726 fc := funcs[ast.Radians] 727 f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"])) 728 c.Assert(err, IsNil) 729 c.Assert(f, NotNil) 730 v, err := evalBuiltinFunc(f, chunk.Event{}) 731 c.Assert(err, IsNil) 732 c.Assert(v, solitonutil.CausetEquals, t["Ret"][0]) 733 } 734 735 invalidArg := "notNum" 736 fc := funcs[ast.Radians] 737 f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{types.NewCauset(invalidArg)})) 738 c.Assert(err, IsNil) 739 _, err = evalBuiltinFunc(f, chunk.Event{}) 740 c.Assert(err, IsNil) 741 c.Assert(int(s.ctx.GetStochastikVars().StmtCtx.WarningCount()), Equals, 1) 742 } 743 744 func (s *testEvaluatorSuite) TestSin(c *C) { 745 cases := []struct { 746 args interface{} 747 expected float64 748 isNil bool 749 getWarning bool 750 }{ 751 {nil, 0, true, false}, 752 {int64(0), float64(0), false, false}, 753 {math.Pi, float64(math.Sin(math.Pi)), false, false}, // Pie ==> 0 754 {-math.Pi, float64(math.Sin(-math.Pi)), false, false}, 755 {math.Pi / 2, float64(math.Sin(math.Pi / 2)), false, false}, // Pie/2 ==> 1 756 {-math.Pi / 2, float64(math.Sin(-math.Pi / 2)), false, false}, 757 {math.Pi / 6, float64(math.Sin(math.Pi / 6)), false, false}, // Pie/6(30 degrees) ==> 0.5 758 {-math.Pi / 6, float64(math.Sin(-math.Pi / 6)), false, false}, 759 {math.Pi * 2, float64(math.Sin(math.Pi * 2)), false, false}, 760 {"adfsdfgs", 0, false, true}, 761 {"0.000", 0, false, false}, 762 } 763 764 for _, t := range cases { 765 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 766 f, err := newFunctionForTest(s.ctx, ast.Sin, s.primitiveValsToConstants([]interface{}{t.args})...) 767 c.Assert(err, IsNil) 768 769 d, err := f.Eval(chunk.Event{}) 770 if t.getWarning { 771 c.Assert(err, IsNil) 772 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1) 773 } else { 774 c.Assert(err, IsNil) 775 if t.isNil { 776 c.Assert(d.HoTT(), Equals, types.HoTTNull) 777 } else { 778 c.Assert(d.GetFloat64(), Equals, t.expected) 779 } 780 } 781 } 782 783 _, err := funcs[ast.Sin].getFunction(s.ctx, []Expression{NewZero()}) 784 c.Assert(err, IsNil) 785 } 786 787 func (s *testEvaluatorSuite) TestCos(c *C) { 788 cases := []struct { 789 args interface{} 790 expected float64 791 isNil bool 792 getWarning bool 793 }{ 794 {nil, 0, true, false}, 795 {int64(0), float64(1), false, false}, 796 {math.Pi, float64(-1), false, false}, // cos pi equals -1 797 {-math.Pi, float64(-1), false, false}, 798 {math.Pi / 2, float64(math.Cos(math.Pi / 2)), false, false}, // Pi/2 is some near 0 (6.123233995736766e-17) but not 0. Even in math it is 0. 799 {-math.Pi / 2, float64(math.Cos(-math.Pi / 2)), false, false}, 800 {"0.000", float64(1), false, false}, // string value case 801 {"sdfgsfsdf", float64(0), false, true}, 802 } 803 804 for _, t := range cases { 805 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 806 f, err := newFunctionForTest(s.ctx, ast.Cos, s.primitiveValsToConstants([]interface{}{t.args})...) 807 c.Assert(err, IsNil) 808 809 d, err := f.Eval(chunk.Event{}) 810 if t.getWarning { 811 c.Assert(err, IsNil) 812 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1) 813 } else { 814 c.Assert(err, IsNil) 815 if t.isNil { 816 c.Assert(d.HoTT(), Equals, types.HoTTNull) 817 } else { 818 c.Assert(d.GetFloat64(), Equals, t.expected) 819 } 820 } 821 } 822 823 _, err := funcs[ast.Cos].getFunction(s.ctx, []Expression{NewZero()}) 824 c.Assert(err, IsNil) 825 } 826 827 func (s *testEvaluatorSuite) TestAcos(c *C) { 828 tests := []struct { 829 args interface{} 830 expect float64 831 isNil bool 832 getWarning bool 833 }{ 834 {nil, 0, true, false}, 835 {float64(1), 0, false, false}, 836 {float64(2), 0, true, false}, 837 {float64(-1), 3.141592653589793, false, false}, 838 {float64(-2), 0, true, false}, 839 {"milevadb", 0, false, true}, 840 } 841 842 for _, test := range tests { 843 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 844 f, err := newFunctionForTest(s.ctx, ast.Acos, s.primitiveValsToConstants([]interface{}{test.args})...) 845 c.Assert(err, IsNil) 846 847 result, err := f.Eval(chunk.Event{}) 848 if test.getWarning { 849 c.Assert(err, IsNil) 850 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1) 851 } else { 852 c.Assert(err, IsNil) 853 if test.isNil { 854 c.Assert(result.HoTT(), Equals, types.HoTTNull) 855 } else { 856 c.Assert(result.GetFloat64(), Equals, test.expect) 857 } 858 } 859 } 860 861 _, err := funcs[ast.Acos].getFunction(s.ctx, []Expression{NewZero()}) 862 c.Assert(err, IsNil) 863 } 864 865 func (s *testEvaluatorSuite) TestAsin(c *C) { 866 tests := []struct { 867 args interface{} 868 expect float64 869 isNil bool 870 getWarning bool 871 }{ 872 {nil, 0, true, false}, 873 {float64(1), 1.5707963267948966, false, false}, 874 {float64(2), 0, true, false}, 875 {float64(-1), -1.5707963267948966, false, false}, 876 {float64(-2), 0, true, false}, 877 {"milevadb", 0, false, true}, 878 } 879 880 for _, test := range tests { 881 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 882 f, err := newFunctionForTest(s.ctx, ast.Asin, s.primitiveValsToConstants([]interface{}{test.args})...) 883 c.Assert(err, IsNil) 884 885 result, err := f.Eval(chunk.Event{}) 886 if test.getWarning { 887 c.Assert(err, IsNil) 888 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1) 889 } else { 890 c.Assert(err, IsNil) 891 if test.isNil { 892 c.Assert(result.HoTT(), Equals, types.HoTTNull) 893 } else { 894 c.Assert(result.GetFloat64(), Equals, test.expect) 895 } 896 } 897 } 898 899 _, err := funcs[ast.Asin].getFunction(s.ctx, []Expression{NewZero()}) 900 c.Assert(err, IsNil) 901 } 902 903 func (s *testEvaluatorSuite) TestAtan(c *C) { 904 tests := []struct { 905 args []interface{} 906 expect float64 907 isNil bool 908 getWarning bool 909 }{ 910 {[]interface{}{nil}, 0, true, false}, 911 {[]interface{}{nil, nil}, 0, true, false}, 912 {[]interface{}{float64(1)}, 0.7853981633974483, false, false}, 913 {[]interface{}{float64(-1)}, -0.7853981633974483, false, false}, 914 {[]interface{}{float64(0), float64(-2)}, float64(math.Pi), false, false}, 915 {[]interface{}{"milevadb"}, 0, false, true}, 916 } 917 918 for _, test := range tests { 919 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 920 f, err := newFunctionForTest(s.ctx, ast.Atan, s.primitiveValsToConstants(test.args)...) 921 c.Assert(err, IsNil) 922 923 result, err := f.Eval(chunk.Event{}) 924 if test.getWarning { 925 c.Assert(err, IsNil) 926 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1) 927 } else { 928 c.Assert(err, IsNil) 929 if test.isNil { 930 c.Assert(result.HoTT(), Equals, types.HoTTNull) 931 } else { 932 c.Assert(result.GetFloat64(), Equals, test.expect) 933 } 934 } 935 } 936 937 _, err := funcs[ast.Atan].getFunction(s.ctx, []Expression{NewZero()}) 938 c.Assert(err, IsNil) 939 } 940 941 func (s *testEvaluatorSuite) TestTan(c *C) { 942 cases := []struct { 943 args interface{} 944 expected float64 945 isNil bool 946 getWarning bool 947 }{ 948 {nil, 0, true, false}, 949 {int64(0), float64(0), false, false}, 950 {math.Pi / 4, float64(1), false, false}, 951 {-math.Pi / 4, float64(-1), false, false}, 952 {math.Pi * 3 / 4, math.Tan(math.Pi * 3 / 4), false, false}, //in allegrosql and golang, it equals -1.0000000000000002, not -1 953 {"0.000", float64(0), false, false}, 954 {"sdfgsdfg", 0, false, true}, 955 } 956 957 for _, t := range cases { 958 preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount() 959 f, err := newFunctionForTest(s.ctx, ast.Tan, s.primitiveValsToConstants([]interface{}{t.args})...) 960 c.Assert(err, IsNil) 961 962 d, err := f.Eval(chunk.Event{}) 963 if t.getWarning { 964 c.Assert(err, IsNil) 965 c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1) 966 } else { 967 c.Assert(err, IsNil) 968 if t.isNil { 969 c.Assert(d.HoTT(), Equals, types.HoTTNull) 970 } else { 971 c.Assert(d.GetFloat64(), Equals, t.expected) 972 } 973 } 974 } 975 976 _, err := funcs[ast.Tan].getFunction(s.ctx, []Expression{NewZero()}) 977 c.Assert(err, IsNil) 978 } 979 980 func (s *testEvaluatorSuite) TestCot(c *C) { 981 tests := []struct { 982 args interface{} 983 expect float64 984 isNil bool 985 getErr bool 986 errMsg string 987 }{ 988 {nil, 0, true, false, ""}, 989 {float64(0), 0, false, true, "[types:1690]DOUBLE value is out of range in 'cot(0)'"}, 990 {float64(-1), -0.6420926159343308, false, false, ""}, 991 {float64(1), 0.6420926159343308, false, false, ""}, 992 {math.Pi / 4, 1 / math.Tan(math.Pi/4), false, false, ""}, 993 {math.Pi / 2, 1 / math.Tan(math.Pi/2), false, false, ""}, 994 {math.Pi, 1 / math.Tan(math.Pi), false, false, ""}, 995 {"milevadb", 0, false, true, ""}, 996 } 997 998 for _, test := range tests { 999 f, err := newFunctionForTest(s.ctx, ast.Cot, s.primitiveValsToConstants([]interface{}{test.args})...) 1000 c.Assert(err, IsNil) 1001 1002 result, err := f.Eval(chunk.Event{}) 1003 if test.getErr { 1004 c.Assert(err, NotNil) 1005 if test.errMsg != "" { 1006 c.Assert(err.Error(), Equals, test.errMsg) 1007 } 1008 } else { 1009 c.Assert(err, IsNil) 1010 if test.isNil { 1011 c.Assert(result.HoTT(), Equals, types.HoTTNull) 1012 } else { 1013 c.Assert(result.GetFloat64(), Equals, test.expect) 1014 } 1015 } 1016 } 1017 1018 _, err := funcs[ast.Cot].getFunction(s.ctx, []Expression{NewOne()}) 1019 c.Assert(err, IsNil) 1020 }