github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/math.go (about) 1 // Copyright 2020-2024 Dolthub, 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package function 16 17 import ( 18 "fmt" 19 "hash/crc32" 20 "math" 21 "math/rand" 22 "regexp" 23 "strconv" 24 "strings" 25 "time" 26 27 "github.com/shopspring/decimal" 28 29 "github.com/dolthub/go-mysql-server/sql" 30 "github.com/dolthub/go-mysql-server/sql/expression" 31 "github.com/dolthub/go-mysql-server/sql/types" 32 ) 33 34 // Rand returns a random float 0 <= x < 1. If it has an argument, that argument will be used to seed the random number 35 // generator, effectively turning it into a hash on that value. 36 type Rand struct { 37 Child sql.Expression 38 } 39 40 var _ sql.Expression = (*Rand)(nil) 41 var _ sql.NonDeterministicExpression = (*Rand)(nil) 42 var _ sql.FunctionExpression = (*Rand)(nil) 43 var _ sql.CollationCoercible = (*Rand)(nil) 44 45 // NewRand creates a new Rand expression. 46 func NewRand(exprs ...sql.Expression) (sql.Expression, error) { 47 if len(exprs) > 1 { 48 return nil, sql.ErrInvalidArgumentNumber.New("rand", "0 or 1", len(exprs)) 49 } 50 if len(exprs) > 0 { 51 return &Rand{Child: exprs[0]}, nil 52 } 53 return &Rand{}, nil 54 } 55 56 // FunctionName implements sql.FunctionExpression 57 func (r *Rand) FunctionName() string { 58 return "rand" 59 } 60 61 // Description implements sql.FunctionExpression 62 func (r *Rand) Description() string { 63 return "returns a random number in the range 0 <= x < 1. If an argument is given, it is used to seed the random number generator." 64 } 65 66 // Type implements sql.Expression. 67 func (r *Rand) Type() sql.Type { 68 return types.Float64 69 } 70 71 // CollationCoercibility implements the interface sql.CollationCoercible. 72 func (*Rand) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 73 return sql.Collation_binary, 5 74 } 75 76 // IsNonDeterministic implements sql.NonDeterministicExpression 77 func (r *Rand) IsNonDeterministic() bool { 78 return r.Child == nil 79 } 80 81 // IsNullable implements sql.Expression 82 func (r *Rand) IsNullable() bool { 83 return false 84 } 85 86 // Resolved implements sql.Expression 87 func (r *Rand) Resolved() bool { 88 return r.Child == nil || r.Child.Resolved() 89 } 90 91 func (r *Rand) String() string { 92 if r.Child != nil { 93 return fmt.Sprintf("%s(%s)", r.FunctionName(), r.Child) 94 } 95 return fmt.Sprintf("%s()", r.FunctionName()) 96 } 97 98 // WithChildren implements sql.Expression. 99 func (r *Rand) WithChildren(children ...sql.Expression) (sql.Expression, error) { 100 if len(children) > 1 { 101 return nil, sql.ErrInvalidChildrenNumber.New(r, len(children), 1) 102 } 103 if len(children) == 0 { 104 return r, nil 105 } 106 107 return NewRand(children[0]) 108 } 109 110 // Children implements sql.Expression 111 func (r *Rand) Children() []sql.Expression { 112 if r.Child == nil { 113 return nil 114 } 115 return []sql.Expression{r.Child} 116 } 117 118 // Eval implements sql.Expression. 119 func (r *Rand) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 120 if r.Child == nil { 121 return rand.Float64(), nil 122 } 123 124 // For child expressions, the mysql semantics are to seed the PRNG with an int64 value of the expression given. For 125 // non-numeric types, the seed will always be 0, which means that rand() will always return the same result for all 126 // non-numeric seed arguments. 127 e, err := r.Child.Eval(ctx, row) 128 if err != nil { 129 return nil, err 130 } 131 132 var seed int64 133 if types.IsNumber(r.Child.Type()) { 134 e, _, err = types.Int64.Convert(e) 135 if err == nil { 136 seed = e.(int64) 137 } 138 } 139 140 return rand.New(rand.NewSource(seed)).Float64(), nil 141 } 142 143 // Sin is the SIN function 144 type Sin struct { 145 *UnaryFunc 146 } 147 148 var _ sql.FunctionExpression = (*Sin)(nil) 149 var _ sql.CollationCoercible = (*Sin)(nil) 150 151 // NewSin returns a new SIN function expression 152 func NewSin(arg sql.Expression) sql.Expression { 153 return &Sin{NewUnaryFunc(arg, "SIN", types.Float64)} 154 } 155 156 // Description implements sql.FunctionExpression 157 func (s *Sin) Description() string { 158 return "returns the sine of the expression given." 159 } 160 161 // CollationCoercibility implements the interface sql.CollationCoercible. 162 func (*Sin) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 163 return sql.Collation_binary, 5 164 } 165 166 // Eval implements sql.Expression 167 func (s *Sin) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 168 val, err := s.EvalChild(ctx, row) 169 if err != nil { 170 return nil, err 171 } 172 173 if val == nil { 174 return nil, nil 175 } 176 177 n, _, err := types.Float64.Convert(val) 178 if err != nil { 179 return nil, err 180 } 181 182 return math.Sin(n.(float64)), nil 183 } 184 185 // WithChildren implements sql.Expression 186 func (s *Sin) WithChildren(children ...sql.Expression) (sql.Expression, error) { 187 if len(children) != 1 { 188 return nil, sql.ErrInvalidChildrenNumber.New(s, len(children), 1) 189 } 190 return NewSin(children[0]), nil 191 } 192 193 type Cos struct { 194 *UnaryFunc 195 } 196 197 var _ sql.FunctionExpression = (*Cos)(nil) 198 var _ sql.CollationCoercible = (*Cos)(nil) 199 200 // NewCos returns a new COS function expression 201 func NewCos(arg sql.Expression) sql.Expression { 202 return &Cos{NewUnaryFunc(arg, "COS", types.Float64)} 203 } 204 205 // Description implements sql.FunctionExpression 206 func (s *Cos) Description() string { 207 return "returns the cosine of an expression." 208 } 209 210 // CollationCoercibility implements the interface sql.CollationCoercible. 211 func (*Cos) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 212 return sql.Collation_binary, 5 213 } 214 215 // Eval implements sql.Expression 216 func (s *Cos) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 217 val, err := s.EvalChild(ctx, row) 218 if err != nil { 219 return nil, err 220 } 221 222 if val == nil { 223 return nil, nil 224 } 225 226 n, _, err := types.Float64.Convert(val) 227 if err != nil { 228 return nil, err 229 } 230 231 return math.Cos(n.(float64)), nil 232 } 233 234 // WithChildren implements sql.Expression 235 func (c *Cos) WithChildren(children ...sql.Expression) (sql.Expression, error) { 236 if len(children) != 1 { 237 return nil, sql.ErrInvalidChildrenNumber.New(c, len(children), 1) 238 } 239 return NewCos(children[0]), nil 240 } 241 242 type Tan struct { 243 *UnaryFunc 244 } 245 246 var _ sql.FunctionExpression = (*Tan)(nil) 247 var _ sql.CollationCoercible = (*Tan)(nil) 248 249 // NewTan returns a new TAN function expression 250 func NewTan(arg sql.Expression) sql.Expression { 251 return &Tan{NewUnaryFunc(arg, "TAN", types.Float64)} 252 } 253 254 // Description implements sql.FunctionExpression 255 func (t *Tan) Description() string { 256 return "returns the tangent of the expression given." 257 } 258 259 // CollationCoercibility implements the interface sql.CollationCoercible. 260 func (*Tan) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 261 return sql.Collation_binary, 5 262 } 263 264 // Eval implements sql.Expression 265 func (t *Tan) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 266 val, err := t.EvalChild(ctx, row) 267 if err != nil { 268 return nil, err 269 } 270 271 if val == nil { 272 return nil, nil 273 } 274 275 n, _, err := types.Float64.Convert(val) 276 if err != nil { 277 return nil, err 278 } 279 res := math.Tan(n.(float64)) 280 if math.IsNaN(res) { 281 return nil, nil 282 } 283 284 return res, nil 285 } 286 287 // WithChildren implements sql.Expression 288 func (t *Tan) WithChildren(children ...sql.Expression) (sql.Expression, error) { 289 if len(children) != 1 { 290 return nil, sql.ErrInvalidChildrenNumber.New(t, len(children), 1) 291 } 292 return NewTan(children[0]), nil 293 } 294 295 type Asin struct { 296 *UnaryFunc 297 } 298 299 var _ sql.FunctionExpression = (*Asin)(nil) 300 var _ sql.CollationCoercible = (*Asin)(nil) 301 302 // NewAsin returns a new ASIN function expression 303 func NewAsin(arg sql.Expression) sql.Expression { 304 return &Asin{NewUnaryFunc(arg, "ASIN", types.Float64)} 305 } 306 307 // Description implements sql.FunctionExpression 308 func (a *Asin) Description() string { 309 return "returns the arcsin of an expression." 310 } 311 312 // CollationCoercibility implements the interface sql.CollationCoercible. 313 func (*Asin) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 314 return sql.Collation_binary, 5 315 } 316 317 // Eval implements sql.Expression 318 func (a *Asin) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 319 val, err := a.EvalChild(ctx, row) 320 if err != nil { 321 return nil, err 322 } 323 324 if val == nil { 325 return nil, nil 326 } 327 328 n, _, err := types.Float64.Convert(val) 329 if err != nil { 330 return nil, err 331 } 332 333 res := math.Asin(n.(float64)) 334 if math.IsNaN(res) { 335 return nil, nil 336 } 337 338 return res, nil 339 } 340 341 // WithChildren implements sql.Expression 342 func (a *Asin) WithChildren(children ...sql.Expression) (sql.Expression, error) { 343 if len(children) != 1 { 344 return nil, sql.ErrInvalidChildrenNumber.New(a, len(children), 1) 345 } 346 return NewAsin(children[0]), nil 347 } 348 349 type Acos struct { 350 *UnaryFunc 351 } 352 353 var _ sql.FunctionExpression = (*Acos)(nil) 354 var _ sql.CollationCoercible = (*Acos)(nil) 355 356 // NewAcos returns a new ACOS function expression 357 func NewAcos(arg sql.Expression) sql.Expression { 358 return &Acos{NewUnaryFunc(arg, "ACOS", types.Float64)} 359 } 360 361 // Description implements sql.FunctionExpression 362 func (a *Acos) Description() string { 363 return "returns the arccos of an expression." 364 } 365 366 // CollationCoercibility implements the interface sql.CollationCoercible. 367 func (*Acos) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 368 return sql.Collation_binary, 5 369 } 370 371 // Eval implements sql.Expression 372 func (a *Acos) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 373 val, err := a.EvalChild(ctx, row) 374 if err != nil { 375 return nil, err 376 } 377 378 if val == nil { 379 return nil, nil 380 } 381 382 n, _, err := types.Float64.Convert(val) 383 if err != nil { 384 return nil, err 385 } 386 387 res := math.Acos(n.(float64)) 388 if math.IsNaN(res) { 389 return nil, nil 390 } 391 392 return res, nil 393 } 394 395 // WithChildren implements sql.Expression 396 func (a *Acos) WithChildren(children ...sql.Expression) (sql.Expression, error) { 397 if len(children) != 1 { 398 return nil, sql.ErrInvalidChildrenNumber.New(a, len(children), 1) 399 } 400 return NewAcos(children[0]), nil 401 } 402 403 type Atan struct { 404 x, y sql.Expression 405 } 406 407 var _ sql.FunctionExpression = (*Atan)(nil) 408 var _ sql.CollationCoercible = (*Atan)(nil) 409 410 // NewAtan returns a new ATAN function expression 411 func NewAtan(args ...sql.Expression) (sql.Expression, error) { 412 if len(args) == 1 { 413 return &Atan{x: expression.NewLiteral(1, types.Int32), y: args[0]}, nil 414 } 415 if len(args) == 2 { 416 return &Atan{x: args[1], y: args[0]}, nil 417 } 418 return nil, sql.ErrInvalidArgumentNumber.New("atan", "1 or 2", len(args)) 419 } 420 421 // FunctionName implements sql.FunctionExpression 422 func (a *Atan) FunctionName() string { 423 return "atan" 424 } 425 426 // Resolved implements sql.Expression 427 func (a *Atan) Resolved() bool { 428 if a.x != nil && !a.x.Resolved() { 429 return false 430 } 431 if a.y != nil && !a.y.Resolved() { 432 return false 433 } 434 return true 435 } 436 437 // String implements sql.Expression 438 func (a *Atan) String() string { 439 if a.x != nil { 440 return fmt.Sprintf("%s(%s, %s)", a.FunctionName(), a.x, a.y) 441 } 442 return fmt.Sprintf("%s(%s)", a.FunctionName(), a.y) 443 } 444 445 // Type implements sql.Expression 446 func (a *Atan) Type() sql.Type { 447 return types.Float64 448 } 449 450 // IsNullable implements sql.Expression 451 func (a *Atan) IsNullable() bool { 452 return true 453 } 454 455 // Description implements sql.FunctionExpression 456 func (a *Atan) Description() string { 457 return "returns the arctan of an expression." 458 } 459 460 // CollationCoercibility implements the interface sql.CollationCoercible. 461 func (*Atan) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 462 return sql.Collation_binary, 5 463 } 464 465 // Eval implements sql.Expression 466 func (a *Atan) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 467 if a.y == nil { 468 return nil, nil 469 } 470 471 yy, err := a.y.Eval(ctx, row) 472 if err != nil { 473 return nil, err 474 } 475 476 if yy == nil { 477 return nil, nil 478 } 479 480 var xx interface{} = float64(1) 481 if a.x != nil { 482 xx, err = a.x.Eval(ctx, row) 483 if err != nil { 484 return nil, err 485 } 486 } 487 if xx == nil { 488 return nil, nil 489 } 490 491 nx, _, err := types.Float64.Convert(xx) 492 if err != nil { 493 return nil, err 494 } 495 496 ny, _, err := types.Float64.Convert(yy) 497 if err != nil { 498 return nil, err 499 } 500 501 return math.Atan2(ny.(float64), nx.(float64)), nil 502 } 503 504 // Children implements sql.Expression 505 func (a *Atan) Children() []sql.Expression { 506 if a.x == nil { 507 return []sql.Expression{a.y} 508 } 509 return []sql.Expression{a.y, a.x} 510 } 511 512 // WithChildren implements sql.Expression 513 func (a *Atan) WithChildren(children ...sql.Expression) (sql.Expression, error) { 514 return NewAtan(children...) 515 } 516 517 type Cot struct { 518 *UnaryFunc 519 } 520 521 var _ sql.FunctionExpression = (*Cot)(nil) 522 var _ sql.CollationCoercible = (*Cot)(nil) 523 524 // NewCot returns a new COT function expression 525 func NewCot(arg sql.Expression) sql.Expression { 526 return &Cot{NewUnaryFunc(arg, "COT", types.Float64)} 527 } 528 529 // Description implements sql.FunctionExpression 530 func (c *Cot) Description() string { 531 return "returns the arctangent of an expression." 532 } 533 534 // CollationCoercibility implements the interface sql.CollationCoercible. 535 func (*Cot) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 536 return sql.Collation_binary, 5 537 } 538 539 // Eval implements sql.Expression 540 func (c *Cot) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 541 val, err := c.EvalChild(ctx, row) 542 if err != nil { 543 return nil, err 544 } 545 546 if val == nil { 547 return nil, nil 548 } 549 550 n, _, err := types.Float64.Convert(val) 551 if err != nil { 552 return nil, err 553 } 554 555 tan := math.Tan(n.(float64)) 556 if math.IsNaN(tan) { 557 return nil, nil 558 } 559 560 res := 1.0 / tan 561 if math.IsInf(res, 0) { 562 return nil, sql.ErrValueOutOfRange.New("DOUBLE", c.Name) 563 } 564 565 return res, nil 566 } 567 568 // WithChildren implements sql.Expression 569 func (c *Cot) WithChildren(children ...sql.Expression) (sql.Expression, error) { 570 if len(children) != 1 { 571 return nil, sql.ErrInvalidChildrenNumber.New(c, len(children), 1) 572 } 573 return NewCot(children[0]), nil 574 } 575 576 type Degrees struct { 577 *UnaryFunc 578 } 579 580 var _ sql.FunctionExpression = (*Degrees)(nil) 581 var _ sql.CollationCoercible = (*Degrees)(nil) 582 583 // NewDegrees returns a new DEGREES function expression 584 func NewDegrees(arg sql.Expression) sql.Expression { 585 return &Degrees{NewUnaryFunc(arg, "DEGREES", types.Float64)} 586 } 587 588 // FunctionName implements sql.FunctionExpression 589 func (d *Degrees) FunctionName() string { 590 return "degrees" 591 } 592 593 // Description implements sql.FunctionExpression 594 func (d *Degrees) Description() string { 595 return "returns the number of degrees in the radian expression given." 596 } 597 598 // CollationCoercibility implements the interface sql.CollationCoercible. 599 func (*Degrees) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 600 return sql.Collation_binary, 5 601 } 602 603 // Eval implements sql.Expression 604 func (d *Degrees) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 605 val, err := d.EvalChild(ctx, row) 606 if err != nil { 607 return nil, err 608 } 609 610 if val == nil { 611 return nil, nil 612 } 613 614 n, _, err := types.Float64.Convert(val) 615 if err != nil { 616 return nil, err 617 } 618 619 return (n.(float64) * 180.0) / math.Pi, nil 620 } 621 622 // WithChildren implements sql.Expression 623 func (d *Degrees) WithChildren(children ...sql.Expression) (sql.Expression, error) { 624 if len(children) != 1 { 625 return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1) 626 } 627 return NewDegrees(children[0]), nil 628 } 629 630 type Radians struct { 631 *UnaryFunc 632 } 633 634 var _ sql.FunctionExpression = (*Radians)(nil) 635 var _ sql.CollationCoercible = (*Radians)(nil) 636 637 // NewRadians returns a new RADIANS function expression 638 func NewRadians(arg sql.Expression) sql.Expression { 639 return &Radians{NewUnaryFunc(arg, "RADIANS", types.Float64)} 640 } 641 642 // Description implements sql.FunctionExpression 643 func (r *Radians) Description() string { 644 return "returns the radian value of the degrees argument given." 645 } 646 647 // CollationCoercibility implements the interface sql.CollationCoercible. 648 func (*Radians) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 649 return sql.Collation_binary, 5 650 } 651 652 // Eval implements sql.Expression 653 func (r *Radians) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 654 val, err := r.EvalChild(ctx, row) 655 if err != nil { 656 return nil, err 657 } 658 659 if val == nil { 660 return nil, nil 661 } 662 663 n, _, err := types.Float64.Convert(val) 664 if err != nil { 665 return nil, err 666 } 667 668 return (n.(float64) * math.Pi) / 180.0, nil 669 } 670 671 // WithChildren implements sql.Expression 672 func (r *Radians) WithChildren(children ...sql.Expression) (sql.Expression, error) { 673 if len(children) != 1 { 674 return nil, sql.ErrInvalidChildrenNumber.New(r, len(children), 1) 675 } 676 return NewRadians(children[0]), nil 677 } 678 679 type Crc32 struct { 680 *UnaryFunc 681 } 682 683 var _ sql.FunctionExpression = (*Crc32)(nil) 684 var _ sql.CollationCoercible = (*Crc32)(nil) 685 686 // NewCrc32 returns a new CRC32 function expression 687 func NewCrc32(arg sql.Expression) sql.Expression { 688 return &Crc32{NewUnaryFunc(arg, "CRC32", types.Uint32)} 689 } 690 691 // Description implements sql.FunctionExpression 692 func (c *Crc32) Description() string { 693 return "returns the cyclic redundancy check value of a given string as a 32-bit unsigned value." 694 } 695 696 // CollationCoercibility implements the interface sql.CollationCoercible. 697 func (*Crc32) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 698 return sql.Collation_binary, 5 699 } 700 701 // Eval implements sql.Expression 702 func (c *Crc32) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 703 arg, err := c.EvalChild(ctx, row) 704 if err != nil { 705 return nil, err 706 } 707 708 if arg == nil { 709 return nil, nil 710 } 711 712 var bytes []byte 713 switch val := arg.(type) { 714 case string: 715 bytes = []byte(val) 716 case int8, int16, int32, int64, int: 717 val, _, err := types.Int64.Convert(arg) 718 719 if err != nil { 720 return nil, err 721 } 722 723 bytes = []byte(strconv.FormatInt(val.(int64), 10)) 724 case uint8, uint16, uint32, uint64, uint: 725 val, _, err := types.Uint64.Convert(arg) 726 727 if err != nil { 728 return nil, err 729 } 730 731 bytes = []byte(strconv.FormatUint(val.(uint64), 10)) 732 case float32: 733 s := floatToString(float64(val)) 734 bytes = []byte(s) 735 case float64: 736 s := floatToString(val) 737 bytes = []byte(s) 738 case bool: 739 if val { 740 bytes = []byte{1} 741 } else { 742 bytes = []byte{0} 743 } 744 default: 745 return nil, sql.ErrInvalidArgumentDetails.New("crc32", fmt.Sprint(arg)) 746 } 747 748 return crc32.ChecksumIEEE(bytes), nil 749 } 750 751 // WithChildren implements sql.Expression 752 func (c *Crc32) WithChildren(children ...sql.Expression) (sql.Expression, error) { 753 if len(children) != 1 { 754 return nil, sql.ErrInvalidChildrenNumber.New(c, len(children), 1) 755 } 756 return NewCrc32(children[0]), nil 757 } 758 759 func floatToString(f float64) string { 760 s := strconv.FormatFloat(f, 'f', -1, 32) 761 idx := strings.IndexRune(s, '.') 762 763 if idx == -1 { 764 s += ".0" 765 } 766 767 return s 768 } 769 770 type Sign struct { 771 *UnaryFunc 772 } 773 774 var _ sql.FunctionExpression = (*Sign)(nil) 775 var _ sql.CollationCoercible = (*Sign)(nil) 776 777 // NewSign returns a new SIGN function expression 778 func NewSign(arg sql.Expression) sql.Expression { 779 return &Sign{NewUnaryFunc(arg, "SIGN", types.Int8)} 780 } 781 782 var negativeSignRegex = regexp.MustCompile(`^-[0-9]*\.?[0-9]*[1-9]`) 783 var positiveSignRegex = regexp.MustCompile(`^+?[0-9]*\.?[0-9]*[1-9]`) 784 785 // Description implements sql.FunctionExpression 786 func (s *Sign) Description() string { 787 return "returns the sign of the argument." 788 } 789 790 // CollationCoercibility implements the interface sql.CollationCoercible. 791 func (*Sign) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 792 return sql.Collation_binary, 5 793 } 794 795 // Eval implements sql.Expression 796 func (s *Sign) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 797 arg, err := s.EvalChild(ctx, row) 798 if err != nil { 799 return nil, err 800 } 801 802 if arg == nil { 803 return nil, nil 804 } 805 806 switch typedVal := arg.(type) { 807 case int8, int16, int32, int64, float64, float32, int, decimal.Decimal: 808 val, _, err := types.Int64.Convert(arg) 809 810 if err != nil { 811 return nil, err 812 } 813 814 n := val.(int64) 815 if n == 0 { 816 return int8(0), nil 817 } else if n < 0 { 818 return int8(-1), nil 819 } 820 821 return int8(1), nil 822 823 case uint8, uint16, uint32, uint64, uint: 824 val, _, err := types.Uint64.Convert(arg) 825 826 if err != nil { 827 return nil, err 828 } 829 830 n := val.(uint64) 831 if n == 0 { 832 return int8(0), nil 833 } 834 835 return int8(1), nil 836 837 case bool: 838 if typedVal { 839 return int8(1), nil 840 } 841 842 return int8(0), nil 843 844 case time.Time: 845 return int8(1), nil 846 847 case string: 848 if negativeSignRegex.MatchString(typedVal) { 849 return int8(-1), nil 850 } else if positiveSignRegex.MatchString(typedVal) { 851 return int8(1), nil 852 } 853 854 return int8(0), nil 855 } 856 857 return int8(0), nil 858 } 859 860 // WithChildren implements sql.Expression 861 func (s *Sign) WithChildren(children ...sql.Expression) (sql.Expression, error) { 862 if len(children) != 1 { 863 return nil, sql.ErrInvalidChildrenNumber.New(s, len(children), 1) 864 } 865 return NewSign(children[0]), nil 866 } 867 868 // NewMod returns a new MOD function expression 869 func NewMod(args ...sql.Expression) (sql.Expression, error) { 870 if len(args) != 2 { 871 return nil, sql.ErrInvalidArgumentNumber.New("mod", "2", len(args)) 872 } 873 874 return expression.NewMod(args[0], args[1]), nil 875 } 876 877 type Pi struct{} 878 879 func NewPi() sql.Expression { 880 return &Pi{} 881 } 882 883 var _ sql.FunctionExpression = &Pi{} 884 var _ sql.CollationCoercible = &Pi{} 885 886 // FunctionName implements sql.FunctionExpression 887 func (p *Pi) FunctionName() string { 888 return "pi" 889 } 890 891 // Description implements sql.FunctionExpression 892 func (p *Pi) Description() string { 893 return "return the value of pi." 894 } 895 896 // Resolved implements sql.Expression 897 func (p *Pi) Resolved() bool { 898 return true 899 } 900 901 // String implements sql.Expression 902 func (p *Pi) String() string { 903 return fmt.Sprintf("%s()", p.FunctionName()) 904 } 905 906 // Type implements sql.Expression 907 func (p *Pi) Type() sql.Type { 908 return types.Float64 909 } 910 911 // CollationCoercibility implements the interface sql.CollationCoercible. 912 func (p *Pi) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 913 return sql.Collation_binary, 5 914 } 915 916 // IsNullable implements sql.Expression 917 func (p *Pi) IsNullable() bool { 918 return false 919 } 920 921 // Eval implements sql.Expression 922 func (p *Pi) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 923 return math.Pi, nil 924 } 925 926 // Children implements sql.Expression 927 func (p *Pi) Children() []sql.Expression { 928 return nil 929 } 930 931 // WithChildren implements sql.Expression 932 func (p *Pi) WithChildren(children ...sql.Expression) (sql.Expression, error) { 933 return sql.NillaryWithChildren(p, children...) 934 } 935 936 type Exp struct { 937 *UnaryFunc 938 } 939 940 func NewExp(arg sql.Expression) sql.Expression { 941 return &Exp{NewUnaryFunc(arg, "EXP", types.Float64)} 942 } 943 944 var _ sql.FunctionExpression = (*Exp)(nil) 945 var _ sql.CollationCoercible = (*Exp)(nil) 946 947 // Description implements sql.FunctionExpression 948 func (e *Exp) Description() string { 949 return "returns e raised to the power of the argument given." 950 } 951 952 // Type implements the Expression interface. 953 func (e *Exp) Type() sql.Type { 954 return types.Float64 955 } 956 957 // CollationCoercibility implements the interface sql.CollationCoercible. 958 func (e *Exp) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 959 return sql.Collation_binary, 5 960 } 961 962 // Eval implements the Expression interface. 963 func (e *Exp) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { 964 if e.Child == nil { 965 return nil, nil 966 } 967 968 val, err := e.Child.Eval(ctx, row) 969 if err != nil { 970 return nil, err 971 } 972 973 if val == nil { 974 return nil, err 975 } 976 977 v, _, err := types.Float64.Convert(val) 978 if err != nil { 979 // TODO: truncate 980 ctx.Warn(1292, "Truncated incorrect DOUBLE value: '%v'", val) 981 v = 0.0 982 } 983 984 vv := v.(float64) 985 res := math.Exp(vv) 986 987 if math.IsNaN(res) || math.IsInf(res, 0) { 988 return nil, nil 989 } 990 991 return res, nil 992 } 993 994 // WithChildren implements the Expression interface. 995 func (e *Exp) WithChildren(children ...sql.Expression) (sql.Expression, error) { 996 if len(children) != 1 { 997 return nil, sql.ErrInvalidChildrenNumber.New(e, len(children), 1) 998 } 999 return NewExp(children[0]), nil 1000 }