github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_math.go (about) 1 // Copyright 2020 The ql Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSES/QL-LICENSE file. 4 5 // Copyright 2020 WHTCORPS INC, Inc. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package memex 19 20 import ( 21 "fmt" 22 "hash/crc32" 23 "math" 24 "strconv" 25 "strings" 26 "sync" 27 28 "github.com/cznic/mathutil" 29 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 30 "github.com/whtcorpsinc/milevadb/stochastikctx" 31 "github.com/whtcorpsinc/milevadb/types" 32 "github.com/whtcorpsinc/milevadb/soliton/chunk" 33 "github.com/whtcorpsinc/fidelpb/go-fidelpb" 34 ) 35 36 var ( 37 _ functionClass = &absFunctionClass{} 38 _ functionClass = &roundFunctionClass{} 39 _ functionClass = &ceilFunctionClass{} 40 _ functionClass = &floorFunctionClass{} 41 _ functionClass = &logFunctionClass{} 42 _ functionClass = &log2FunctionClass{} 43 _ functionClass = &log10FunctionClass{} 44 _ functionClass = &randFunctionClass{} 45 _ functionClass = &powFunctionClass{} 46 _ functionClass = &convFunctionClass{} 47 _ functionClass = &crc32FunctionClass{} 48 _ functionClass = &signFunctionClass{} 49 _ functionClass = &sqrtFunctionClass{} 50 _ functionClass = &acosFunctionClass{} 51 _ functionClass = &asinFunctionClass{} 52 _ functionClass = &atanFunctionClass{} 53 _ functionClass = &cosFunctionClass{} 54 _ functionClass = &cotFunctionClass{} 55 _ functionClass = °reesFunctionClass{} 56 _ functionClass = &expFunctionClass{} 57 _ functionClass = &piFunctionClass{} 58 _ functionClass = &radiansFunctionClass{} 59 _ functionClass = &sinFunctionClass{} 60 _ functionClass = &tanFunctionClass{} 61 _ functionClass = &truncateFunctionClass{} 62 ) 63 64 var ( 65 _ builtinFunc = &builtinAbsRealSig{} 66 _ builtinFunc = &builtinAbsIntSig{} 67 _ builtinFunc = &builtinAbsUIntSig{} 68 _ builtinFunc = &builtinAbsDecSig{} 69 _ builtinFunc = &builtinRoundRealSig{} 70 _ builtinFunc = &builtinRoundIntSig{} 71 _ builtinFunc = &builtinRoundDecSig{} 72 _ builtinFunc = &builtinRoundWithFracRealSig{} 73 _ builtinFunc = &builtinRoundWithFracIntSig{} 74 _ builtinFunc = &builtinRoundWithFracDecSig{} 75 _ builtinFunc = &builtinCeilRealSig{} 76 _ builtinFunc = &builtinCeilIntToDecSig{} 77 _ builtinFunc = &builtinCeilIntToIntSig{} 78 _ builtinFunc = &builtinCeilDecToIntSig{} 79 _ builtinFunc = &builtinCeilDecToDecSig{} 80 _ builtinFunc = &builtinFloorRealSig{} 81 _ builtinFunc = &builtinFloorIntToDecSig{} 82 _ builtinFunc = &builtinFloorIntToIntSig{} 83 _ builtinFunc = &builtinFloorDecToIntSig{} 84 _ builtinFunc = &builtinFloorDecToDecSig{} 85 _ builtinFunc = &builtinLog1ArgSig{} 86 _ builtinFunc = &builtinLog2ArgsSig{} 87 _ builtinFunc = &builtinLog2Sig{} 88 _ builtinFunc = &builtinLog10Sig{} 89 _ builtinFunc = &builtinRandSig{} 90 _ builtinFunc = &builtinRandWithSeedFirstGenSig{} 91 _ builtinFunc = &builtinPowSig{} 92 _ builtinFunc = &builtinConvSig{} 93 _ builtinFunc = &builtinCRC32Sig{} 94 _ builtinFunc = &builtinSignSig{} 95 _ builtinFunc = &builtinSqrtSig{} 96 _ builtinFunc = &builtinAcosSig{} 97 _ builtinFunc = &builtinAsinSig{} 98 _ builtinFunc = &builtinAtan1ArgSig{} 99 _ builtinFunc = &builtinAtan2ArgsSig{} 100 _ builtinFunc = &builtinCosSig{} 101 _ builtinFunc = &builtinCotSig{} 102 _ builtinFunc = &builtinDegreesSig{} 103 _ builtinFunc = &builtinExpSig{} 104 _ builtinFunc = &builtinPISig{} 105 _ builtinFunc = &builtinRadiansSig{} 106 _ builtinFunc = &builtinSinSig{} 107 _ builtinFunc = &builtinTanSig{} 108 _ builtinFunc = &builtinTruncateIntSig{} 109 _ builtinFunc = &builtinTruncateRealSig{} 110 _ builtinFunc = &builtinTruncateDecimalSig{} 111 _ builtinFunc = &builtinTruncateUintSig{} 112 ) 113 114 type absFunctionClass struct { 115 baseFunctionClass 116 } 117 118 func (c *absFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 119 if err := c.verifyArgs(args); err != nil { 120 return nil, c.verifyArgs(args) 121 } 122 123 argFieldTp := args[0].GetType() 124 argTp := argFieldTp.EvalType() 125 if argTp != types.ETInt && argTp != types.ETDecimal { 126 argTp = types.ETReal 127 } 128 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, argTp, argTp) 129 if err != nil { 130 return nil, err 131 } 132 if allegrosql.HasUnsignedFlag(argFieldTp.Flag) { 133 bf.tp.Flag |= allegrosql.UnsignedFlag 134 } 135 if argTp == types.ETReal { 136 bf.tp.Flen, bf.tp.Decimal = allegrosql.GetDefaultFieldLengthAndDecimal(allegrosql.TypeDouble) 137 } else { 138 bf.tp.Flen = argFieldTp.Flen 139 bf.tp.Decimal = argFieldTp.Decimal 140 } 141 var sig builtinFunc 142 switch argTp { 143 case types.ETInt: 144 if allegrosql.HasUnsignedFlag(argFieldTp.Flag) { 145 sig = &builtinAbsUIntSig{bf} 146 sig.setPbCode(fidelpb.ScalarFuncSig_AbsUInt) 147 } else { 148 sig = &builtinAbsIntSig{bf} 149 sig.setPbCode(fidelpb.ScalarFuncSig_AbsInt) 150 } 151 case types.ETDecimal: 152 sig = &builtinAbsDecSig{bf} 153 sig.setPbCode(fidelpb.ScalarFuncSig_AbsDecimal) 154 case types.ETReal: 155 sig = &builtinAbsRealSig{bf} 156 sig.setPbCode(fidelpb.ScalarFuncSig_AbsReal) 157 default: 158 panic("unexpected argTp") 159 } 160 return sig, nil 161 } 162 163 type builtinAbsRealSig struct { 164 baseBuiltinFunc 165 } 166 167 func (b *builtinAbsRealSig) Clone() builtinFunc { 168 newSig := &builtinAbsRealSig{} 169 newSig.cloneFrom(&b.baseBuiltinFunc) 170 return newSig 171 } 172 173 // evalReal evals ABS(value). 174 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_abs 175 func (b *builtinAbsRealSig) evalReal(event chunk.Event) (float64, bool, error) { 176 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 177 if isNull || err != nil { 178 return 0, isNull, err 179 } 180 return math.Abs(val), false, nil 181 } 182 183 type builtinAbsIntSig struct { 184 baseBuiltinFunc 185 } 186 187 func (b *builtinAbsIntSig) Clone() builtinFunc { 188 newSig := &builtinAbsIntSig{} 189 newSig.cloneFrom(&b.baseBuiltinFunc) 190 return newSig 191 } 192 193 // evalInt evals ABS(value). 194 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_abs 195 func (b *builtinAbsIntSig) evalInt(event chunk.Event) (int64, bool, error) { 196 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 197 if isNull || err != nil { 198 return 0, isNull, err 199 } 200 if val >= 0 { 201 return val, false, nil 202 } 203 if val == math.MinInt64 { 204 return 0, false, types.ErrOverflow.GenWithStackByArgs("BIGINT", fmt.Sprintf("abs(%d)", val)) 205 } 206 return -val, false, nil 207 } 208 209 type builtinAbsUIntSig struct { 210 baseBuiltinFunc 211 } 212 213 func (b *builtinAbsUIntSig) Clone() builtinFunc { 214 newSig := &builtinAbsUIntSig{} 215 newSig.cloneFrom(&b.baseBuiltinFunc) 216 return newSig 217 } 218 219 // evalInt evals ABS(value). 220 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_abs 221 func (b *builtinAbsUIntSig) evalInt(event chunk.Event) (int64, bool, error) { 222 return b.args[0].EvalInt(b.ctx, event) 223 } 224 225 type builtinAbsDecSig struct { 226 baseBuiltinFunc 227 } 228 229 func (b *builtinAbsDecSig) Clone() builtinFunc { 230 newSig := &builtinAbsDecSig{} 231 newSig.cloneFrom(&b.baseBuiltinFunc) 232 return newSig 233 } 234 235 // evalDecimal evals ABS(value). 236 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_abs 237 func (b *builtinAbsDecSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 238 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 239 if isNull || err != nil { 240 return nil, isNull, err 241 } 242 to := new(types.MyDecimal) 243 if !val.IsNegative() { 244 *to = *val 245 } else { 246 if err = types.DecimalSub(new(types.MyDecimal), val, to); err != nil { 247 return nil, true, err 248 } 249 } 250 return to, false, nil 251 } 252 253 func (c *roundFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 254 if err := c.verifyArgs(args); err != nil { 255 return nil, c.verifyArgs(args) 256 } 257 argTp := args[0].GetType().EvalType() 258 if argTp != types.ETInt && argTp != types.ETDecimal { 259 argTp = types.ETReal 260 } 261 argTps := []types.EvalType{argTp} 262 if len(args) > 1 { 263 argTps = append(argTps, types.ETInt) 264 } 265 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, argTp, argTps...) 266 if err != nil { 267 return nil, err 268 } 269 argFieldTp := args[0].GetType() 270 if allegrosql.HasUnsignedFlag(argFieldTp.Flag) { 271 bf.tp.Flag |= allegrosql.UnsignedFlag 272 } 273 274 bf.tp.Flen = argFieldTp.Flen 275 bf.tp.Decimal = calculateDecimal4RoundAndTruncate(ctx, args, argTp) 276 277 var sig builtinFunc 278 if len(args) > 1 { 279 switch argTp { 280 case types.ETInt: 281 sig = &builtinRoundWithFracIntSig{bf} 282 sig.setPbCode(fidelpb.ScalarFuncSig_RoundWithFracInt) 283 case types.ETDecimal: 284 sig = &builtinRoundWithFracDecSig{bf} 285 sig.setPbCode(fidelpb.ScalarFuncSig_RoundWithFracDec) 286 case types.ETReal: 287 sig = &builtinRoundWithFracRealSig{bf} 288 sig.setPbCode(fidelpb.ScalarFuncSig_RoundWithFracReal) 289 default: 290 panic("unexpected argTp") 291 } 292 } else { 293 switch argTp { 294 case types.ETInt: 295 sig = &builtinRoundIntSig{bf} 296 sig.setPbCode(fidelpb.ScalarFuncSig_RoundInt) 297 case types.ETDecimal: 298 sig = &builtinRoundDecSig{bf} 299 sig.setPbCode(fidelpb.ScalarFuncSig_RoundDec) 300 case types.ETReal: 301 sig = &builtinRoundRealSig{bf} 302 sig.setPbCode(fidelpb.ScalarFuncSig_RoundReal) 303 default: 304 panic("unexpected argTp") 305 } 306 } 307 return sig, nil 308 } 309 310 // calculateDecimal4RoundAndTruncate calculates tp.decimals of round/truncate func. 311 func calculateDecimal4RoundAndTruncate(ctx stochastikctx.Context, args []Expression, retType types.EvalType) int { 312 if retType == types.ETInt || len(args) <= 1 { 313 return 0 314 } 315 secondConst, secondIsConst := args[1].(*Constant) 316 if !secondIsConst { 317 return args[0].GetType().Decimal 318 } 319 argDec, isNull, err := secondConst.EvalInt(ctx, chunk.Event{}) 320 if err != nil || isNull || argDec < 0 { 321 return 0 322 } 323 if argDec > allegrosql.MaxDecimalScale { 324 return allegrosql.MaxDecimalScale 325 } 326 return int(argDec) 327 } 328 329 type builtinRoundRealSig struct { 330 baseBuiltinFunc 331 } 332 333 func (b *builtinRoundRealSig) Clone() builtinFunc { 334 newSig := &builtinRoundRealSig{} 335 newSig.cloneFrom(&b.baseBuiltinFunc) 336 return newSig 337 } 338 339 // evalReal evals ROUND(value). 340 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_round 341 func (b *builtinRoundRealSig) evalReal(event chunk.Event) (float64, bool, error) { 342 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 343 if isNull || err != nil { 344 return 0, isNull, err 345 } 346 return types.Round(val, 0), false, nil 347 } 348 349 type builtinRoundIntSig struct { 350 baseBuiltinFunc 351 } 352 353 func (b *builtinRoundIntSig) Clone() builtinFunc { 354 newSig := &builtinRoundIntSig{} 355 newSig.cloneFrom(&b.baseBuiltinFunc) 356 return newSig 357 } 358 359 // evalInt evals ROUND(value). 360 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_round 361 func (b *builtinRoundIntSig) evalInt(event chunk.Event) (int64, bool, error) { 362 return b.args[0].EvalInt(b.ctx, event) 363 } 364 365 type builtinRoundDecSig struct { 366 baseBuiltinFunc 367 } 368 369 func (b *builtinRoundDecSig) Clone() builtinFunc { 370 newSig := &builtinRoundDecSig{} 371 newSig.cloneFrom(&b.baseBuiltinFunc) 372 return newSig 373 } 374 375 // evalDecimal evals ROUND(value). 376 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_round 377 func (b *builtinRoundDecSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 378 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 379 if isNull || err != nil { 380 return nil, isNull, err 381 } 382 to := new(types.MyDecimal) 383 if err = val.Round(to, 0, types.ModeHalfEven); err != nil { 384 return nil, true, err 385 } 386 return to, false, nil 387 } 388 389 type builtinRoundWithFracRealSig struct { 390 baseBuiltinFunc 391 } 392 393 func (b *builtinRoundWithFracRealSig) Clone() builtinFunc { 394 newSig := &builtinRoundWithFracRealSig{} 395 newSig.cloneFrom(&b.baseBuiltinFunc) 396 return newSig 397 } 398 399 // evalReal evals ROUND(value, frac). 400 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_round 401 func (b *builtinRoundWithFracRealSig) evalReal(event chunk.Event) (float64, bool, error) { 402 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 403 if isNull || err != nil { 404 return 0, isNull, err 405 } 406 frac, isNull, err := b.args[1].EvalInt(b.ctx, event) 407 if isNull || err != nil { 408 return 0, isNull, err 409 } 410 return types.Round(val, int(frac)), false, nil 411 } 412 413 type builtinRoundWithFracIntSig struct { 414 baseBuiltinFunc 415 } 416 417 func (b *builtinRoundWithFracIntSig) Clone() builtinFunc { 418 newSig := &builtinRoundWithFracIntSig{} 419 newSig.cloneFrom(&b.baseBuiltinFunc) 420 return newSig 421 } 422 423 // evalInt evals ROUND(value, frac). 424 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_round 425 func (b *builtinRoundWithFracIntSig) evalInt(event chunk.Event) (int64, bool, error) { 426 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 427 if isNull || err != nil { 428 return 0, isNull, err 429 } 430 frac, isNull, err := b.args[1].EvalInt(b.ctx, event) 431 if isNull || err != nil { 432 return 0, isNull, err 433 } 434 return int64(types.Round(float64(val), int(frac))), false, nil 435 } 436 437 type builtinRoundWithFracDecSig struct { 438 baseBuiltinFunc 439 } 440 441 func (b *builtinRoundWithFracDecSig) Clone() builtinFunc { 442 newSig := &builtinRoundWithFracDecSig{} 443 newSig.cloneFrom(&b.baseBuiltinFunc) 444 return newSig 445 } 446 447 // evalDecimal evals ROUND(value, frac). 448 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_round 449 func (b *builtinRoundWithFracDecSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 450 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 451 if isNull || err != nil { 452 return nil, isNull, err 453 } 454 frac, isNull, err := b.args[1].EvalInt(b.ctx, event) 455 if isNull || err != nil { 456 return nil, isNull, err 457 } 458 to := new(types.MyDecimal) 459 if err = val.Round(to, mathutil.Min(int(frac), b.tp.Decimal), types.ModeHalfEven); err != nil { 460 return nil, true, err 461 } 462 return to, false, nil 463 } 464 465 type ceilFunctionClass struct { 466 baseFunctionClass 467 } 468 469 func (c *ceilFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 470 if err = c.verifyArgs(args); err != nil { 471 return nil, err 472 } 473 474 retTp, argTp := getEvalTp4FloorAndCeil(args[0]) 475 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, retTp, argTp) 476 if err != nil { 477 return nil, err 478 } 479 setFlag4FloorAndCeil(bf.tp, args[0]) 480 argFieldTp := args[0].GetType() 481 bf.tp.Flen, bf.tp.Decimal = argFieldTp.Flen, 0 482 483 switch argTp { 484 case types.ETInt: 485 if retTp == types.ETInt { 486 sig = &builtinCeilIntToIntSig{bf} 487 sig.setPbCode(fidelpb.ScalarFuncSig_CeilIntToInt) 488 } else { 489 sig = &builtinCeilIntToDecSig{bf} 490 sig.setPbCode(fidelpb.ScalarFuncSig_CeilIntToDec) 491 } 492 case types.ETDecimal: 493 if retTp == types.ETInt { 494 sig = &builtinCeilDecToIntSig{bf} 495 sig.setPbCode(fidelpb.ScalarFuncSig_CeilDecToInt) 496 } else { 497 sig = &builtinCeilDecToDecSig{bf} 498 sig.setPbCode(fidelpb.ScalarFuncSig_CeilDecToDec) 499 } 500 default: 501 sig = &builtinCeilRealSig{bf} 502 sig.setPbCode(fidelpb.ScalarFuncSig_CeilReal) 503 } 504 return sig, nil 505 } 506 507 type builtinCeilRealSig struct { 508 baseBuiltinFunc 509 } 510 511 func (b *builtinCeilRealSig) Clone() builtinFunc { 512 newSig := &builtinCeilRealSig{} 513 newSig.cloneFrom(&b.baseBuiltinFunc) 514 return newSig 515 } 516 517 // evalReal evals a builtinCeilRealSig. 518 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_ceil 519 func (b *builtinCeilRealSig) evalReal(event chunk.Event) (float64, bool, error) { 520 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 521 if isNull || err != nil { 522 return 0, isNull, err 523 } 524 return math.Ceil(val), false, nil 525 } 526 527 type builtinCeilIntToIntSig struct { 528 baseBuiltinFunc 529 } 530 531 func (b *builtinCeilIntToIntSig) Clone() builtinFunc { 532 newSig := &builtinCeilIntToIntSig{} 533 newSig.cloneFrom(&b.baseBuiltinFunc) 534 return newSig 535 } 536 537 // evalInt evals a builtinCeilIntToIntSig. 538 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_ceil 539 func (b *builtinCeilIntToIntSig) evalInt(event chunk.Event) (int64, bool, error) { 540 return b.args[0].EvalInt(b.ctx, event) 541 } 542 543 type builtinCeilIntToDecSig struct { 544 baseBuiltinFunc 545 } 546 547 func (b *builtinCeilIntToDecSig) Clone() builtinFunc { 548 newSig := &builtinCeilIntToDecSig{} 549 newSig.cloneFrom(&b.baseBuiltinFunc) 550 return newSig 551 } 552 553 // evalDecimal evals a builtinCeilIntToDecSig. 554 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_Ceil 555 func (b *builtinCeilIntToDecSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 556 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 557 if isNull || err != nil { 558 return nil, true, err 559 } 560 561 if allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag) || val >= 0 { 562 return types.NewDecFromUint(uint64(val)), false, nil 563 } 564 return types.NewDecFromInt(val), false, nil 565 } 566 567 type builtinCeilDecToIntSig struct { 568 baseBuiltinFunc 569 } 570 571 func (b *builtinCeilDecToIntSig) Clone() builtinFunc { 572 newSig := &builtinCeilDecToIntSig{} 573 newSig.cloneFrom(&b.baseBuiltinFunc) 574 return newSig 575 } 576 577 // evalInt evals a builtinCeilDecToIntSig. 578 // Ceil receives 579 func (b *builtinCeilDecToIntSig) evalInt(event chunk.Event) (int64, bool, error) { 580 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 581 if isNull || err != nil { 582 return 0, isNull, err 583 } 584 // err here will only be ErrOverFlow(will never happen) or ErrTruncate(can be ignored). 585 res, err := val.ToInt() 586 if err == types.ErrTruncated { 587 err = nil 588 if !val.IsNegative() { 589 res = res + 1 590 } 591 } 592 return res, false, err 593 } 594 595 type builtinCeilDecToDecSig struct { 596 baseBuiltinFunc 597 } 598 599 func (b *builtinCeilDecToDecSig) Clone() builtinFunc { 600 newSig := &builtinCeilDecToDecSig{} 601 newSig.cloneFrom(&b.baseBuiltinFunc) 602 return newSig 603 } 604 605 // evalDecimal evals a builtinCeilDecToDecSig. 606 func (b *builtinCeilDecToDecSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 607 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 608 if isNull || err != nil { 609 return nil, isNull, err 610 } 611 612 res := new(types.MyDecimal) 613 if val.IsNegative() { 614 err = val.Round(res, 0, types.ModeTruncate) 615 return res, err != nil, err 616 } 617 618 err = val.Round(res, 0, types.ModeTruncate) 619 if err != nil || res.Compare(val) == 0 { 620 return res, err != nil, err 621 } 622 623 err = types.DecimalAdd(res, types.NewDecFromInt(1), res) 624 return res, err != nil, err 625 } 626 627 type floorFunctionClass struct { 628 baseFunctionClass 629 } 630 631 // getEvalTp4FloorAndCeil gets the types.EvalType of FLOOR and CEIL. 632 func getEvalTp4FloorAndCeil(arg Expression) (retTp, argTp types.EvalType) { 633 fieldTp := arg.GetType() 634 retTp, argTp = types.ETInt, fieldTp.EvalType() 635 switch argTp { 636 case types.ETInt: 637 if fieldTp.Tp == allegrosql.TypeLonglong { 638 retTp = types.ETDecimal 639 } 640 case types.ETDecimal: 641 if fieldTp.Flen-fieldTp.Decimal > allegrosql.MaxIntWidth-2 { // len(math.MaxInt64) - 1 642 retTp = types.ETDecimal 643 } 644 default: 645 retTp, argTp = types.ETReal, types.ETReal 646 } 647 return retTp, argTp 648 } 649 650 // setFlag4FloorAndCeil sets return flag of FLOOR and CEIL. 651 func setFlag4FloorAndCeil(tp *types.FieldType, arg Expression) { 652 fieldTp := arg.GetType() 653 if (fieldTp.Tp == allegrosql.TypeLong || fieldTp.Tp == allegrosql.TypeNewDecimal) && allegrosql.HasUnsignedFlag(fieldTp.Flag) { 654 tp.Flag |= allegrosql.UnsignedFlag 655 } 656 // TODO: when argument type is timestamp, add not null flag. 657 } 658 659 func (c *floorFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 660 if err = c.verifyArgs(args); err != nil { 661 return nil, err 662 } 663 664 retTp, argTp := getEvalTp4FloorAndCeil(args[0]) 665 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, retTp, argTp) 666 if err != nil { 667 return nil, err 668 } 669 setFlag4FloorAndCeil(bf.tp, args[0]) 670 bf.tp.Flen, bf.tp.Decimal = args[0].GetType().Flen, 0 671 switch argTp { 672 case types.ETInt: 673 if retTp == types.ETInt { 674 sig = &builtinFloorIntToIntSig{bf} 675 sig.setPbCode(fidelpb.ScalarFuncSig_FloorIntToInt) 676 } else { 677 sig = &builtinFloorIntToDecSig{bf} 678 sig.setPbCode(fidelpb.ScalarFuncSig_FloorIntToDec) 679 } 680 case types.ETDecimal: 681 if retTp == types.ETInt { 682 sig = &builtinFloorDecToIntSig{bf} 683 sig.setPbCode(fidelpb.ScalarFuncSig_FloorDecToInt) 684 } else { 685 sig = &builtinFloorDecToDecSig{bf} 686 sig.setPbCode(fidelpb.ScalarFuncSig_FloorDecToDec) 687 } 688 default: 689 sig = &builtinFloorRealSig{bf} 690 sig.setPbCode(fidelpb.ScalarFuncSig_FloorReal) 691 } 692 return sig, nil 693 } 694 695 type builtinFloorRealSig struct { 696 baseBuiltinFunc 697 } 698 699 func (b *builtinFloorRealSig) Clone() builtinFunc { 700 newSig := &builtinFloorRealSig{} 701 newSig.cloneFrom(&b.baseBuiltinFunc) 702 return newSig 703 } 704 705 // evalReal evals a builtinFloorRealSig. 706 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_floor 707 func (b *builtinFloorRealSig) evalReal(event chunk.Event) (float64, bool, error) { 708 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 709 if isNull || err != nil { 710 return 0, isNull, err 711 } 712 return math.Floor(val), false, nil 713 } 714 715 type builtinFloorIntToIntSig struct { 716 baseBuiltinFunc 717 } 718 719 func (b *builtinFloorIntToIntSig) Clone() builtinFunc { 720 newSig := &builtinFloorIntToIntSig{} 721 newSig.cloneFrom(&b.baseBuiltinFunc) 722 return newSig 723 } 724 725 // evalInt evals a builtinFloorIntToIntSig. 726 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_floor 727 func (b *builtinFloorIntToIntSig) evalInt(event chunk.Event) (int64, bool, error) { 728 return b.args[0].EvalInt(b.ctx, event) 729 } 730 731 type builtinFloorIntToDecSig struct { 732 baseBuiltinFunc 733 } 734 735 func (b *builtinFloorIntToDecSig) Clone() builtinFunc { 736 newSig := &builtinFloorIntToDecSig{} 737 newSig.cloneFrom(&b.baseBuiltinFunc) 738 return newSig 739 } 740 741 // evalDecimal evals a builtinFloorIntToDecSig. 742 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_floor 743 func (b *builtinFloorIntToDecSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 744 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 745 if isNull || err != nil { 746 return nil, true, err 747 } 748 749 if allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag) || val >= 0 { 750 return types.NewDecFromUint(uint64(val)), false, nil 751 } 752 return types.NewDecFromInt(val), false, nil 753 } 754 755 type builtinFloorDecToIntSig struct { 756 baseBuiltinFunc 757 } 758 759 func (b *builtinFloorDecToIntSig) Clone() builtinFunc { 760 newSig := &builtinFloorDecToIntSig{} 761 newSig.cloneFrom(&b.baseBuiltinFunc) 762 return newSig 763 } 764 765 // evalInt evals a builtinFloorDecToIntSig. 766 // floor receives 767 func (b *builtinFloorDecToIntSig) evalInt(event chunk.Event) (int64, bool, error) { 768 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 769 if isNull || err != nil { 770 return 0, isNull, err 771 } 772 // err here will only be ErrOverFlow(will never happen) or ErrTruncate(can be ignored). 773 res, err := val.ToInt() 774 if err == types.ErrTruncated { 775 err = nil 776 if val.IsNegative() { 777 res-- 778 } 779 } 780 return res, false, err 781 } 782 783 type builtinFloorDecToDecSig struct { 784 baseBuiltinFunc 785 } 786 787 func (b *builtinFloorDecToDecSig) Clone() builtinFunc { 788 newSig := &builtinFloorDecToDecSig{} 789 newSig.cloneFrom(&b.baseBuiltinFunc) 790 return newSig 791 } 792 793 // evalDecimal evals a builtinFloorDecToDecSig. 794 func (b *builtinFloorDecToDecSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 795 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 796 if isNull || err != nil { 797 return nil, true, err 798 } 799 800 res := new(types.MyDecimal) 801 if !val.IsNegative() { 802 err = val.Round(res, 0, types.ModeTruncate) 803 return res, err != nil, err 804 } 805 806 err = val.Round(res, 0, types.ModeTruncate) 807 if err != nil || res.Compare(val) == 0 { 808 return res, err != nil, err 809 } 810 811 err = types.DecimalSub(res, types.NewDecFromInt(1), res) 812 return res, err != nil, err 813 } 814 815 type logFunctionClass struct { 816 baseFunctionClass 817 } 818 819 func (c *logFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 820 if err := c.verifyArgs(args); err != nil { 821 return nil, err 822 } 823 var ( 824 sig builtinFunc 825 bf baseBuiltinFunc 826 argsLen = len(args) 827 ) 828 829 var err error 830 if argsLen == 1 { 831 bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 832 if err != nil { 833 return nil, err 834 } 835 } else { 836 bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal, types.ETReal) 837 if err != nil { 838 return nil, err 839 } 840 } 841 842 if argsLen == 1 { 843 sig = &builtinLog1ArgSig{bf} 844 sig.setPbCode(fidelpb.ScalarFuncSig_Log1Arg) 845 } else { 846 sig = &builtinLog2ArgsSig{bf} 847 sig.setPbCode(fidelpb.ScalarFuncSig_Log2Args) 848 } 849 850 return sig, nil 851 } 852 853 type builtinLog1ArgSig struct { 854 baseBuiltinFunc 855 } 856 857 func (b *builtinLog1ArgSig) Clone() builtinFunc { 858 newSig := &builtinLog1ArgSig{} 859 newSig.cloneFrom(&b.baseBuiltinFunc) 860 return newSig 861 } 862 863 // evalReal evals a builtinLog1ArgSig, corresponding to log(x). 864 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_log 865 func (b *builtinLog1ArgSig) evalReal(event chunk.Event) (float64, bool, error) { 866 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 867 if isNull || err != nil { 868 return 0, isNull, err 869 } 870 if val <= 0 { 871 b.ctx.GetStochastikVars().StmtCtx.AppendWarning(ErrInvalidArgumentForLogarithm) 872 return 0, true, nil 873 } 874 return math.Log(val), false, nil 875 } 876 877 type builtinLog2ArgsSig struct { 878 baseBuiltinFunc 879 } 880 881 func (b *builtinLog2ArgsSig) Clone() builtinFunc { 882 newSig := &builtinLog2ArgsSig{} 883 newSig.cloneFrom(&b.baseBuiltinFunc) 884 return newSig 885 } 886 887 // evalReal evals a builtinLog2ArgsSig, corresponding to log(b, x). 888 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_log 889 func (b *builtinLog2ArgsSig) evalReal(event chunk.Event) (float64, bool, error) { 890 val1, isNull, err := b.args[0].EvalReal(b.ctx, event) 891 if isNull || err != nil { 892 return 0, isNull, err 893 } 894 895 val2, isNull, err := b.args[1].EvalReal(b.ctx, event) 896 if isNull || err != nil { 897 return 0, isNull, err 898 } 899 900 if val1 <= 0 || val1 == 1 || val2 <= 0 { 901 b.ctx.GetStochastikVars().StmtCtx.AppendWarning(ErrInvalidArgumentForLogarithm) 902 return 0, true, nil 903 } 904 905 return math.Log(val2) / math.Log(val1), false, nil 906 } 907 908 type log2FunctionClass struct { 909 baseFunctionClass 910 } 911 912 func (c *log2FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 913 if err := c.verifyArgs(args); err != nil { 914 return nil, err 915 } 916 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 917 if err != nil { 918 return nil, err 919 } 920 sig := &builtinLog2Sig{bf} 921 sig.setPbCode(fidelpb.ScalarFuncSig_Log2) 922 return sig, nil 923 } 924 925 type builtinLog2Sig struct { 926 baseBuiltinFunc 927 } 928 929 func (b *builtinLog2Sig) Clone() builtinFunc { 930 newSig := &builtinLog2Sig{} 931 newSig.cloneFrom(&b.baseBuiltinFunc) 932 return newSig 933 } 934 935 // evalReal evals a builtinLog2Sig. 936 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_log2 937 func (b *builtinLog2Sig) evalReal(event chunk.Event) (float64, bool, error) { 938 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 939 if isNull || err != nil { 940 return 0, isNull, err 941 } 942 if val <= 0 { 943 b.ctx.GetStochastikVars().StmtCtx.AppendWarning(ErrInvalidArgumentForLogarithm) 944 return 0, true, nil 945 } 946 return math.Log2(val), false, nil 947 } 948 949 type log10FunctionClass struct { 950 baseFunctionClass 951 } 952 953 func (c *log10FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 954 if err := c.verifyArgs(args); err != nil { 955 return nil, err 956 } 957 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 958 if err != nil { 959 return nil, err 960 } 961 sig := &builtinLog10Sig{bf} 962 sig.setPbCode(fidelpb.ScalarFuncSig_Log10) 963 return sig, nil 964 } 965 966 type builtinLog10Sig struct { 967 baseBuiltinFunc 968 } 969 970 func (b *builtinLog10Sig) Clone() builtinFunc { 971 newSig := &builtinLog10Sig{} 972 newSig.cloneFrom(&b.baseBuiltinFunc) 973 return newSig 974 } 975 976 // evalReal evals a builtinLog10Sig. 977 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_log10 978 func (b *builtinLog10Sig) evalReal(event chunk.Event) (float64, bool, error) { 979 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 980 if isNull || err != nil { 981 return 0, isNull, err 982 } 983 if val <= 0 { 984 b.ctx.GetStochastikVars().StmtCtx.AppendWarning(ErrInvalidArgumentForLogarithm) 985 return 0, true, nil 986 } 987 return math.Log10(val), false, nil 988 } 989 990 type randFunctionClass struct { 991 baseFunctionClass 992 } 993 994 func (c *randFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 995 if err := c.verifyArgs(args); err != nil { 996 return nil, err 997 } 998 var sig builtinFunc 999 var argTps []types.EvalType 1000 if len(args) > 0 { 1001 argTps = []types.EvalType{types.ETInt} 1002 } 1003 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, argTps...) 1004 if err != nil { 1005 return nil, err 1006 } 1007 bt := bf 1008 if len(args) == 0 { 1009 sig = &builtinRandSig{bt, &sync.Mutex{}, NewWithTime()} 1010 sig.setPbCode(fidelpb.ScalarFuncSig_Rand) 1011 } else if _, isConstant := args[0].(*Constant); isConstant { 1012 // According to MyALLEGROSQL manual: 1013 // If an integer argument N is specified, it is used as the seed value: 1014 // With a constant initializer argument, the seed is initialized once 1015 // when the memex is prepared, prior to execution. 1016 seed, isNull, err := args[0].EvalInt(ctx, chunk.Event{}) 1017 if err != nil { 1018 return nil, err 1019 } 1020 if isNull { 1021 // When the seed is null we need to use 0 as the seed. 1022 // The behavior same as MyALLEGROSQL. 1023 seed = 0 1024 } 1025 sig = &builtinRandSig{bt, &sync.Mutex{}, NewWithSeed(seed)} 1026 sig.setPbCode(fidelpb.ScalarFuncSig_Rand) 1027 } else { 1028 sig = &builtinRandWithSeedFirstGenSig{bt} 1029 sig.setPbCode(fidelpb.ScalarFuncSig_RandWithSeedFirstGen) 1030 } 1031 return sig, nil 1032 } 1033 1034 type builtinRandSig struct { 1035 baseBuiltinFunc 1036 mu *sync.Mutex 1037 mysqlRng *MysqlRng 1038 } 1039 1040 func (b *builtinRandSig) Clone() builtinFunc { 1041 newSig := &builtinRandSig{mysqlRng: b.mysqlRng, mu: b.mu} 1042 newSig.cloneFrom(&b.baseBuiltinFunc) 1043 return newSig 1044 } 1045 1046 // evalReal evals RAND(). 1047 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_rand 1048 func (b *builtinRandSig) evalReal(event chunk.Event) (float64, bool, error) { 1049 b.mu.Lock() 1050 res := b.mysqlRng.Gen() 1051 b.mu.Unlock() 1052 return res, false, nil 1053 } 1054 1055 type builtinRandWithSeedFirstGenSig struct { 1056 baseBuiltinFunc 1057 } 1058 1059 func (b *builtinRandWithSeedFirstGenSig) Clone() builtinFunc { 1060 newSig := &builtinRandWithSeedFirstGenSig{} 1061 newSig.cloneFrom(&b.baseBuiltinFunc) 1062 return newSig 1063 } 1064 1065 // evalReal evals RAND(N). 1066 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_rand 1067 func (b *builtinRandWithSeedFirstGenSig) evalReal(event chunk.Event) (float64, bool, error) { 1068 seed, isNull, err := b.args[0].EvalInt(b.ctx, event) 1069 if err != nil { 1070 return 0, true, err 1071 } 1072 // b.args[0] is promised to be a non-constant(such as a defCausumn name) in 1073 // builtinRandWithSeedFirstGenSig, the seed is initialized with the value for each 1074 // invocation of RAND(). 1075 var rng *MysqlRng 1076 if !isNull { 1077 rng = NewWithSeed(seed) 1078 } else { 1079 rng = NewWithSeed(0) 1080 } 1081 return rng.Gen(), false, nil 1082 } 1083 1084 type powFunctionClass struct { 1085 baseFunctionClass 1086 } 1087 1088 func (c *powFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1089 if err := c.verifyArgs(args); err != nil { 1090 return nil, err 1091 } 1092 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal, types.ETReal) 1093 if err != nil { 1094 return nil, err 1095 } 1096 sig := &builtinPowSig{bf} 1097 sig.setPbCode(fidelpb.ScalarFuncSig_Pow) 1098 return sig, nil 1099 } 1100 1101 type builtinPowSig struct { 1102 baseBuiltinFunc 1103 } 1104 1105 func (b *builtinPowSig) Clone() builtinFunc { 1106 newSig := &builtinPowSig{} 1107 newSig.cloneFrom(&b.baseBuiltinFunc) 1108 return newSig 1109 } 1110 1111 // evalReal evals POW(x, y). 1112 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_pow 1113 func (b *builtinPowSig) evalReal(event chunk.Event) (float64, bool, error) { 1114 x, isNull, err := b.args[0].EvalReal(b.ctx, event) 1115 if isNull || err != nil { 1116 return 0, isNull, err 1117 } 1118 y, isNull, err := b.args[1].EvalReal(b.ctx, event) 1119 if isNull || err != nil { 1120 return 0, isNull, err 1121 } 1122 power := math.Pow(x, y) 1123 if math.IsInf(power, -1) || math.IsInf(power, 1) || math.IsNaN(power) { 1124 return 0, false, types.ErrOverflow.GenWithStackByArgs("DOUBLE", fmt.Sprintf("pow(%s, %s)", strconv.FormatFloat(x, 'f', -1, 64), strconv.FormatFloat(y, 'f', -1, 64))) 1125 } 1126 return power, false, nil 1127 } 1128 1129 type roundFunctionClass struct { 1130 baseFunctionClass 1131 } 1132 1133 type convFunctionClass struct { 1134 baseFunctionClass 1135 } 1136 1137 func (c *convFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1138 if err := c.verifyArgs(args); err != nil { 1139 return nil, err 1140 } 1141 1142 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETInt, types.ETInt) 1143 if err != nil { 1144 return nil, err 1145 } 1146 bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo() 1147 bf.tp.Flen = 64 1148 sig := &builtinConvSig{bf} 1149 sig.setPbCode(fidelpb.ScalarFuncSig_Conv) 1150 return sig, nil 1151 } 1152 1153 type builtinConvSig struct { 1154 baseBuiltinFunc 1155 } 1156 1157 func (b *builtinConvSig) Clone() builtinFunc { 1158 newSig := &builtinConvSig{} 1159 newSig.cloneFrom(&b.baseBuiltinFunc) 1160 return newSig 1161 } 1162 1163 // evalString evals CONV(N,from_base,to_base). 1164 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_conv. 1165 func (b *builtinConvSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 1166 str, isNull, err := b.args[0].EvalString(b.ctx, event) 1167 if isNull || err != nil { 1168 return res, isNull, err 1169 } 1170 1171 fromBase, isNull, err := b.args[1].EvalInt(b.ctx, event) 1172 if isNull || err != nil { 1173 return res, isNull, err 1174 } 1175 1176 toBase, isNull, err := b.args[2].EvalInt(b.ctx, event) 1177 if isNull || err != nil { 1178 return res, isNull, err 1179 } 1180 return b.conv(str, fromBase, toBase) 1181 } 1182 func (b *builtinConvSig) conv(str string, fromBase, toBase int64) (res string, isNull bool, err error) { 1183 var ( 1184 signed bool 1185 negative bool 1186 ignoreSign bool 1187 ) 1188 if fromBase < 0 { 1189 fromBase = -fromBase 1190 signed = true 1191 } 1192 1193 if toBase < 0 { 1194 toBase = -toBase 1195 ignoreSign = true 1196 } 1197 1198 if fromBase > 36 || fromBase < 2 || toBase > 36 || toBase < 2 { 1199 return res, true, nil 1200 } 1201 1202 str = getValidPrefix(strings.TrimSpace(str), fromBase) 1203 if len(str) == 0 { 1204 return "0", false, nil 1205 } 1206 1207 if str[0] == '-' { 1208 negative = true 1209 str = str[1:] 1210 } 1211 1212 val, err := strconv.ParseUint(str, int(fromBase), 64) 1213 if err != nil { 1214 return res, false, types.ErrOverflow.GenWithStackByArgs("BIGINT UNSINGED", str) 1215 } 1216 if signed { 1217 if negative && val > -math.MinInt64 { 1218 val = -math.MinInt64 1219 } 1220 if !negative && val > math.MaxInt64 { 1221 val = math.MaxInt64 1222 } 1223 } 1224 if negative { 1225 val = -val 1226 } 1227 1228 if int64(val) < 0 { 1229 negative = true 1230 } else { 1231 negative = false 1232 } 1233 if ignoreSign && negative { 1234 val = 0 - val 1235 } 1236 1237 s := strconv.FormatUint(val, int(toBase)) 1238 if negative && ignoreSign { 1239 s = "-" + s 1240 } 1241 res = strings.ToUpper(s) 1242 return res, false, nil 1243 } 1244 1245 type crc32FunctionClass struct { 1246 baseFunctionClass 1247 } 1248 1249 func (c *crc32FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1250 if err := c.verifyArgs(args); err != nil { 1251 return nil, err 1252 } 1253 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString) 1254 if err != nil { 1255 return nil, err 1256 } 1257 bf.tp.Flen = 10 1258 bf.tp.Flag |= allegrosql.UnsignedFlag 1259 sig := &builtinCRC32Sig{bf} 1260 sig.setPbCode(fidelpb.ScalarFuncSig_CRC32) 1261 return sig, nil 1262 } 1263 1264 type builtinCRC32Sig struct { 1265 baseBuiltinFunc 1266 } 1267 1268 func (b *builtinCRC32Sig) Clone() builtinFunc { 1269 newSig := &builtinCRC32Sig{} 1270 newSig.cloneFrom(&b.baseBuiltinFunc) 1271 return newSig 1272 } 1273 1274 // evalInt evals a CRC32(expr). 1275 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_crc32 1276 func (b *builtinCRC32Sig) evalInt(event chunk.Event) (int64, bool, error) { 1277 x, isNull, err := b.args[0].EvalString(b.ctx, event) 1278 if isNull || err != nil { 1279 return 0, isNull, err 1280 } 1281 r := crc32.ChecksumIEEE([]byte(x)) 1282 return int64(r), false, nil 1283 } 1284 1285 type signFunctionClass struct { 1286 baseFunctionClass 1287 } 1288 1289 func (c *signFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1290 if err := c.verifyArgs(args); err != nil { 1291 return nil, err 1292 } 1293 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETReal) 1294 if err != nil { 1295 return nil, err 1296 } 1297 sig := &builtinSignSig{bf} 1298 sig.setPbCode(fidelpb.ScalarFuncSig_Sign) 1299 return sig, nil 1300 } 1301 1302 type builtinSignSig struct { 1303 baseBuiltinFunc 1304 } 1305 1306 func (b *builtinSignSig) Clone() builtinFunc { 1307 newSig := &builtinSignSig{} 1308 newSig.cloneFrom(&b.baseBuiltinFunc) 1309 return newSig 1310 } 1311 1312 // evalInt evals SIGN(v). 1313 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_sign 1314 func (b *builtinSignSig) evalInt(event chunk.Event) (int64, bool, error) { 1315 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1316 if isNull || err != nil { 1317 return 0, isNull, err 1318 } 1319 if val > 0 { 1320 return 1, false, nil 1321 } else if val == 0 { 1322 return 0, false, nil 1323 } else { 1324 return -1, false, nil 1325 } 1326 } 1327 1328 type sqrtFunctionClass struct { 1329 baseFunctionClass 1330 } 1331 1332 func (c *sqrtFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1333 if err := c.verifyArgs(args); err != nil { 1334 return nil, err 1335 } 1336 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1337 if err != nil { 1338 return nil, err 1339 } 1340 sig := &builtinSqrtSig{bf} 1341 sig.setPbCode(fidelpb.ScalarFuncSig_Sqrt) 1342 return sig, nil 1343 } 1344 1345 type builtinSqrtSig struct { 1346 baseBuiltinFunc 1347 } 1348 1349 func (b *builtinSqrtSig) Clone() builtinFunc { 1350 newSig := &builtinSqrtSig{} 1351 newSig.cloneFrom(&b.baseBuiltinFunc) 1352 return newSig 1353 } 1354 1355 // evalReal evals a SQRT(x). 1356 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_sqrt 1357 func (b *builtinSqrtSig) evalReal(event chunk.Event) (float64, bool, error) { 1358 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1359 if isNull || err != nil { 1360 return 0, isNull, err 1361 } 1362 if val < 0 { 1363 return 0, true, nil 1364 } 1365 return math.Sqrt(val), false, nil 1366 } 1367 1368 type acosFunctionClass struct { 1369 baseFunctionClass 1370 } 1371 1372 func (c *acosFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1373 if err := c.verifyArgs(args); err != nil { 1374 return nil, err 1375 } 1376 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1377 if err != nil { 1378 return nil, err 1379 } 1380 sig := &builtinAcosSig{bf} 1381 sig.setPbCode(fidelpb.ScalarFuncSig_Acos) 1382 return sig, nil 1383 } 1384 1385 type builtinAcosSig struct { 1386 baseBuiltinFunc 1387 } 1388 1389 func (b *builtinAcosSig) Clone() builtinFunc { 1390 newSig := &builtinAcosSig{} 1391 newSig.cloneFrom(&b.baseBuiltinFunc) 1392 return newSig 1393 } 1394 1395 // evalReal evals a builtinAcosSig. 1396 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_acos 1397 func (b *builtinAcosSig) evalReal(event chunk.Event) (float64, bool, error) { 1398 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1399 if isNull || err != nil { 1400 return 0, isNull, err 1401 } 1402 if val < -1 || val > 1 { 1403 return 0, true, nil 1404 } 1405 1406 return math.Acos(val), false, nil 1407 } 1408 1409 type asinFunctionClass struct { 1410 baseFunctionClass 1411 } 1412 1413 func (c *asinFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1414 if err := c.verifyArgs(args); err != nil { 1415 return nil, err 1416 } 1417 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1418 if err != nil { 1419 return nil, err 1420 } 1421 sig := &builtinAsinSig{bf} 1422 sig.setPbCode(fidelpb.ScalarFuncSig_Asin) 1423 return sig, nil 1424 } 1425 1426 type builtinAsinSig struct { 1427 baseBuiltinFunc 1428 } 1429 1430 func (b *builtinAsinSig) Clone() builtinFunc { 1431 newSig := &builtinAsinSig{} 1432 newSig.cloneFrom(&b.baseBuiltinFunc) 1433 return newSig 1434 } 1435 1436 // evalReal evals a builtinAsinSig. 1437 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_asin 1438 func (b *builtinAsinSig) evalReal(event chunk.Event) (float64, bool, error) { 1439 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1440 if isNull || err != nil { 1441 return 0, isNull, err 1442 } 1443 1444 if val < -1 || val > 1 { 1445 return 0, true, nil 1446 } 1447 1448 return math.Asin(val), false, nil 1449 } 1450 1451 type atanFunctionClass struct { 1452 baseFunctionClass 1453 } 1454 1455 func (c *atanFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1456 if err := c.verifyArgs(args); err != nil { 1457 return nil, err 1458 } 1459 var ( 1460 sig builtinFunc 1461 bf baseBuiltinFunc 1462 argsLen = len(args) 1463 ) 1464 1465 var err error 1466 if argsLen == 1 { 1467 bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1468 if err != nil { 1469 return nil, err 1470 } 1471 } else { 1472 bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal, types.ETReal) 1473 if err != nil { 1474 return nil, err 1475 } 1476 } 1477 1478 if argsLen == 1 { 1479 sig = &builtinAtan1ArgSig{bf} 1480 sig.setPbCode(fidelpb.ScalarFuncSig_Atan1Arg) 1481 } else { 1482 sig = &builtinAtan2ArgsSig{bf} 1483 sig.setPbCode(fidelpb.ScalarFuncSig_Atan2Args) 1484 } 1485 1486 return sig, nil 1487 } 1488 1489 type builtinAtan1ArgSig struct { 1490 baseBuiltinFunc 1491 } 1492 1493 func (b *builtinAtan1ArgSig) Clone() builtinFunc { 1494 newSig := &builtinAtan1ArgSig{} 1495 newSig.cloneFrom(&b.baseBuiltinFunc) 1496 return newSig 1497 } 1498 1499 // evalReal evals a builtinAtan1ArgSig, corresponding to atan(x). 1500 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_atan 1501 func (b *builtinAtan1ArgSig) evalReal(event chunk.Event) (float64, bool, error) { 1502 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1503 if isNull || err != nil { 1504 return 0, isNull, err 1505 } 1506 1507 return math.Atan(val), false, nil 1508 } 1509 1510 type builtinAtan2ArgsSig struct { 1511 baseBuiltinFunc 1512 } 1513 1514 func (b *builtinAtan2ArgsSig) Clone() builtinFunc { 1515 newSig := &builtinAtan2ArgsSig{} 1516 newSig.cloneFrom(&b.baseBuiltinFunc) 1517 return newSig 1518 } 1519 1520 // evalReal evals a builtinAtan1ArgSig, corresponding to atan(y, x). 1521 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_atan 1522 func (b *builtinAtan2ArgsSig) evalReal(event chunk.Event) (float64, bool, error) { 1523 val1, isNull, err := b.args[0].EvalReal(b.ctx, event) 1524 if isNull || err != nil { 1525 return 0, isNull, err 1526 } 1527 1528 val2, isNull, err := b.args[1].EvalReal(b.ctx, event) 1529 if isNull || err != nil { 1530 return 0, isNull, err 1531 } 1532 1533 return math.Atan2(val1, val2), false, nil 1534 } 1535 1536 type cosFunctionClass struct { 1537 baseFunctionClass 1538 } 1539 1540 func (c *cosFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1541 if err := c.verifyArgs(args); err != nil { 1542 return nil, err 1543 } 1544 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1545 if err != nil { 1546 return nil, err 1547 } 1548 sig := &builtinCosSig{bf} 1549 sig.setPbCode(fidelpb.ScalarFuncSig_Cos) 1550 return sig, nil 1551 } 1552 1553 type builtinCosSig struct { 1554 baseBuiltinFunc 1555 } 1556 1557 func (b *builtinCosSig) Clone() builtinFunc { 1558 newSig := &builtinCosSig{} 1559 newSig.cloneFrom(&b.baseBuiltinFunc) 1560 return newSig 1561 } 1562 1563 // evalReal evals a builtinCosSig. 1564 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_cos 1565 func (b *builtinCosSig) evalReal(event chunk.Event) (float64, bool, error) { 1566 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1567 if isNull || err != nil { 1568 return 0, isNull, err 1569 } 1570 return math.Cos(val), false, nil 1571 } 1572 1573 type cotFunctionClass struct { 1574 baseFunctionClass 1575 } 1576 1577 func (c *cotFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1578 if err := c.verifyArgs(args); err != nil { 1579 return nil, err 1580 } 1581 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1582 if err != nil { 1583 return nil, err 1584 } 1585 sig := &builtinCotSig{bf} 1586 sig.setPbCode(fidelpb.ScalarFuncSig_Cot) 1587 return sig, nil 1588 } 1589 1590 type builtinCotSig struct { 1591 baseBuiltinFunc 1592 } 1593 1594 func (b *builtinCotSig) Clone() builtinFunc { 1595 newSig := &builtinCotSig{} 1596 newSig.cloneFrom(&b.baseBuiltinFunc) 1597 return newSig 1598 } 1599 1600 // evalReal evals a builtinCotSig. 1601 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_cot 1602 func (b *builtinCotSig) evalReal(event chunk.Event) (float64, bool, error) { 1603 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1604 if isNull || err != nil { 1605 return 0, isNull, err 1606 } 1607 1608 tan := math.Tan(val) 1609 if tan != 0 { 1610 cot := 1 / tan 1611 if !math.IsInf(cot, 0) && !math.IsNaN(cot) { 1612 return cot, false, nil 1613 } 1614 } 1615 return 0, false, types.ErrOverflow.GenWithStackByArgs("DOUBLE", fmt.Sprintf("cot(%s)", strconv.FormatFloat(val, 'f', -1, 64))) 1616 } 1617 1618 type degreesFunctionClass struct { 1619 baseFunctionClass 1620 } 1621 1622 func (c *degreesFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1623 if err := c.verifyArgs(args); err != nil { 1624 return nil, err 1625 } 1626 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1627 if err != nil { 1628 return nil, err 1629 } 1630 sig := &builtinDegreesSig{bf} 1631 sig.setPbCode(fidelpb.ScalarFuncSig_Degrees) 1632 return sig, nil 1633 } 1634 1635 type builtinDegreesSig struct { 1636 baseBuiltinFunc 1637 } 1638 1639 func (b *builtinDegreesSig) Clone() builtinFunc { 1640 newSig := &builtinDegreesSig{} 1641 newSig.cloneFrom(&b.baseBuiltinFunc) 1642 return newSig 1643 } 1644 1645 // evalReal evals a builtinDegreesSig. 1646 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_degrees 1647 func (b *builtinDegreesSig) evalReal(event chunk.Event) (float64, bool, error) { 1648 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1649 if isNull || err != nil { 1650 return 0, isNull, err 1651 } 1652 res := val * 180 / math.Pi 1653 return res, false, nil 1654 } 1655 1656 type expFunctionClass struct { 1657 baseFunctionClass 1658 } 1659 1660 func (c *expFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1661 if err := c.verifyArgs(args); err != nil { 1662 return nil, err 1663 } 1664 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1665 if err != nil { 1666 return nil, err 1667 } 1668 sig := &builtinExpSig{bf} 1669 sig.setPbCode(fidelpb.ScalarFuncSig_Exp) 1670 return sig, nil 1671 } 1672 1673 type builtinExpSig struct { 1674 baseBuiltinFunc 1675 } 1676 1677 func (b *builtinExpSig) Clone() builtinFunc { 1678 newSig := &builtinExpSig{} 1679 newSig.cloneFrom(&b.baseBuiltinFunc) 1680 return newSig 1681 } 1682 1683 // evalReal evals a builtinExpSig. 1684 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_exp 1685 func (b *builtinExpSig) evalReal(event chunk.Event) (float64, bool, error) { 1686 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1687 if isNull || err != nil { 1688 return 0, isNull, err 1689 } 1690 exp := math.Exp(val) 1691 if math.IsInf(exp, 0) || math.IsNaN(exp) { 1692 s := fmt.Sprintf("exp(%s)", b.args[0].String()) 1693 return 0, false, types.ErrOverflow.GenWithStackByArgs("DOUBLE", s) 1694 } 1695 return exp, false, nil 1696 } 1697 1698 type piFunctionClass struct { 1699 baseFunctionClass 1700 } 1701 1702 func (c *piFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1703 if err := c.verifyArgs(args); err != nil { 1704 return nil, err 1705 } 1706 var ( 1707 bf baseBuiltinFunc 1708 sig builtinFunc 1709 ) 1710 1711 var err error 1712 bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal) 1713 if err != nil { 1714 return nil, err 1715 } 1716 bf.tp.Decimal = 6 1717 bf.tp.Flen = 8 1718 sig = &builtinPISig{bf} 1719 sig.setPbCode(fidelpb.ScalarFuncSig_PI) 1720 return sig, nil 1721 } 1722 1723 type builtinPISig struct { 1724 baseBuiltinFunc 1725 } 1726 1727 func (b *builtinPISig) Clone() builtinFunc { 1728 newSig := &builtinPISig{} 1729 newSig.cloneFrom(&b.baseBuiltinFunc) 1730 return newSig 1731 } 1732 1733 // evalReal evals a builtinPISig. 1734 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_pi 1735 func (b *builtinPISig) evalReal(_ chunk.Event) (float64, bool, error) { 1736 return float64(math.Pi), false, nil 1737 } 1738 1739 type radiansFunctionClass struct { 1740 baseFunctionClass 1741 } 1742 1743 func (c *radiansFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1744 if err := c.verifyArgs(args); err != nil { 1745 return nil, err 1746 } 1747 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1748 if err != nil { 1749 return nil, err 1750 } 1751 sig := &builtinRadiansSig{bf} 1752 sig.setPbCode(fidelpb.ScalarFuncSig_Radians) 1753 return sig, nil 1754 } 1755 1756 type builtinRadiansSig struct { 1757 baseBuiltinFunc 1758 } 1759 1760 func (b *builtinRadiansSig) Clone() builtinFunc { 1761 newSig := &builtinRadiansSig{} 1762 newSig.cloneFrom(&b.baseBuiltinFunc) 1763 return newSig 1764 } 1765 1766 // evalReal evals RADIANS(X). 1767 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_radians 1768 func (b *builtinRadiansSig) evalReal(event chunk.Event) (float64, bool, error) { 1769 x, isNull, err := b.args[0].EvalReal(b.ctx, event) 1770 if isNull || err != nil { 1771 return 0, isNull, err 1772 } 1773 return x * math.Pi / 180, false, nil 1774 } 1775 1776 type sinFunctionClass struct { 1777 baseFunctionClass 1778 } 1779 1780 func (c *sinFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1781 if err := c.verifyArgs(args); err != nil { 1782 return nil, err 1783 } 1784 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1785 if err != nil { 1786 return nil, err 1787 } 1788 sig := &builtinSinSig{bf} 1789 sig.setPbCode(fidelpb.ScalarFuncSig_Sin) 1790 return sig, nil 1791 } 1792 1793 type builtinSinSig struct { 1794 baseBuiltinFunc 1795 } 1796 1797 func (b *builtinSinSig) Clone() builtinFunc { 1798 newSig := &builtinSinSig{} 1799 newSig.cloneFrom(&b.baseBuiltinFunc) 1800 return newSig 1801 } 1802 1803 // evalReal evals a builtinSinSig. 1804 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_sin 1805 func (b *builtinSinSig) evalReal(event chunk.Event) (float64, bool, error) { 1806 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1807 if isNull || err != nil { 1808 return 0, isNull, err 1809 } 1810 return math.Sin(val), false, nil 1811 } 1812 1813 type tanFunctionClass struct { 1814 baseFunctionClass 1815 } 1816 1817 func (c *tanFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1818 if err := c.verifyArgs(args); err != nil { 1819 return nil, err 1820 } 1821 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETReal, types.ETReal) 1822 if err != nil { 1823 return nil, err 1824 } 1825 sig := &builtinTanSig{bf} 1826 sig.setPbCode(fidelpb.ScalarFuncSig_Tan) 1827 return sig, nil 1828 } 1829 1830 type builtinTanSig struct { 1831 baseBuiltinFunc 1832 } 1833 1834 func (b *builtinTanSig) Clone() builtinFunc { 1835 newSig := &builtinTanSig{} 1836 newSig.cloneFrom(&b.baseBuiltinFunc) 1837 return newSig 1838 } 1839 1840 // evalReal evals a builtinTanSig. 1841 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_tan 1842 func (b *builtinTanSig) evalReal(event chunk.Event) (float64, bool, error) { 1843 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 1844 if isNull || err != nil { 1845 return 0, isNull, err 1846 } 1847 return math.Tan(val), false, nil 1848 } 1849 1850 type truncateFunctionClass struct { 1851 baseFunctionClass 1852 } 1853 1854 func (c *truncateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 1855 if err := c.verifyArgs(args); err != nil { 1856 return nil, err 1857 } 1858 1859 argTp := args[0].GetType().EvalType() 1860 if argTp.IsStringHoTT() { 1861 argTp = types.ETReal 1862 } 1863 1864 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, argTp, argTp, types.ETInt) 1865 if err != nil { 1866 return nil, err 1867 } 1868 1869 bf.tp.Decimal = calculateDecimal4RoundAndTruncate(ctx, args, argTp) 1870 bf.tp.Flen = args[0].GetType().Flen - args[0].GetType().Decimal + bf.tp.Decimal 1871 bf.tp.Flag |= args[0].GetType().Flag 1872 1873 var sig builtinFunc 1874 switch argTp { 1875 case types.ETInt: 1876 if allegrosql.HasUnsignedFlag(args[0].GetType().Flag) { 1877 sig = &builtinTruncateUintSig{bf} 1878 sig.setPbCode(fidelpb.ScalarFuncSig_TruncateUint) 1879 } else { 1880 sig = &builtinTruncateIntSig{bf} 1881 sig.setPbCode(fidelpb.ScalarFuncSig_TruncateInt) 1882 } 1883 case types.ETReal: 1884 sig = &builtinTruncateRealSig{bf} 1885 sig.setPbCode(fidelpb.ScalarFuncSig_TruncateReal) 1886 case types.ETDecimal: 1887 sig = &builtinTruncateDecimalSig{bf} 1888 sig.setPbCode(fidelpb.ScalarFuncSig_TruncateDecimal) 1889 default: 1890 return nil, errIncorrectArgs.GenWithStackByArgs("truncate") 1891 } 1892 1893 return sig, nil 1894 } 1895 1896 type builtinTruncateDecimalSig struct { 1897 baseBuiltinFunc 1898 } 1899 1900 func (b *builtinTruncateDecimalSig) Clone() builtinFunc { 1901 newSig := &builtinTruncateDecimalSig{} 1902 newSig.cloneFrom(&b.baseBuiltinFunc) 1903 return newSig 1904 } 1905 1906 // evalDecimal evals a TRUNCATE(X,D). 1907 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_truncate 1908 func (b *builtinTruncateDecimalSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 1909 x, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 1910 if isNull || err != nil { 1911 return nil, isNull, err 1912 } 1913 1914 d, isNull, err := b.args[1].EvalInt(b.ctx, event) 1915 if isNull || err != nil { 1916 return nil, isNull, err 1917 } 1918 1919 result := new(types.MyDecimal) 1920 if err := x.Round(result, mathutil.Min(int(d), b.getRetTp().Decimal), types.ModeTruncate); err != nil { 1921 return nil, true, err 1922 } 1923 return result, false, nil 1924 } 1925 1926 type builtinTruncateRealSig struct { 1927 baseBuiltinFunc 1928 } 1929 1930 func (b *builtinTruncateRealSig) Clone() builtinFunc { 1931 newSig := &builtinTruncateRealSig{} 1932 newSig.cloneFrom(&b.baseBuiltinFunc) 1933 return newSig 1934 } 1935 1936 // evalReal evals a TRUNCATE(X,D). 1937 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_truncate 1938 func (b *builtinTruncateRealSig) evalReal(event chunk.Event) (float64, bool, error) { 1939 x, isNull, err := b.args[0].EvalReal(b.ctx, event) 1940 if isNull || err != nil { 1941 return 0, isNull, err 1942 } 1943 1944 d, isNull, err := b.args[1].EvalInt(b.ctx, event) 1945 if isNull || err != nil { 1946 return 0, isNull, err 1947 } 1948 1949 return types.Truncate(x, int(d)), false, nil 1950 } 1951 1952 type builtinTruncateIntSig struct { 1953 baseBuiltinFunc 1954 } 1955 1956 func (b *builtinTruncateIntSig) Clone() builtinFunc { 1957 newSig := &builtinTruncateIntSig{} 1958 newSig.cloneFrom(&b.baseBuiltinFunc) 1959 return newSig 1960 } 1961 1962 // evalInt evals a TRUNCATE(X,D). 1963 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_truncate 1964 func (b *builtinTruncateIntSig) evalInt(event chunk.Event) (int64, bool, error) { 1965 x, isNull, err := b.args[0].EvalInt(b.ctx, event) 1966 if isNull || err != nil { 1967 return 0, isNull, err 1968 } 1969 if allegrosql.HasUnsignedFlag(b.args[1].GetType().Flag) { 1970 return x, false, nil 1971 } 1972 1973 d, isNull, err := b.args[1].EvalInt(b.ctx, event) 1974 if isNull || err != nil { 1975 return 0, isNull, err 1976 } 1977 1978 if d >= 0 { 1979 return x, false, nil 1980 } 1981 // -MinInt = MinInt, special case 1982 if d == mathutil.MinInt { 1983 return 0, false, nil 1984 } 1985 shift := int64(math.Pow10(int(-d))) 1986 return x / shift * shift, false, nil 1987 } 1988 1989 func (b *builtinTruncateUintSig) Clone() builtinFunc { 1990 newSig := &builtinTruncateUintSig{} 1991 newSig.cloneFrom(&b.baseBuiltinFunc) 1992 return newSig 1993 } 1994 1995 type builtinTruncateUintSig struct { 1996 baseBuiltinFunc 1997 } 1998 1999 // evalInt evals a TRUNCATE(X,D). 2000 // See https://dev.allegrosql.com/doc/refman/5.7/en/mathematical-functions.html#function_truncate 2001 func (b *builtinTruncateUintSig) evalInt(event chunk.Event) (int64, bool, error) { 2002 x, isNull, err := b.args[0].EvalInt(b.ctx, event) 2003 if isNull || err != nil { 2004 return 0, isNull, err 2005 } 2006 if allegrosql.HasUnsignedFlag(b.args[1].GetType().Flag) { 2007 return x, false, nil 2008 } 2009 uintx := uint64(x) 2010 2011 d, isNull, err := b.args[1].EvalInt(b.ctx, event) 2012 if isNull || err != nil { 2013 return 0, isNull, err 2014 } 2015 if d >= 0 { 2016 return x, false, nil 2017 } 2018 // -MinInt = MinInt, special case 2019 if d == mathutil.MinInt { 2020 return 0, false, nil 2021 } 2022 shift := uint64(math.Pow10(int(-d))) 2023 return int64(uintx / shift * shift), false, nil 2024 }