github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_arithmetic_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 "time" 18 19 . "github.com/whtcorpsinc/check" 20 "github.com/whtcorpsinc/BerolinaSQL/ast" 21 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 22 "github.com/whtcorpsinc/milevadb/types" 23 "github.com/whtcorpsinc/milevadb/soliton/chunk" 24 "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 25 "github.com/whtcorpsinc/fidelpb/go-fidelpb" 26 ) 27 28 func (s *testEvaluatorSuite) TestSetFlenDecimal4RealOrDecimal(c *C) { 29 ret := &types.FieldType{} 30 a := &types.FieldType{ 31 Decimal: 1, 32 Flen: 3, 33 } 34 b := &types.FieldType{ 35 Decimal: 0, 36 Flen: 2, 37 } 38 setFlenDecimal4RealOrDecimal(ret, a, b, true, false) 39 c.Assert(ret.Decimal, Equals, 1) 40 c.Assert(ret.Flen, Equals, 6) 41 42 b.Flen = 65 43 setFlenDecimal4RealOrDecimal(ret, a, b, true, false) 44 c.Assert(ret.Decimal, Equals, 1) 45 c.Assert(ret.Flen, Equals, allegrosql.MaxRealWidth) 46 setFlenDecimal4RealOrDecimal(ret, a, b, false, false) 47 c.Assert(ret.Decimal, Equals, 1) 48 c.Assert(ret.Flen, Equals, allegrosql.MaxDecimalWidth) 49 50 b.Flen = types.UnspecifiedLength 51 setFlenDecimal4RealOrDecimal(ret, a, b, true, false) 52 c.Assert(ret.Decimal, Equals, 1) 53 c.Assert(ret.Flen, Equals, types.UnspecifiedLength) 54 55 b.Decimal = types.UnspecifiedLength 56 setFlenDecimal4RealOrDecimal(ret, a, b, true, false) 57 c.Assert(ret.Decimal, Equals, types.UnspecifiedLength) 58 c.Assert(ret.Flen, Equals, types.UnspecifiedLength) 59 60 ret = &types.FieldType{} 61 a = &types.FieldType{ 62 Decimal: 1, 63 Flen: 3, 64 } 65 b = &types.FieldType{ 66 Decimal: 0, 67 Flen: 2, 68 } 69 setFlenDecimal4RealOrDecimal(ret, a, b, true, true) 70 c.Assert(ret.Decimal, Equals, 1) 71 c.Assert(ret.Flen, Equals, 8) 72 73 b.Flen = 65 74 setFlenDecimal4RealOrDecimal(ret, a, b, true, true) 75 c.Assert(ret.Decimal, Equals, 1) 76 c.Assert(ret.Flen, Equals, allegrosql.MaxRealWidth) 77 setFlenDecimal4RealOrDecimal(ret, a, b, false, true) 78 c.Assert(ret.Decimal, Equals, 1) 79 c.Assert(ret.Flen, Equals, allegrosql.MaxDecimalWidth) 80 81 b.Flen = types.UnspecifiedLength 82 setFlenDecimal4RealOrDecimal(ret, a, b, true, true) 83 c.Assert(ret.Decimal, Equals, 1) 84 c.Assert(ret.Flen, Equals, types.UnspecifiedLength) 85 86 b.Decimal = types.UnspecifiedLength 87 setFlenDecimal4RealOrDecimal(ret, a, b, true, true) 88 c.Assert(ret.Decimal, Equals, types.UnspecifiedLength) 89 c.Assert(ret.Flen, Equals, types.UnspecifiedLength) 90 } 91 92 func (s *testEvaluatorSuite) TestSetFlenDecimal4Int(c *C) { 93 ret := &types.FieldType{} 94 a := &types.FieldType{ 95 Decimal: 1, 96 Flen: 3, 97 } 98 b := &types.FieldType{ 99 Decimal: 0, 100 Flen: 2, 101 } 102 setFlenDecimal4Int(ret, a, b) 103 c.Assert(ret.Decimal, Equals, 0) 104 c.Assert(ret.Flen, Equals, allegrosql.MaxIntWidth) 105 106 b.Flen = allegrosql.MaxIntWidth + 1 107 setFlenDecimal4Int(ret, a, b) 108 c.Assert(ret.Decimal, Equals, 0) 109 c.Assert(ret.Flen, Equals, allegrosql.MaxIntWidth) 110 111 b.Flen = types.UnspecifiedLength 112 setFlenDecimal4Int(ret, a, b) 113 c.Assert(ret.Decimal, Equals, 0) 114 c.Assert(ret.Flen, Equals, allegrosql.MaxIntWidth) 115 } 116 117 func (s *testEvaluatorSuite) TestArithmeticPlus(c *C) { 118 // case: 1 119 args := []interface{}{int64(12), int64(1)} 120 121 bf, err := funcs[ast.Plus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 122 c.Assert(err, IsNil) 123 c.Assert(bf, NotNil) 124 intSig, ok := bf.(*builtinArithmeticPlusIntSig) 125 c.Assert(ok, IsTrue) 126 c.Assert(intSig, NotNil) 127 128 intResult, isNull, err := intSig.evalInt(chunk.Event{}) 129 c.Assert(err, IsNil) 130 c.Assert(isNull, IsFalse) 131 c.Assert(intResult, Equals, int64(13)) 132 133 // case 2 134 args = []interface{}{float64(1.01001), float64(-0.01)} 135 136 bf, err = funcs[ast.Plus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 137 c.Assert(err, IsNil) 138 c.Assert(bf, NotNil) 139 realSig, ok := bf.(*builtinArithmeticPlusRealSig) 140 c.Assert(ok, IsTrue) 141 c.Assert(realSig, NotNil) 142 143 realResult, isNull, err := realSig.evalReal(chunk.Event{}) 144 c.Assert(err, IsNil) 145 c.Assert(isNull, IsFalse) 146 c.Assert(realResult, Equals, float64(1.00001)) 147 148 // case 3 149 args = []interface{}{nil, float64(-0.11101)} 150 151 bf, err = funcs[ast.Plus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 152 c.Assert(err, IsNil) 153 c.Assert(bf, NotNil) 154 realSig, ok = bf.(*builtinArithmeticPlusRealSig) 155 c.Assert(ok, IsTrue) 156 c.Assert(realSig, NotNil) 157 158 realResult, isNull, err = realSig.evalReal(chunk.Event{}) 159 c.Assert(err, IsNil) 160 c.Assert(isNull, IsTrue) 161 c.Assert(realResult, Equals, float64(0)) 162 163 // case 4 164 args = []interface{}{nil, nil} 165 166 bf, err = funcs[ast.Plus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 167 c.Assert(err, IsNil) 168 c.Assert(bf, NotNil) 169 realSig, ok = bf.(*builtinArithmeticPlusRealSig) 170 c.Assert(ok, IsTrue) 171 c.Assert(realSig, NotNil) 172 173 realResult, isNull, err = realSig.evalReal(chunk.Event{}) 174 c.Assert(err, IsNil) 175 c.Assert(isNull, IsTrue) 176 c.Assert(realResult, Equals, float64(0)) 177 178 // case 5 179 hexStr, err := types.ParseHexStr("0x20000000000000") 180 c.Assert(err, IsNil) 181 args = []interface{}{hexStr, int64(1)} 182 183 bf, err = funcs[ast.Plus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 184 c.Assert(err, IsNil) 185 c.Assert(bf, NotNil) 186 intSig, ok = bf.(*builtinArithmeticPlusIntSig) 187 c.Assert(ok, IsTrue) 188 c.Assert(intSig, NotNil) 189 190 intResult, _, err = intSig.evalInt(chunk.Event{}) 191 c.Assert(err, IsNil) 192 c.Assert(intResult, Equals, int64(9007199254740993)) 193 } 194 195 func (s *testEvaluatorSuite) TestArithmeticMinus(c *C) { 196 // case: 1 197 args := []interface{}{int64(12), int64(1)} 198 199 bf, err := funcs[ast.Minus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 200 c.Assert(err, IsNil) 201 c.Assert(bf, NotNil) 202 intSig, ok := bf.(*builtinArithmeticMinusIntSig) 203 c.Assert(ok, IsTrue) 204 c.Assert(intSig, NotNil) 205 206 intResult, isNull, err := intSig.evalInt(chunk.Event{}) 207 c.Assert(err, IsNil) 208 c.Assert(isNull, IsFalse) 209 c.Assert(intResult, Equals, int64(11)) 210 211 // case 2 212 args = []interface{}{float64(1.01001), float64(-0.01)} 213 214 bf, err = funcs[ast.Minus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 215 c.Assert(err, IsNil) 216 c.Assert(bf, NotNil) 217 realSig, ok := bf.(*builtinArithmeticMinusRealSig) 218 c.Assert(ok, IsTrue) 219 c.Assert(realSig, NotNil) 220 221 realResult, isNull, err := realSig.evalReal(chunk.Event{}) 222 c.Assert(err, IsNil) 223 c.Assert(isNull, IsFalse) 224 c.Assert(realResult, Equals, float64(1.02001)) 225 226 // case 3 227 args = []interface{}{nil, float64(-0.11101)} 228 229 bf, err = funcs[ast.Minus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 230 c.Assert(err, IsNil) 231 c.Assert(bf, NotNil) 232 realSig, ok = bf.(*builtinArithmeticMinusRealSig) 233 c.Assert(ok, IsTrue) 234 c.Assert(realSig, NotNil) 235 236 realResult, isNull, err = realSig.evalReal(chunk.Event{}) 237 c.Assert(err, IsNil) 238 c.Assert(isNull, IsTrue) 239 c.Assert(realResult, Equals, float64(0)) 240 241 // case 4 242 args = []interface{}{float64(1.01), nil} 243 244 bf, err = funcs[ast.Minus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 245 c.Assert(err, IsNil) 246 c.Assert(bf, NotNil) 247 realSig, ok = bf.(*builtinArithmeticMinusRealSig) 248 c.Assert(ok, IsTrue) 249 c.Assert(realSig, NotNil) 250 251 realResult, isNull, err = realSig.evalReal(chunk.Event{}) 252 c.Assert(err, IsNil) 253 c.Assert(isNull, IsTrue) 254 c.Assert(realResult, Equals, float64(0)) 255 256 // case 5 257 args = []interface{}{nil, nil} 258 259 bf, err = funcs[ast.Minus].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 260 c.Assert(err, IsNil) 261 c.Assert(bf, NotNil) 262 realSig, ok = bf.(*builtinArithmeticMinusRealSig) 263 c.Assert(ok, IsTrue) 264 c.Assert(realSig, NotNil) 265 266 realResult, isNull, err = realSig.evalReal(chunk.Event{}) 267 c.Assert(err, IsNil) 268 c.Assert(isNull, IsTrue) 269 c.Assert(realResult, Equals, float64(0)) 270 } 271 272 func (s *testEvaluatorSuite) TestArithmeticMultiply(c *C) { 273 testCases := []struct { 274 args []interface{} 275 expect interface{} 276 err error 277 }{ 278 { 279 args: []interface{}{int64(11), int64(11)}, 280 expect: int64(121), 281 }, 282 { 283 args: []interface{}{uint64(11), uint64(11)}, 284 expect: int64(121), 285 }, 286 { 287 args: []interface{}{float64(11), float64(11)}, 288 expect: float64(121), 289 }, 290 { 291 args: []interface{}{nil, float64(-0.11101)}, 292 expect: nil, 293 }, 294 { 295 args: []interface{}{float64(1.01), nil}, 296 expect: nil, 297 }, 298 { 299 args: []interface{}{nil, nil}, 300 expect: nil, 301 }, 302 } 303 304 for _, tc := range testCases { 305 sig, err := funcs[ast.Mul].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...))) 306 c.Assert(err, IsNil) 307 c.Assert(sig, NotNil) 308 val, err := evalBuiltinFunc(sig, chunk.Event{}) 309 c.Assert(err, IsNil) 310 c.Assert(val, solitonutil.CausetEquals, types.NewCauset(tc.expect)) 311 } 312 } 313 314 func (s *testEvaluatorSuite) TestArithmeticDivide(c *C) { 315 testCases := []struct { 316 args []interface{} 317 expect interface{} 318 }{ 319 { 320 args: []interface{}{float64(11.1111111), float64(11.1)}, 321 expect: float64(1.001001), 322 }, 323 { 324 args: []interface{}{float64(11.1111111), float64(0)}, 325 expect: nil, 326 }, 327 { 328 args: []interface{}{int64(11), int64(11)}, 329 expect: float64(1), 330 }, 331 { 332 args: []interface{}{int64(11), int64(2)}, 333 expect: float64(5.5), 334 }, 335 { 336 args: []interface{}{int64(11), int64(0)}, 337 expect: nil, 338 }, 339 { 340 args: []interface{}{uint64(11), uint64(11)}, 341 expect: float64(1), 342 }, 343 { 344 args: []interface{}{uint64(11), uint64(2)}, 345 expect: float64(5.5), 346 }, 347 { 348 args: []interface{}{uint64(11), uint64(0)}, 349 expect: nil, 350 }, 351 { 352 args: []interface{}{nil, float64(-0.11101)}, 353 expect: nil, 354 }, 355 { 356 args: []interface{}{float64(1.01), nil}, 357 expect: nil, 358 }, 359 { 360 args: []interface{}{nil, nil}, 361 expect: nil, 362 }, 363 } 364 365 for _, tc := range testCases { 366 sig, err := funcs[ast.Div].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...))) 367 c.Assert(err, IsNil) 368 c.Assert(sig, NotNil) 369 switch sig.(type) { 370 case *builtinArithmeticIntDivideIntSig: 371 c.Assert(sig.PbCode(), Equals, fidelpb.ScalarFuncSig_IntDivideInt) 372 case *builtinArithmeticIntDivideDecimalSig: 373 c.Assert(sig.PbCode(), Equals, fidelpb.ScalarFuncSig_IntDivideDecimal) 374 } 375 val, err := evalBuiltinFunc(sig, chunk.Event{}) 376 c.Assert(err, IsNil) 377 c.Assert(val, solitonutil.CausetEquals, types.NewCauset(tc.expect)) 378 } 379 } 380 381 func (s *testEvaluatorSuite) TestArithmeticIntDivide(c *C) { 382 testCases := []struct { 383 args []interface{} 384 expect []interface{} 385 }{ 386 { 387 args: []interface{}{int64(13), int64(11)}, 388 expect: []interface{}{int64(1), nil}, 389 }, 390 { 391 args: []interface{}{int64(-13), int64(11)}, 392 expect: []interface{}{int64(-1), nil}, 393 }, 394 { 395 args: []interface{}{int64(13), int64(-11)}, 396 expect: []interface{}{int64(-1), nil}, 397 }, 398 { 399 args: []interface{}{int64(-13), int64(-11)}, 400 expect: []interface{}{int64(1), nil}, 401 }, 402 { 403 args: []interface{}{int64(33), int64(11)}, 404 expect: []interface{}{int64(3), nil}, 405 }, 406 { 407 args: []interface{}{int64(-33), int64(11)}, 408 expect: []interface{}{int64(-3), nil}, 409 }, 410 { 411 args: []interface{}{int64(33), int64(-11)}, 412 expect: []interface{}{int64(-3), nil}, 413 }, 414 { 415 args: []interface{}{int64(-33), int64(-11)}, 416 expect: []interface{}{int64(3), nil}, 417 }, 418 { 419 args: []interface{}{int64(11), int64(0)}, 420 expect: []interface{}{nil, nil}, 421 }, 422 { 423 args: []interface{}{int64(-11), int64(0)}, 424 expect: []interface{}{nil, nil}, 425 }, 426 { 427 args: []interface{}{float64(11.01), float64(1.1)}, 428 expect: []interface{}{int64(10), nil}, 429 }, 430 { 431 args: []interface{}{float64(-11.01), float64(1.1)}, 432 expect: []interface{}{int64(-10), nil}, 433 }, 434 { 435 args: []interface{}{float64(11.01), float64(-1.1)}, 436 expect: []interface{}{int64(-10), nil}, 437 }, 438 { 439 args: []interface{}{float64(-11.01), float64(-1.1)}, 440 expect: []interface{}{int64(10), nil}, 441 }, 442 { 443 args: []interface{}{nil, float64(-0.11101)}, 444 expect: []interface{}{nil, nil}, 445 }, 446 { 447 args: []interface{}{float64(1.01), nil}, 448 expect: []interface{}{nil, nil}, 449 }, 450 { 451 args: []interface{}{nil, int64(-1001)}, 452 expect: []interface{}{nil, nil}, 453 }, 454 { 455 args: []interface{}{int64(101), nil}, 456 expect: []interface{}{nil, nil}, 457 }, 458 { 459 args: []interface{}{nil, nil}, 460 expect: []interface{}{nil, nil}, 461 }, 462 { 463 args: []interface{}{float64(123456789100000.0), float64(-0.00001)}, 464 expect: []interface{}{nil, "*BIGINT value is out of range in '\\(123456789100000 DIV -0.00001\\)'"}, 465 }, 466 { 467 args: []interface{}{int64(-9223372036854775808), float64(-1)}, 468 expect: []interface{}{nil, "*BIGINT value is out of range in '\\(-9223372036854775808 DIV -1\\)'"}, 469 }, 470 { 471 args: []interface{}{uint64(1), float64(-2)}, 472 expect: []interface{}{0, nil}, 473 }, 474 { 475 args: []interface{}{uint64(1), float64(-1)}, 476 expect: []interface{}{nil, "*BIGINT UNSIGNED value is out of range in '\\(1 DIV -1\\)'"}, 477 }, 478 } 479 480 for _, tc := range testCases { 481 sig, err := funcs[ast.IntDiv].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...))) 482 c.Assert(err, IsNil) 483 c.Assert(sig, NotNil) 484 val, err := evalBuiltinFunc(sig, chunk.Event{}) 485 if tc.expect[1] == nil { 486 c.Assert(err, IsNil) 487 c.Assert(val, solitonutil.CausetEquals, types.NewCauset(tc.expect[0])) 488 } else { 489 c.Assert(err, ErrorMatches, tc.expect[1]) 490 } 491 } 492 } 493 494 func (s *testEvaluatorSuite) TestArithmeticMod(c *C) { 495 testCases := []struct { 496 args []interface{} 497 expect interface{} 498 }{ 499 { 500 args: []interface{}{int64(13), int64(11)}, 501 expect: int64(2), 502 }, 503 { 504 args: []interface{}{int64(-13), int64(11)}, 505 expect: int64(-2), 506 }, 507 { 508 args: []interface{}{int64(13), int64(-11)}, 509 expect: int64(2), 510 }, 511 { 512 args: []interface{}{int64(-13), int64(-11)}, 513 expect: int64(-2), 514 }, 515 { 516 args: []interface{}{int64(33), int64(11)}, 517 expect: int64(0), 518 }, 519 { 520 args: []interface{}{int64(-33), int64(11)}, 521 expect: int64(0), 522 }, 523 { 524 args: []interface{}{int64(33), int64(-11)}, 525 expect: int64(0), 526 }, 527 { 528 args: []interface{}{int64(-33), int64(-11)}, 529 expect: int64(0), 530 }, 531 { 532 args: []interface{}{int64(11), int64(0)}, 533 expect: nil, 534 }, 535 { 536 args: []interface{}{int64(-11), int64(0)}, 537 expect: nil, 538 }, 539 { 540 args: []interface{}{int64(1), float64(1.1)}, 541 expect: float64(1), 542 }, 543 { 544 args: []interface{}{int64(-1), float64(1.1)}, 545 expect: float64(-1), 546 }, 547 { 548 args: []interface{}{int64(1), float64(-1.1)}, 549 expect: float64(1), 550 }, 551 { 552 args: []interface{}{int64(-1), float64(-1.1)}, 553 expect: float64(-1), 554 }, 555 { 556 args: []interface{}{nil, float64(-0.11101)}, 557 expect: nil, 558 }, 559 { 560 args: []interface{}{float64(1.01), nil}, 561 expect: nil, 562 }, 563 { 564 args: []interface{}{nil, int64(-1001)}, 565 expect: nil, 566 }, 567 { 568 args: []interface{}{int64(101), nil}, 569 expect: nil, 570 }, 571 { 572 args: []interface{}{nil, nil}, 573 expect: nil, 574 }, 575 { 576 args: []interface{}{"1231", 12}, 577 expect: 7, 578 }, 579 { 580 args: []interface{}{"1231", "12"}, 581 expect: float64(7), 582 }, 583 { 584 args: []interface{}{types.Duration{Duration: 45296 * time.Second}, 122}, 585 expect: 114, 586 }, 587 { 588 args: []interface{}{types.Set{Value: 7, Name: "abc"}, "12"}, 589 expect: float64(7), 590 }, 591 } 592 593 for _, tc := range testCases { 594 sig, err := funcs[ast.Mod].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...))) 595 c.Assert(err, IsNil) 596 c.Assert(sig, NotNil) 597 val, err := evalBuiltinFunc(sig, chunk.Event{}) 598 switch sig.(type) { 599 case *builtinArithmeticModRealSig: 600 c.Assert(sig.PbCode(), Equals, fidelpb.ScalarFuncSig_ModReal) 601 case *builtinArithmeticModIntSig: 602 c.Assert(sig.PbCode(), Equals, fidelpb.ScalarFuncSig_ModInt) 603 case *builtinArithmeticModDecimalSig: 604 c.Assert(sig.PbCode(), Equals, fidelpb.ScalarFuncSig_ModDecimal) 605 } 606 c.Assert(err, IsNil) 607 c.Assert(val, solitonutil.CausetEquals, types.NewCauset(tc.expect)) 608 } 609 }