storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/s3select/sql/value.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2019 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package sql 18 19 import ( 20 "encoding/json" 21 "errors" 22 "fmt" 23 "math" 24 "reflect" 25 "strconv" 26 "strings" 27 "time" 28 "unicode/utf8" 29 ) 30 31 var ( 32 errArithMismatchedTypes = errors.New("cannot perform arithmetic on mismatched types") 33 errArithInvalidOperator = errors.New("invalid arithmetic operator") 34 errArithDivideByZero = errors.New("cannot divide by 0") 35 36 errCmpMismatchedTypes = errors.New("cannot compare values of different types") 37 errCmpInvalidBoolOperator = errors.New("invalid comparison operator for boolean arguments") 38 ) 39 40 // Value represents a value of restricted type reduced from an 41 // expression represented by an ASTNode. Only one of the fields is 42 // non-nil. 43 // 44 // In cases where we are fetching data from a data source (like csv), 45 // the type may not be determined yet. In these cases, a byte-slice is 46 // used. 47 type Value struct { 48 value interface{} 49 } 50 51 // MarshalJSON provides json marshaling of values. 52 func (v Value) MarshalJSON() ([]byte, error) { 53 if b, ok := v.ToBytes(); ok { 54 return b, nil 55 } 56 return json.Marshal(v.value) 57 } 58 59 // GetTypeString returns a string representation for vType 60 func (v Value) GetTypeString() string { 61 switch v.value.(type) { 62 case nil: 63 return "NULL" 64 case bool: 65 return "BOOL" 66 case string: 67 return "STRING" 68 case int64: 69 return "INT" 70 case float64: 71 return "FLOAT" 72 case time.Time: 73 return "TIMESTAMP" 74 case []byte: 75 return "BYTES" 76 case []Value: 77 return "ARRAY" 78 } 79 return "--" 80 } 81 82 // Repr returns a string representation of value. 83 func (v Value) Repr() string { 84 switch x := v.value.(type) { 85 case nil: 86 return ":NULL" 87 case bool, int64, float64: 88 return fmt.Sprintf("%v:%s", v.value, v.GetTypeString()) 89 case time.Time: 90 return fmt.Sprintf("%s:TIMESTAMP", x) 91 case string: 92 return fmt.Sprintf("\"%s\":%s", x, v.GetTypeString()) 93 case []byte: 94 return fmt.Sprintf("\"%s\":BYTES", string(x)) 95 case []Value: 96 var s strings.Builder 97 s.WriteByte('[') 98 for i, v := range x { 99 s.WriteString(v.Repr()) 100 if i < len(x)-1 { 101 s.WriteByte(',') 102 } 103 } 104 s.WriteString("]:ARRAY") 105 return s.String() 106 default: 107 return fmt.Sprintf("%v:INVALID", v.value) 108 } 109 } 110 111 // FromFloat creates a Value from a number 112 func FromFloat(f float64) *Value { 113 return &Value{value: f} 114 } 115 116 // FromInt creates a Value from an int 117 func FromInt(f int64) *Value { 118 return &Value{value: f} 119 } 120 121 // FromString creates a Value from a string 122 func FromString(str string) *Value { 123 return &Value{value: str} 124 } 125 126 // FromBool creates a Value from a bool 127 func FromBool(b bool) *Value { 128 return &Value{value: b} 129 } 130 131 // FromTimestamp creates a Value from a timestamp 132 func FromTimestamp(t time.Time) *Value { 133 return &Value{value: t} 134 } 135 136 // FromNull creates a Value with Null value 137 func FromNull() *Value { 138 return &Value{value: nil} 139 } 140 141 // FromBytes creates a Value from a []byte 142 func FromBytes(b []byte) *Value { 143 return &Value{value: b} 144 } 145 146 // FromArray creates a Value from an array of values. 147 func FromArray(a []Value) *Value { 148 return &Value{value: a} 149 } 150 151 // ToFloat works for int and float values 152 func (v Value) ToFloat() (val float64, ok bool) { 153 switch x := v.value.(type) { 154 case float64: 155 return x, true 156 case int64: 157 return float64(x), true 158 } 159 return 0, false 160 } 161 162 // ToInt returns the value if int. 163 func (v Value) ToInt() (val int64, ok bool) { 164 val, ok = v.value.(int64) 165 return 166 } 167 168 // ToString returns the value if string. 169 func (v Value) ToString() (val string, ok bool) { 170 val, ok = v.value.(string) 171 return 172 } 173 174 // Equals returns whether the values strictly match. 175 // Both type and value must match. 176 func (v Value) Equals(b Value) (ok bool) { 177 if !v.SameTypeAs(b) { 178 return false 179 } 180 return reflect.DeepEqual(v.value, b.value) 181 } 182 183 // SameTypeAs return whether the two types are strictly the same. 184 func (v Value) SameTypeAs(b Value) (ok bool) { 185 switch v.value.(type) { 186 case bool: 187 _, ok = b.value.(bool) 188 case string: 189 _, ok = b.value.(string) 190 case int64: 191 _, ok = b.value.(int64) 192 case float64: 193 _, ok = b.value.(float64) 194 case time.Time: 195 _, ok = b.value.(time.Time) 196 case []byte: 197 _, ok = b.value.([]byte) 198 case []Value: 199 _, ok = b.value.([]Value) 200 default: 201 ok = reflect.TypeOf(v.value) == reflect.TypeOf(b.value) 202 } 203 return ok 204 } 205 206 // ToBool returns the bool value; second return value refers to if the bool 207 // conversion succeeded. 208 func (v Value) ToBool() (val bool, ok bool) { 209 val, ok = v.value.(bool) 210 return 211 } 212 213 // ToTimestamp returns the timestamp value if present. 214 func (v Value) ToTimestamp() (t time.Time, ok bool) { 215 t, ok = v.value.(time.Time) 216 return 217 } 218 219 // ToBytes returns the value if byte-slice. 220 func (v Value) ToBytes() (val []byte, ok bool) { 221 val, ok = v.value.([]byte) 222 return 223 } 224 225 // ToArray returns the value if it is a slice of values. 226 func (v Value) ToArray() (val []Value, ok bool) { 227 val, ok = v.value.([]Value) 228 return 229 } 230 231 // IsNull - checks if value is missing. 232 func (v Value) IsNull() bool { 233 switch v.value.(type) { 234 case nil: 235 return true 236 } 237 return false 238 } 239 240 // IsArray returns whether the value is an array. 241 func (v Value) IsArray() (ok bool) { 242 _, ok = v.value.([]Value) 243 return ok 244 } 245 246 func (v Value) isNumeric() bool { 247 switch v.value.(type) { 248 case int64, float64: 249 return true 250 } 251 return false 252 } 253 254 // setters used internally to mutate values 255 256 func (v *Value) setInt(i int64) { 257 v.value = i 258 } 259 260 func (v *Value) setFloat(f float64) { 261 v.value = f 262 } 263 264 func (v *Value) setString(s string) { 265 v.value = s 266 } 267 268 func (v *Value) setBool(b bool) { 269 v.value = b 270 } 271 272 func (v *Value) setTimestamp(t time.Time) { 273 v.value = t 274 } 275 276 func (v Value) String() string { 277 return fmt.Sprintf("%#v", v.value) 278 } 279 280 // CSVString - convert to string for CSV serialization 281 func (v Value) CSVString() string { 282 switch x := v.value.(type) { 283 case nil: 284 return "" 285 case bool: 286 if x { 287 return "true" 288 } 289 return "false" 290 case string: 291 return x 292 case int64: 293 return strconv.FormatInt(x, 10) 294 case float64: 295 return strconv.FormatFloat(x, 'g', -1, 64) 296 case time.Time: 297 return FormatSQLTimestamp(x) 298 case []byte: 299 return string(x) 300 case []Value: 301 b, _ := json.Marshal(x) 302 return string(b) 303 304 default: 305 return "CSV serialization not implemented for this type" 306 } 307 } 308 309 // negate negates a numeric value 310 func (v *Value) negate() { 311 switch x := v.value.(type) { 312 case float64: 313 v.value = -x 314 case int64: 315 v.value = -x 316 } 317 } 318 319 // Value comparison functions: we do not expose them outside the 320 // module. Logical operators "<", ">", ">=", "<=" work on strings and 321 // numbers. Equality operators "=", "!=" work on strings, 322 // numbers and booleans. 323 324 // Supported comparison operators 325 const ( 326 opLt = "<" 327 opLte = "<=" 328 opGt = ">" 329 opGte = ">=" 330 opEq = "=" 331 opIneq = "!=" 332 ) 333 334 // InferBytesType will attempt to infer the data type of bytes. 335 // Will fail if value type is not bytes or it would result in invalid utf8. 336 // ORDER: int, float, bool, JSON (object or array), timestamp, string 337 // If the content is valid JSON, the type will still be bytes. 338 func (v *Value) InferBytesType() (err error) { 339 b, ok := v.ToBytes() 340 if !ok { 341 return fmt.Errorf("InferByteType: Input is not bytes, but %v", v.GetTypeString()) 342 } 343 344 // Check for numeric inference 345 if x, ok := v.bytesToInt(); ok { 346 v.setInt(x) 347 return nil 348 } 349 if x, ok := v.bytesToFloat(); ok { 350 v.setFloat(x) 351 return nil 352 } 353 if x, ok := v.bytesToBool(); ok { 354 v.setBool(x) 355 return nil 356 } 357 358 asString := strings.TrimSpace(v.bytesToString()) 359 if len(b) > 0 && 360 (strings.HasPrefix(asString, "{") || strings.HasPrefix(asString, "[")) { 361 return nil 362 } 363 364 if t, err := parseSQLTimestamp(asString); err == nil { 365 v.setTimestamp(t) 366 return nil 367 } 368 if !utf8.Valid(b) { 369 return errors.New("value is not valid utf-8") 370 } 371 // Fallback to string 372 v.setString(asString) 373 return 374 } 375 376 // When numeric types are compared, type promotions could happen. If 377 // values do not have types (e.g. when reading from CSV), for 378 // comparison operations, automatic type conversion happens by trying 379 // to check if the value is a number (first an integer, then a float), 380 // and falling back to string. 381 func (v *Value) compareOp(op string, a *Value) (res bool, err error) { 382 if !isValidComparisonOperator(op) { 383 return false, errArithInvalidOperator 384 } 385 386 // Check if type conversion/inference is needed - it is needed 387 // if the Value is a byte-slice. 388 err = inferTypesForCmp(v, a) 389 if err != nil { 390 return false, err 391 } 392 393 // Check if either is nil 394 if v.IsNull() || a.IsNull() { 395 // If one is, both must be. 396 return boolCompare(op, v.IsNull(), a.IsNull()) 397 } 398 399 // Check array values 400 aArr, aOK := a.ToArray() 401 vArr, vOK := v.ToArray() 402 if aOK && vOK { 403 return arrayCompare(op, aArr, vArr) 404 } 405 406 isNumeric := v.isNumeric() && a.isNumeric() 407 if isNumeric { 408 intV, ok1i := v.ToInt() 409 intA, ok2i := a.ToInt() 410 if ok1i && ok2i { 411 return intCompare(op, intV, intA), nil 412 } 413 414 // If both values are numeric, then at least one is 415 // float since we got here, so we convert. 416 flV, _ := v.ToFloat() 417 flA, _ := a.ToFloat() 418 return floatCompare(op, flV, flA), nil 419 } 420 421 strV, ok1s := v.ToString() 422 strA, ok2s := a.ToString() 423 if ok1s && ok2s { 424 return stringCompare(op, strV, strA), nil 425 } 426 427 boolV, ok1b := v.ToBool() 428 boolA, ok2b := a.ToBool() 429 if ok1b && ok2b { 430 return boolCompare(op, boolV, boolA) 431 } 432 433 timestampV, ok1t := v.ToTimestamp() 434 timestampA, ok2t := a.ToTimestamp() 435 if ok1t && ok2t { 436 return timestampCompare(op, timestampV, timestampA), nil 437 } 438 439 // Types cannot be compared, they do not match. 440 switch op { 441 case opEq: 442 return false, nil 443 case opIneq: 444 return true, nil 445 } 446 return false, errCmpInvalidBoolOperator 447 } 448 449 func inferTypesForCmp(a *Value, b *Value) error { 450 _, okA := a.ToBytes() 451 _, okB := b.ToBytes() 452 switch { 453 case !okA && !okB: 454 // Both Values already have types 455 return nil 456 457 case okA && okB: 458 // Both Values are untyped so try the types in order: 459 // int, float, bool, string 460 461 // Check for numeric inference 462 iA, okAi := a.bytesToInt() 463 iB, okBi := b.bytesToInt() 464 if okAi && okBi { 465 a.setInt(iA) 466 b.setInt(iB) 467 return nil 468 } 469 470 fA, okAf := a.bytesToFloat() 471 fB, okBf := b.bytesToFloat() 472 if okAf && okBf { 473 a.setFloat(fA) 474 b.setFloat(fB) 475 return nil 476 } 477 478 // Check if they int and float combination. 479 if okAi && okBf { 480 a.setInt(iA) 481 b.setFloat(fA) 482 return nil 483 } 484 if okBi && okAf { 485 a.setFloat(fA) 486 b.setInt(iB) 487 return nil 488 } 489 490 // Not numeric types at this point. 491 492 // Check for bool inference 493 bA, okAb := a.bytesToBool() 494 bB, okBb := b.bytesToBool() 495 if okAb && okBb { 496 a.setBool(bA) 497 b.setBool(bB) 498 return nil 499 } 500 501 // Fallback to string 502 sA := a.bytesToString() 503 sB := b.bytesToString() 504 a.setString(sA) 505 b.setString(sB) 506 return nil 507 508 case okA && !okB: 509 // Here a has `a` is untyped, but `b` has a fixed 510 // type. 511 switch b.value.(type) { 512 case string: 513 s := a.bytesToString() 514 a.setString(s) 515 516 case int64, float64: 517 if iA, ok := a.bytesToInt(); ok { 518 a.setInt(iA) 519 } else if fA, ok := a.bytesToFloat(); ok { 520 a.setFloat(fA) 521 } else { 522 return fmt.Errorf("Could not convert %s to a number", a.String()) 523 } 524 525 case bool: 526 if bA, ok := a.bytesToBool(); ok { 527 a.setBool(bA) 528 } else { 529 return fmt.Errorf("Could not convert %s to a boolean", a.String()) 530 } 531 532 default: 533 return errCmpMismatchedTypes 534 } 535 return nil 536 537 case !okA && okB: 538 // swap arguments to avoid repeating code 539 return inferTypesForCmp(b, a) 540 541 default: 542 // Does not happen 543 return nil 544 } 545 } 546 547 // Value arithmetic functions: we do not expose them outside the 548 // module. All arithmetic works only on numeric values with automatic 549 // promotion to the "larger" type that can represent the value. TODO: 550 // Add support for large number arithmetic. 551 552 // Supported arithmetic operators 553 const ( 554 opPlus = "+" 555 opMinus = "-" 556 opDivide = "/" 557 opMultiply = "*" 558 opModulo = "%" 559 ) 560 561 // For arithmetic operations, if both values are numeric then the 562 // operation shall succeed. If the types are unknown automatic type 563 // conversion to a number is attempted. 564 func (v *Value) arithOp(op string, a *Value) error { 565 err := inferTypeForArithOp(v) 566 if err != nil { 567 return err 568 } 569 570 err = inferTypeForArithOp(a) 571 if err != nil { 572 return err 573 } 574 575 if !v.isNumeric() || !a.isNumeric() { 576 return errInvalidDataType(errArithMismatchedTypes) 577 } 578 579 if !isValidArithOperator(op) { 580 return errInvalidDataType(errArithMismatchedTypes) 581 } 582 583 intV, ok1i := v.ToInt() 584 intA, ok2i := a.ToInt() 585 switch { 586 case ok1i && ok2i: 587 res, err := intArithOp(op, intV, intA) 588 v.setInt(res) 589 return err 590 591 default: 592 // Convert arguments to float 593 flV, _ := v.ToFloat() 594 flA, _ := a.ToFloat() 595 res, err := floatArithOp(op, flV, flA) 596 v.setFloat(res) 597 return err 598 } 599 } 600 601 func inferTypeForArithOp(a *Value) error { 602 if _, ok := a.ToBytes(); !ok { 603 return nil 604 } 605 606 if i, ok := a.bytesToInt(); ok { 607 a.setInt(i) 608 return nil 609 } 610 611 if f, ok := a.bytesToFloat(); ok { 612 a.setFloat(f) 613 return nil 614 } 615 616 err := fmt.Errorf("Could not convert %q to a number", string(a.value.([]byte))) 617 return errInvalidDataType(err) 618 } 619 620 // All the bytesTo* functions defined below assume the value is a byte-slice. 621 622 // Converts untyped value into int. The bool return implies success - 623 // it returns false only if there is a conversion failure. 624 func (v Value) bytesToInt() (int64, bool) { 625 bytes, _ := v.ToBytes() 626 i, err := strconv.ParseInt(strings.TrimSpace(string(bytes)), 10, 64) 627 return i, err == nil 628 } 629 630 // Converts untyped value into float. The bool return implies success 631 // - it returns false only if there is a conversion failure. 632 func (v Value) bytesToFloat() (float64, bool) { 633 bytes, _ := v.ToBytes() 634 i, err := strconv.ParseFloat(strings.TrimSpace(string(bytes)), 64) 635 return i, err == nil 636 } 637 638 // Converts untyped value into bool. The second bool return implies 639 // success - it returns false in case of a conversion failure. 640 func (v Value) bytesToBool() (val bool, ok bool) { 641 bytes, _ := v.ToBytes() 642 ok = true 643 switch strings.ToLower(strings.TrimSpace(string(bytes))) { 644 case "t", "true", "1": 645 val = true 646 case "f", "false", "0": 647 val = false 648 default: 649 ok = false 650 } 651 return val, ok 652 } 653 654 // bytesToString - never fails, but returns empty string if value is not bytes. 655 func (v Value) bytesToString() string { 656 bytes, _ := v.ToBytes() 657 return string(bytes) 658 } 659 660 // Calculates minimum or maximum of v and a and assigns the result to 661 // v - it works only on numeric arguments, where `v` is already 662 // assumed to be numeric. Attempts conversion to numeric type for `a` 663 // (first int, then float) only if the underlying values do not have a 664 // type. 665 func (v *Value) minmax(a *Value, isMax, isFirstRow bool) error { 666 err := inferTypeForArithOp(a) 667 if err != nil { 668 return err 669 } 670 671 if !a.isNumeric() { 672 return errArithMismatchedTypes 673 } 674 675 // In case of first row, set v to a. 676 if isFirstRow { 677 intA, okI := a.ToInt() 678 if okI { 679 v.setInt(intA) 680 return nil 681 } 682 floatA, _ := a.ToFloat() 683 v.setFloat(floatA) 684 return nil 685 } 686 687 intV, ok1i := v.ToInt() 688 intA, ok2i := a.ToInt() 689 if ok1i && ok2i { 690 result := intV 691 if !isMax { 692 if intA < result { 693 result = intA 694 } 695 } else { 696 if intA > result { 697 result = intA 698 } 699 } 700 v.setInt(result) 701 return nil 702 } 703 704 floatV, _ := v.ToFloat() 705 floatA, _ := a.ToFloat() 706 var result float64 707 if !isMax { 708 result = math.Min(floatV, floatA) 709 } else { 710 result = math.Max(floatV, floatA) 711 } 712 v.setFloat(result) 713 return nil 714 } 715 716 func inferTypeAsTimestamp(v *Value) error { 717 if s, ok := v.ToString(); ok { 718 t, err := parseSQLTimestamp(s) 719 if err != nil { 720 return err 721 } 722 v.setTimestamp(t) 723 } else if b, ok := v.ToBytes(); ok { 724 s := string(b) 725 t, err := parseSQLTimestamp(s) 726 if err != nil { 727 return err 728 } 729 v.setTimestamp(t) 730 } 731 return nil 732 } 733 734 // inferTypeAsString is used to convert untyped values to string - it 735 // is called when the caller requires a string context to proceed. 736 func inferTypeAsString(v *Value) { 737 b, ok := v.ToBytes() 738 if !ok { 739 return 740 } 741 742 v.setString(string(b)) 743 } 744 745 func isValidComparisonOperator(op string) bool { 746 switch op { 747 case opLt: 748 case opLte: 749 case opGt: 750 case opGte: 751 case opEq: 752 case opIneq: 753 default: 754 return false 755 } 756 return true 757 } 758 759 func intCompare(op string, left, right int64) bool { 760 switch op { 761 case opLt: 762 return left < right 763 case opLte: 764 return left <= right 765 case opGt: 766 return left > right 767 case opGte: 768 return left >= right 769 case opEq: 770 return left == right 771 case opIneq: 772 return left != right 773 } 774 // This case does not happen 775 return false 776 } 777 778 func floatCompare(op string, left, right float64) bool { 779 diff := math.Abs(left - right) 780 switch op { 781 case opLt: 782 return left < right 783 case opLte: 784 return left <= right 785 case opGt: 786 return left > right 787 case opGte: 788 return left >= right 789 case opEq: 790 return diff < floatCmpTolerance 791 case opIneq: 792 return diff > floatCmpTolerance 793 } 794 // This case does not happen 795 return false 796 } 797 798 func stringCompare(op string, left, right string) bool { 799 switch op { 800 case opLt: 801 return left < right 802 case opLte: 803 return left <= right 804 case opGt: 805 return left > right 806 case opGte: 807 return left >= right 808 case opEq: 809 return left == right 810 case opIneq: 811 return left != right 812 } 813 // This case does not happen 814 return false 815 } 816 817 func boolCompare(op string, left, right bool) (bool, error) { 818 switch op { 819 case opEq: 820 return left == right, nil 821 case opIneq: 822 return left != right, nil 823 default: 824 return false, errCmpInvalidBoolOperator 825 } 826 } 827 828 func arrayCompare(op string, left, right []Value) (bool, error) { 829 switch op { 830 case opEq: 831 if len(left) != len(right) { 832 return false, nil 833 } 834 for i, l := range left { 835 eq, err := l.compareOp(op, &right[i]) 836 if !eq || err != nil { 837 return eq, err 838 } 839 } 840 return true, nil 841 case opIneq: 842 for i, l := range left { 843 eq, err := l.compareOp(op, &right[i]) 844 if eq || err != nil { 845 return eq, err 846 } 847 } 848 return false, nil 849 default: 850 return false, errCmpInvalidBoolOperator 851 } 852 } 853 854 func timestampCompare(op string, left, right time.Time) bool { 855 switch op { 856 case opLt: 857 return left.Before(right) 858 case opLte: 859 return left.Before(right) || left.Equal(right) 860 case opGt: 861 return left.After(right) 862 case opGte: 863 return left.After(right) || left.Equal(right) 864 case opEq: 865 return left.Equal(right) 866 case opIneq: 867 return !left.Equal(right) 868 } 869 // This case does not happen 870 return false 871 } 872 873 func isValidArithOperator(op string) bool { 874 switch op { 875 case opPlus: 876 case opMinus: 877 case opDivide: 878 case opMultiply: 879 case opModulo: 880 default: 881 return false 882 } 883 return true 884 } 885 886 // Overflow errors are ignored. 887 func intArithOp(op string, left, right int64) (int64, error) { 888 switch op { 889 case opPlus: 890 return left + right, nil 891 case opMinus: 892 return left - right, nil 893 case opDivide: 894 if right == 0 { 895 return 0, errArithDivideByZero 896 } 897 return left / right, nil 898 case opMultiply: 899 return left * right, nil 900 case opModulo: 901 if right == 0 { 902 return 0, errArithDivideByZero 903 } 904 return left % right, nil 905 } 906 // This does not happen 907 return 0, nil 908 } 909 910 // Overflow errors are ignored. 911 func floatArithOp(op string, left, right float64) (float64, error) { 912 switch op { 913 case opPlus: 914 return left + right, nil 915 case opMinus: 916 return left - right, nil 917 case opDivide: 918 if right == 0 { 919 return 0, errArithDivideByZero 920 } 921 return left / right, nil 922 case opMultiply: 923 return left * right, nil 924 case opModulo: 925 if right == 0 { 926 return 0, errArithDivideByZero 927 } 928 return math.Mod(left, right), nil 929 } 930 // This does not happen 931 return 0, nil 932 }