github.com/dolthub/go-mysql-server@v0.18.0/sql/types/number.go (about) 1 // Copyright 2022 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 types 16 17 import ( 18 "encoding/hex" 19 "fmt" 20 "math" 21 "reflect" 22 "regexp" 23 "strconv" 24 "time" 25 26 "github.com/dolthub/vitess/go/sqltypes" 27 "github.com/dolthub/vitess/go/vt/proto/query" 28 "github.com/shopspring/decimal" 29 30 "github.com/dolthub/go-mysql-server/sql" 31 "github.com/dolthub/go-mysql-server/sql/values" 32 ) 33 34 var ( 35 // Boolean is a synonym for TINYINT(1) 36 Boolean = MustCreateNumberTypeWithDisplayWidth(sqltypes.Int8, 1) 37 // Int8 is an integer of 8 bits 38 Int8 = MustCreateNumberType(sqltypes.Int8) 39 // Uint8 is an unsigned integer of 8 bits 40 Uint8 = MustCreateNumberType(sqltypes.Uint8) 41 // Int16 is an integer of 16 bits 42 Int16 = MustCreateNumberType(sqltypes.Int16) 43 // Uint16 is an unsigned integer of 16 bits 44 Uint16 = MustCreateNumberType(sqltypes.Uint16) 45 // Int24 is an integer of 24 bits. 46 Int24 = MustCreateNumberType(sqltypes.Int24) 47 // Uint24 is an unsigned integer of 24 bits. 48 Uint24 = MustCreateNumberType(sqltypes.Uint24) 49 // Int32 is an integer of 32 bits. 50 Int32 = MustCreateNumberType(sqltypes.Int32) 51 // Uint32 is an unsigned integer of 32 bits. 52 Uint32 = MustCreateNumberType(sqltypes.Uint32) 53 // Int64 is an integer of 64 bytes. 54 Int64 = MustCreateNumberType(sqltypes.Int64) 55 // Uint64 is an unsigned integer of 64 bits. 56 Uint64 = MustCreateNumberType(sqltypes.Uint64) 57 // Float32 is a floating point number of 32 bits. 58 Float32 = MustCreateNumberType(sqltypes.Float32) 59 // Float64 is a floating point number of 64 bits. 60 Float64 = MustCreateNumberType(sqltypes.Float64) 61 62 // decimal that represents the max value an uint64 can hold 63 dec_uint64_max = decimal.NewFromInt(math.MaxInt64).Mul(decimal.NewFromInt(2).Add(decimal.NewFromInt(1))) 64 dec_uint32_max = decimal.NewFromInt(math.MaxInt32).Mul(decimal.NewFromInt(2).Add(decimal.NewFromInt(1))) 65 dec_uint16_max = decimal.NewFromInt(math.MaxInt16).Mul(decimal.NewFromInt(2).Add(decimal.NewFromInt(1))) 66 dec_uint8_max = decimal.NewFromInt(math.MaxInt8).Mul(decimal.NewFromInt(2).Add(decimal.NewFromInt(1))) 67 // decimal that represents the max value an int64 can hold 68 dec_int64_max = decimal.NewFromInt(math.MaxInt64) 69 // decimal that represents the min value an int64 can hold 70 dec_int64_min = decimal.NewFromInt(math.MinInt64) 71 // decimal that represents the zero value 72 dec_zero = decimal.NewFromInt(0) 73 74 numberInt8ValueType = reflect.TypeOf(int8(0)) 75 numberInt16ValueType = reflect.TypeOf(int16(0)) 76 numberInt32ValueType = reflect.TypeOf(int32(0)) 77 numberInt64ValueType = reflect.TypeOf(int64(0)) 78 numberUint8ValueType = reflect.TypeOf(uint8(0)) 79 numberUint16ValueType = reflect.TypeOf(uint16(0)) 80 numberUint32ValueType = reflect.TypeOf(uint32(0)) 81 numberUint64ValueType = reflect.TypeOf(uint64(0)) 82 numberFloat32ValueType = reflect.TypeOf(float32(0)) 83 numberFloat64ValueType = reflect.TypeOf(float64(0)) 84 85 numre = regexp.MustCompile(`^[ ]*[0-9]*\.?[0-9]+`) 86 ) 87 88 type NumberTypeImpl_ struct { 89 baseType query.Type 90 displayWidth int 91 } 92 93 var _ sql.Type = NumberTypeImpl_{} 94 var _ sql.Type2 = NumberTypeImpl_{} 95 var _ sql.CollationCoercible = NumberTypeImpl_{} 96 var _ sql.NumberType = NumberTypeImpl_{} 97 98 // CreateNumberType creates a NumberType. 99 func CreateNumberType(baseType query.Type) (sql.NumberType, error) { 100 return CreateNumberTypeWithDisplayWidth(baseType, 0) 101 } 102 103 // CreateNumberTypeWithDisplayWidth creates a NumberType that includes optional |displayWidth| metadata. Note that 104 // MySQL only allows a |displayWidth| of 1 for Int8 (i.e. TINYINT(1)); any other combination of |displayWidth| and 105 // |baseType| is not supported and will cause this function to return an error. 106 func CreateNumberTypeWithDisplayWidth(baseType query.Type, displayWidth int) (sql.NumberType, error) { 107 switch baseType { 108 case sqltypes.Int8, sqltypes.Uint8, sqltypes.Int16, sqltypes.Uint16, sqltypes.Int24, sqltypes.Uint24, 109 sqltypes.Int32, sqltypes.Uint32, sqltypes.Int64, sqltypes.Uint64, sqltypes.Float32, sqltypes.Float64: 110 111 // displayWidth of 0 is valid for all types, displayWidth of 1 is only valid for Int8 112 if displayWidth == 0 || (displayWidth == 1 && baseType == sqltypes.Int8) { 113 return NumberTypeImpl_{ 114 baseType: baseType, 115 displayWidth: displayWidth, 116 }, nil 117 } 118 return nil, fmt.Errorf("display width of %d is not valid for type %s", displayWidth, baseType.String()) 119 } 120 return nil, fmt.Errorf("%v is not a valid number base type", baseType.String()) 121 } 122 123 // MustCreateNumberType is the same as CreateNumberType except it panics on errors. 124 func MustCreateNumberType(baseType query.Type) sql.NumberType { 125 nt, err := CreateNumberType(baseType) 126 if err != nil { 127 panic(err) 128 } 129 return nt 130 } 131 132 // MustCreateNumberTypeWithDisplayWidth is the same as CreateNumberTypeWithDisplayWidth except it panics on errors. 133 func MustCreateNumberTypeWithDisplayWidth(baseType query.Type, displayWidth int) sql.NumberType { 134 nt, err := CreateNumberTypeWithDisplayWidth(baseType, displayWidth) 135 if err != nil { 136 panic(err) 137 } 138 return nt 139 } 140 141 func NumericUnaryValue(t sql.Type) interface{} { 142 nt := t.(NumberTypeImpl_) 143 switch nt.baseType { 144 case sqltypes.Int8: 145 return int8(1) 146 case sqltypes.Uint8: 147 return uint8(1) 148 case sqltypes.Int16: 149 return int16(1) 150 case sqltypes.Uint16: 151 return uint16(1) 152 case sqltypes.Int24: 153 return int32(1) 154 case sqltypes.Uint24: 155 return uint32(1) 156 case sqltypes.Int32: 157 return int32(1) 158 case sqltypes.Uint32: 159 return uint32(1) 160 case sqltypes.Int64: 161 return int64(1) 162 case sqltypes.Uint64: 163 return uint64(1) 164 case sqltypes.Float32: 165 return float32(1) 166 case sqltypes.Float64: 167 return float64(1) 168 default: 169 panic(fmt.Sprintf("%v is not a valid number base type", nt.baseType.String())) 170 } 171 } 172 173 // Compare implements Type interface. 174 func (t NumberTypeImpl_) Compare(a interface{}, b interface{}) (int, error) { 175 if hasNulls, res := CompareNulls(a, b); hasNulls { 176 return res, nil 177 } 178 179 switch t.baseType { 180 case sqltypes.Uint8, sqltypes.Uint16, sqltypes.Uint24, sqltypes.Uint32, sqltypes.Uint64: 181 ca, _, err := convertToUint64(t, a) 182 if err != nil { 183 return 0, err 184 } 185 cb, _, err := convertToUint64(t, b) 186 if err != nil { 187 return 0, err 188 } 189 190 if ca == cb { 191 return 0, nil 192 } 193 if ca < cb { 194 return -1, nil 195 } 196 return +1, nil 197 case sqltypes.Float32, sqltypes.Float64: 198 ca, err := convertToFloat64(t, a) 199 if err != nil { 200 return 0, err 201 } 202 cb, err := convertToFloat64(t, b) 203 if err != nil { 204 return 0, err 205 } 206 207 if ca == cb { 208 return 0, nil 209 } 210 if ca < cb { 211 return -1, nil 212 } 213 return +1, nil 214 default: 215 ca, _, err := convertToInt64(t, a) 216 if err != nil { 217 ca = 0 218 } 219 cb, _, err := convertToInt64(t, b) 220 if err != nil { 221 cb = 0 222 } 223 224 if ca == cb { 225 return 0, nil 226 } 227 if ca < cb { 228 return -1, nil 229 } 230 return +1, nil 231 } 232 } 233 234 // Convert implements Type interface. 235 func (t NumberTypeImpl_) Convert(v interface{}) (interface{}, sql.ConvertInRange, error) { 236 if v == nil { 237 return nil, sql.InRange, nil 238 } 239 240 if ti, ok := v.(time.Time); ok { 241 v = ti.UTC().Unix() 242 } 243 244 if jv, ok := v.(sql.JSONWrapper); ok { 245 v = jv.ToInterface() 246 } 247 248 switch t.baseType { 249 case sqltypes.Int8: 250 num, _, err := convertToInt64(t, v) 251 if err != nil { 252 return nil, sql.OutOfRange, err 253 } 254 if num > math.MaxInt8 { 255 return int8(math.MaxInt8), sql.OutOfRange, nil 256 } else if num < math.MinInt8 { 257 return int8(math.MinInt8), sql.OutOfRange, nil 258 } 259 return int8(num), sql.InRange, nil 260 case sqltypes.Uint8: 261 return convertToUint8(t, v) 262 case sqltypes.Int16: 263 num, _, err := convertToInt64(t, v) 264 if err != nil { 265 return nil, sql.OutOfRange, err 266 } 267 if num > math.MaxInt16 { 268 return int16(math.MaxInt16), sql.OutOfRange, nil 269 } else if num < math.MinInt16 { 270 return int16(math.MinInt16), sql.OutOfRange, nil 271 } 272 return int16(num), sql.InRange, nil 273 case sqltypes.Uint16: 274 return convertToUint16(t, v) 275 case sqltypes.Int24: 276 num, _, err := convertToInt64(t, v) 277 if err != nil { 278 return nil, sql.OutOfRange, err 279 } 280 if num > (1<<23 - 1) { 281 return int32(1<<23 - 1), sql.OutOfRange, nil 282 } else if num < (-1 << 23) { 283 return int32(-1 << 23), sql.OutOfRange, nil 284 } 285 return int32(num), sql.InRange, nil 286 case sqltypes.Uint24: 287 num, _, err := convertToInt64(t, v) 288 if err != nil { 289 return nil, sql.OutOfRange, err 290 } 291 if num >= (1 << 24) { 292 return uint32(1<<24 - 1), sql.OutOfRange, nil 293 } else if num < 0 { 294 return uint32(1<<24 - int32(-num)), sql.OutOfRange, nil 295 } 296 return uint32(num), sql.InRange, nil 297 case sqltypes.Int32: 298 num, _, err := convertToInt64(t, v) 299 if err != nil { 300 return nil, sql.OutOfRange, err 301 } 302 if num > math.MaxInt32 { 303 return int32(math.MaxInt32), sql.OutOfRange, nil 304 } else if num < math.MinInt32 { 305 return int32(math.MinInt32), sql.OutOfRange, nil 306 } 307 return int32(num), sql.InRange, nil 308 case sqltypes.Uint32: 309 return convertToUint32(t, v) 310 case sqltypes.Int64: 311 return convertToInt64(t, v) 312 case sqltypes.Uint64: 313 return convertToUint64(t, v) 314 case sqltypes.Float32: 315 num, err := convertToFloat64(t, v) 316 if err != nil { 317 return nil, sql.OutOfRange, err 318 } 319 if num > math.MaxFloat32 { 320 return float32(math.MaxFloat32), sql.OutOfRange, nil 321 } else if num < -math.MaxFloat32 { 322 return float32(-math.MaxFloat32), sql.OutOfRange, nil 323 } 324 return float32(num), sql.InRange, nil 325 case sqltypes.Float64: 326 ret, err := convertToFloat64(t, v) 327 return ret, sql.InRange, err 328 default: 329 return nil, sql.OutOfRange, sql.ErrInvalidType.New(t.baseType.String()) 330 } 331 } 332 333 // MaxTextResponseByteLength implements the Type interface 334 func (t NumberTypeImpl_) MaxTextResponseByteLength(_ *sql.Context) uint32 { 335 // MySQL integer type limits: https://dev.mysql.com/doc/refman/8.0/en/integer-types.html 336 // This is for a text response format, NOT a binary encoding 337 switch t.baseType { 338 case sqltypes.Uint8: 339 return 3 340 case sqltypes.Int8: 341 return 4 342 case sqltypes.Uint16: 343 return 5 344 case sqltypes.Int16: 345 return 6 346 case sqltypes.Uint24: 347 return 8 348 case sqltypes.Int24: 349 return 9 350 case sqltypes.Uint32: 351 return 10 352 case sqltypes.Int32: 353 return 11 354 case sqltypes.Uint64: 355 return 20 356 case sqltypes.Int64: 357 return 20 358 case sqltypes.Float32: 359 return 12 360 case sqltypes.Float64: 361 return 22 362 default: 363 panic(fmt.Sprintf("%v is not a valid number base type", t.baseType.String())) 364 } 365 } 366 367 // MustConvert implements the Type interface. 368 func (t NumberTypeImpl_) MustConvert(v interface{}) interface{} { 369 value, _, err := t.Convert(v) 370 if err != nil { 371 panic(err) 372 } 373 return value 374 } 375 376 // Equals implements the Type interface. 377 func (t NumberTypeImpl_) Equals(otherType sql.Type) bool { 378 return t.baseType == otherType.Type() 379 } 380 381 // Promote implements the Type interface. 382 func (t NumberTypeImpl_) Promote() sql.Type { 383 switch t.baseType { 384 case sqltypes.Int8, sqltypes.Int16, sqltypes.Int24, sqltypes.Int32, sqltypes.Int64: 385 return Int64 386 case sqltypes.Uint8, sqltypes.Uint16, sqltypes.Uint24, sqltypes.Uint32, sqltypes.Uint64: 387 return Uint64 388 case sqltypes.Float32, sqltypes.Float64: 389 return Float64 390 default: 391 panic(sql.ErrInvalidBaseType.New(t.baseType.String(), "number")) 392 } 393 } 394 395 // SQL implements Type interface. 396 func (t NumberTypeImpl_) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes.Value, error) { 397 if v == nil { 398 return sqltypes.NULL, nil 399 } 400 401 stop := len(dest) 402 if vt, _, err := t.Convert(v); err == nil { 403 switch t.baseType { 404 case sqltypes.Int8, sqltypes.Int16, sqltypes.Int24, sqltypes.Int32, sqltypes.Int64: 405 dest = strconv.AppendInt(dest, mustInt64(vt), 10) 406 case sqltypes.Uint8, sqltypes.Uint16, sqltypes.Uint24, sqltypes.Uint32, sqltypes.Uint64: 407 dest = strconv.AppendUint(dest, mustUint64(vt), 10) 408 case sqltypes.Float32: 409 dest = strconv.AppendFloat(dest, mustFloat64(vt), 'g', -1, 32) 410 case sqltypes.Float64: 411 dest = strconv.AppendFloat(dest, mustFloat64(vt), 'g', -1, 64) 412 default: 413 panic(sql.ErrInvalidBaseType.New(t.baseType.String(), "number")) 414 } 415 } else if sql.ErrInvalidValue.Is(err) { 416 switch str := v.(type) { 417 case []byte: 418 dest = str 419 case string: 420 dest = []byte(str) 421 default: 422 return sqltypes.Value{}, err 423 } 424 } else { 425 return sqltypes.Value{}, err 426 } 427 428 val := dest[stop:] 429 430 return sqltypes.MakeTrusted(t.baseType, val), nil 431 } 432 433 func (t NumberTypeImpl_) Compare2(a sql.Value, b sql.Value) (int, error) { 434 switch t.baseType { 435 case sqltypes.Uint8, sqltypes.Uint16, sqltypes.Uint24, sqltypes.Uint32, sqltypes.Uint64: 436 ca, err := convertValueToUint64(t, a) 437 if err != nil { 438 return 0, err 439 } 440 cb, err := convertValueToUint64(t, b) 441 if err != nil { 442 return 0, err 443 } 444 445 if ca == cb { 446 return 0, nil 447 } 448 if ca < cb { 449 return -1, nil 450 } 451 return +1, nil 452 case sqltypes.Float32, sqltypes.Float64: 453 ca, err := convertValueToFloat64(t, a) 454 if err != nil { 455 return 0, err 456 } 457 cb, err := convertValueToFloat64(t, b) 458 if err != nil { 459 return 0, err 460 } 461 462 if ca == cb { 463 return 0, nil 464 } 465 if ca < cb { 466 return -1, nil 467 } 468 return +1, nil 469 default: 470 ca, err := convertValueToInt64(t, a) 471 if err != nil { 472 return 0, err 473 } 474 cb, err := convertValueToInt64(t, b) 475 if err != nil { 476 return 0, err 477 } 478 479 if ca == cb { 480 return 0, nil 481 } 482 if ca < cb { 483 return -1, nil 484 } 485 return +1, nil 486 } 487 } 488 489 func (t NumberTypeImpl_) Convert2(value sql.Value) (sql.Value, error) { 490 panic("implement me") 491 } 492 493 func (t NumberTypeImpl_) Zero2() sql.Value { 494 switch t.baseType { 495 case sqltypes.Int8: 496 x := values.WriteInt8(make([]byte, values.Int8Size), 0) 497 return sql.Value{ 498 Typ: query.Type_INT8, 499 Val: x, 500 } 501 case sqltypes.Int16: 502 x := values.WriteInt16(make([]byte, values.Int16Size), 0) 503 return sql.Value{ 504 Typ: query.Type_INT16, 505 Val: x, 506 } 507 case sqltypes.Int24: 508 x := values.WriteInt24(make([]byte, values.Int24Size), 0) 509 return sql.Value{ 510 Typ: query.Type_INT24, 511 Val: x, 512 } 513 case sqltypes.Int32: 514 x := values.WriteInt32(make([]byte, values.Int32Size), 0) 515 return sql.Value{ 516 Typ: query.Type_INT32, 517 Val: x, 518 } 519 case sqltypes.Int64: 520 x := values.WriteInt64(make([]byte, values.Int64Size), 0) 521 return sql.Value{ 522 Typ: query.Type_INT64, 523 Val: x, 524 } 525 case sqltypes.Uint8: 526 x := values.WriteUint8(make([]byte, values.Uint8Size), 0) 527 return sql.Value{ 528 Typ: query.Type_UINT8, 529 Val: x, 530 } 531 case sqltypes.Uint16: 532 x := values.WriteUint16(make([]byte, values.Uint16Size), 0) 533 return sql.Value{ 534 Typ: query.Type_UINT16, 535 Val: x, 536 } 537 case sqltypes.Uint24: 538 x := values.WriteUint24(make([]byte, values.Uint24Size), 0) 539 return sql.Value{ 540 Typ: query.Type_UINT24, 541 Val: x, 542 } 543 case sqltypes.Uint32: 544 x := values.WriteUint32(make([]byte, values.Uint32Size), 0) 545 return sql.Value{ 546 Typ: query.Type_UINT32, 547 Val: x, 548 } 549 case sqltypes.Uint64: 550 x := values.WriteUint64(make([]byte, values.Uint64Size), 0) 551 return sql.Value{ 552 Typ: query.Type_UINT64, 553 Val: x, 554 } 555 case sqltypes.Float32: 556 x := values.WriteFloat32(make([]byte, values.Float32Size), 0) 557 return sql.Value{ 558 Typ: query.Type_FLOAT32, 559 Val: x, 560 } 561 case sqltypes.Float64: 562 x := values.WriteUint64(make([]byte, values.Uint64Size), 0) 563 return sql.Value{ 564 Typ: query.Type_UINT64, 565 Val: x, 566 } 567 default: 568 panic(sql.ErrInvalidBaseType.New(t.baseType.String(), "number")) 569 } 570 } 571 572 // SQL2 implements Type2 interface. 573 func (t NumberTypeImpl_) SQL2(v sql.Value) (sqltypes.Value, error) { 574 if v.IsNull() { 575 return sqltypes.NULL, nil 576 } 577 578 var val []byte 579 switch t.baseType { 580 case sqltypes.Int8: 581 x := values.ReadInt8(v.Val) 582 val = []byte(strconv.FormatInt(int64(x), 10)) 583 case sqltypes.Int16: 584 x := values.ReadInt16(v.Val) 585 val = []byte(strconv.FormatInt(int64(x), 10)) 586 case sqltypes.Int24: 587 x := values.ReadInt24(v.Val) 588 val = []byte(strconv.FormatInt(int64(x), 10)) 589 case sqltypes.Int32: 590 x := values.ReadInt32(v.Val) 591 val = []byte(strconv.FormatInt(int64(x), 10)) 592 case sqltypes.Int64: 593 x := values.ReadInt64(v.Val) 594 val = []byte(strconv.FormatInt(x, 10)) 595 case sqltypes.Uint8: 596 x := values.ReadUint8(v.Val) 597 val = []byte(strconv.FormatUint(uint64(x), 10)) 598 case sqltypes.Uint16: 599 x := values.ReadUint16(v.Val) 600 val = []byte(strconv.FormatUint(uint64(x), 10)) 601 case sqltypes.Uint24: 602 x := values.ReadUint24(v.Val) 603 val = []byte(strconv.FormatUint(uint64(x), 10)) 604 case sqltypes.Uint32: 605 x := values.ReadUint32(v.Val) 606 val = []byte(strconv.FormatUint(uint64(x), 10)) 607 case sqltypes.Uint64: 608 x := values.ReadUint64(v.Val) 609 val = []byte(strconv.FormatUint(x, 10)) 610 case sqltypes.Float32: 611 x := values.ReadFloat32(v.Val) 612 val = []byte(strconv.FormatFloat(float64(x), 'f', -1, 32)) 613 case sqltypes.Float64: 614 x := values.ReadFloat64(v.Val) 615 val = []byte(strconv.FormatFloat(x, 'f', -1, 64)) 616 default: 617 panic(sql.ErrInvalidBaseType.New(t.baseType.String(), "number")) 618 } 619 620 return sqltypes.MakeTrusted(t.baseType, val), nil 621 } 622 623 // String implements Type interface. 624 func (t NumberTypeImpl_) String() string { 625 switch t.baseType { 626 case sqltypes.Int8: 627 // MySQL 8.1.0 only honors display width for signed TINYINT fields 628 if t.displayWidth != 0 { 629 return fmt.Sprintf("tinyint(%d)", t.displayWidth) 630 } 631 return "tinyint" 632 case sqltypes.Uint8: 633 return "tinyint unsigned" 634 case sqltypes.Int16: 635 return "smallint" 636 case sqltypes.Uint16: 637 return "smallint unsigned" 638 case sqltypes.Int24: 639 return "mediumint" 640 case sqltypes.Uint24: 641 return "mediumint unsigned" 642 case sqltypes.Int32: 643 return "int" 644 case sqltypes.Uint32: 645 return "int unsigned" 646 case sqltypes.Int64: 647 return "bigint" 648 case sqltypes.Uint64: 649 return "bigint unsigned" 650 case sqltypes.Float32: 651 return "float" 652 case sqltypes.Float64: 653 return "double" 654 default: 655 panic(fmt.Sprintf("%v is not a valid number base type", t.baseType.String())) 656 } 657 } 658 659 // Type implements Type interface. 660 func (t NumberTypeImpl_) Type() query.Type { 661 return t.baseType 662 } 663 664 // ValueType implements Type interface. 665 func (t NumberTypeImpl_) ValueType() reflect.Type { 666 switch t.baseType { 667 case sqltypes.Int8: 668 return numberInt8ValueType 669 case sqltypes.Uint8: 670 return numberUint8ValueType 671 case sqltypes.Int16: 672 return numberInt16ValueType 673 case sqltypes.Uint16: 674 return numberUint16ValueType 675 case sqltypes.Int24: 676 return numberInt32ValueType 677 case sqltypes.Uint24: 678 return numberUint32ValueType 679 case sqltypes.Int32: 680 return numberInt32ValueType 681 case sqltypes.Uint32: 682 return numberUint32ValueType 683 case sqltypes.Int64: 684 return numberInt64ValueType 685 case sqltypes.Uint64: 686 return numberUint64ValueType 687 case sqltypes.Float32: 688 return numberFloat32ValueType 689 case sqltypes.Float64: 690 return numberFloat64ValueType 691 default: 692 panic(fmt.Sprintf("%v is not a valid number base type", t.baseType.String())) 693 } 694 } 695 696 // Zero implements Type interface. 697 func (t NumberTypeImpl_) Zero() interface{} { 698 switch t.baseType { 699 case sqltypes.Int8: 700 return int8(0) 701 case sqltypes.Uint8: 702 return uint8(0) 703 case sqltypes.Int16: 704 return int16(0) 705 case sqltypes.Uint16: 706 return uint16(0) 707 case sqltypes.Int24: 708 return int32(0) 709 case sqltypes.Uint24: 710 return uint32(0) 711 case sqltypes.Int32: 712 return int32(0) 713 case sqltypes.Uint32: 714 return uint32(0) 715 case sqltypes.Int64: 716 return int64(0) 717 case sqltypes.Uint64: 718 return uint64(0) 719 case sqltypes.Float32: 720 return float32(0) 721 case sqltypes.Float64: 722 return float64(0) 723 default: 724 panic(fmt.Sprintf("%v is not a valid number base type", t.baseType.String())) 725 } 726 } 727 728 // CollationCoercibility implements sql.CollationCoercible interface. 729 func (NumberTypeImpl_) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 730 return sql.Collation_binary, 5 731 } 732 733 // IsFloat implements NumberType interface. 734 func (t NumberTypeImpl_) IsFloat() bool { 735 switch t.baseType { 736 case sqltypes.Float32, sqltypes.Float64: 737 return true 738 } 739 return false 740 } 741 742 // IsSigned implements NumberType interface. 743 func (t NumberTypeImpl_) IsSigned() bool { 744 switch t.baseType { 745 case sqltypes.Int8, sqltypes.Int16, sqltypes.Int24, sqltypes.Int32, sqltypes.Int64, sqltypes.Float32, sqltypes.Float64: 746 return true 747 } 748 return false 749 } 750 751 // DisplayWidth() implements NumberType inteface. 752 func (t NumberTypeImpl_) DisplayWidth() int { 753 return t.displayWidth 754 } 755 756 func convertToInt64(t NumberTypeImpl_, v interface{}) (int64, sql.ConvertInRange, error) { 757 switch v := v.(type) { 758 case int: 759 return int64(v), sql.InRange, nil 760 case int8: 761 return int64(v), sql.InRange, nil 762 case int16: 763 return int64(v), sql.InRange, nil 764 case int32: 765 return int64(v), sql.InRange, nil 766 case int64: 767 return v, sql.InRange, nil 768 case uint: 769 return int64(v), sql.InRange, nil 770 case uint8: 771 return int64(v), sql.InRange, nil 772 case uint16: 773 return int64(v), sql.InRange, nil 774 case uint32: 775 return int64(v), sql.InRange, nil 776 case uint64: 777 if v > math.MaxInt64 { 778 return math.MaxInt64, sql.OutOfRange, nil 779 } 780 return int64(v), sql.InRange, nil 781 case float32: 782 if v > float32(math.MaxInt64) { 783 return math.MaxInt64, sql.OutOfRange, nil 784 } else if v < float32(math.MinInt64) { 785 return math.MinInt64, sql.OutOfRange, nil 786 } 787 return int64(math.Round(float64(v))), sql.OutOfRange, nil 788 case float64: 789 if v > float64(math.MaxInt64) { 790 return math.MaxInt64, sql.OutOfRange, nil 791 } else if v < float64(math.MinInt64) { 792 return math.MinInt64, sql.OutOfRange, nil 793 } 794 return int64(math.Round(v)), sql.InRange, nil 795 case decimal.Decimal: 796 if v.GreaterThan(dec_int64_max) { 797 return dec_int64_max.IntPart(), sql.OutOfRange, nil 798 } else if v.LessThan(dec_int64_min) { 799 return dec_int64_min.IntPart(), sql.OutOfRange, nil 800 } 801 return v.Round(0).IntPart(), sql.InRange, nil 802 case []byte: 803 i, err := strconv.ParseInt(hex.EncodeToString(v), 16, 64) 804 if err != nil { 805 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 806 } 807 return i, sql.InRange, nil 808 case string: 809 if v == "" { 810 // StringType{}.Zero() returns empty string, but should represent "0" for number value 811 return 0, sql.InRange, nil 812 } 813 // Parse first an integer, which allows for more values than float64 814 i, err := strconv.ParseInt(v, 10, 64) 815 if err == nil { 816 return i, sql.InRange, nil 817 } 818 // If that fails, try as a float and truncate it to integral 819 f, err := strconv.ParseFloat(v, 64) 820 if err != nil { 821 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 822 } 823 return int64(f), sql.InRange, nil 824 case bool: 825 if v { 826 return 1, sql.InRange, nil 827 } 828 return 0, sql.InRange, nil 829 case nil: 830 return 0, sql.InRange, nil 831 default: 832 return 0, sql.OutOfRange, sql.ErrInvalidValueType.New(v, t.String()) 833 } 834 } 835 836 func convertValueToInt64(t NumberTypeImpl_, v sql.Value) (int64, error) { 837 switch v.Typ { 838 case query.Type_INT8: 839 return int64(values.ReadInt8(v.Val)), nil 840 case query.Type_INT16: 841 return int64(values.ReadInt16(v.Val)), nil 842 case query.Type_INT24: 843 return int64(values.ReadInt24(v.Val)), nil 844 case query.Type_INT32: 845 return int64(values.ReadInt32(v.Val)), nil 846 case query.Type_INT64: 847 return values.ReadInt64(v.Val), nil 848 case query.Type_UINT8: 849 return int64(values.ReadUint8(v.Val)), nil 850 case query.Type_UINT16: 851 return int64(values.ReadUint16(v.Val)), nil 852 case query.Type_UINT24: 853 return int64(values.ReadUint24(v.Val)), nil 854 case query.Type_UINT32: 855 return int64(values.ReadUint32(v.Val)), nil 856 case query.Type_UINT64: 857 v := values.ReadUint64(v.Val) 858 if v > math.MaxInt64 { 859 return math.MaxInt64, nil 860 } 861 return int64(v), nil 862 case query.Type_FLOAT32: 863 v := values.ReadFloat32(v.Val) 864 if v > float32(math.MaxInt64) { 865 return math.MaxInt64, nil 866 } else if v < float32(math.MinInt64) { 867 return math.MinInt64, nil 868 } 869 return int64(math.Round(float64(v))), nil 870 case query.Type_FLOAT64: 871 v := values.ReadFloat64(v.Val) 872 if v > float64(math.MaxInt64) { 873 return math.MaxInt64, nil 874 } else if v < float64(math.MinInt64) { 875 return math.MinInt64, nil 876 } 877 return int64(math.Round(v)), nil 878 // TODO: add more conversions 879 default: 880 panic(sql.ErrInvalidBaseType.New(t.baseType.String(), "number")) 881 } 882 } 883 884 func convertValueToUint64(t NumberTypeImpl_, v sql.Value) (uint64, error) { 885 switch v.Typ { 886 case query.Type_INT8: 887 return uint64(values.ReadInt8(v.Val)), nil 888 case query.Type_INT16: 889 return uint64(values.ReadInt16(v.Val)), nil 890 case query.Type_INT24: 891 return uint64(values.ReadInt24(v.Val)), nil 892 case query.Type_INT32: 893 return uint64(values.ReadInt32(v.Val)), nil 894 case query.Type_INT64: 895 return uint64(values.ReadInt64(v.Val)), nil 896 case query.Type_UINT8: 897 return uint64(values.ReadUint8(v.Val)), nil 898 case query.Type_UINT16: 899 return uint64(values.ReadUint16(v.Val)), nil 900 case query.Type_UINT24: 901 return uint64(values.ReadUint24(v.Val)), nil 902 case query.Type_UINT32: 903 return uint64(values.ReadUint32(v.Val)), nil 904 case query.Type_UINT64: 905 return values.ReadUint64(v.Val), nil 906 case query.Type_FLOAT32: 907 v := values.ReadFloat32(v.Val) 908 if v >= float32(math.MaxUint64) { 909 return math.MaxUint64, nil 910 } 911 return uint64(math.Round(float64(v))), nil 912 case query.Type_FLOAT64: 913 v := values.ReadFloat64(v.Val) 914 if v >= float64(math.MaxUint64) { 915 return math.MaxUint64, nil 916 } 917 return uint64(math.Round(v)), nil 918 // TODO: add more conversions 919 default: 920 panic(sql.ErrInvalidBaseType.New(t.baseType.String(), "number")) 921 } 922 } 923 924 func convertToUint64(t NumberTypeImpl_, v interface{}) (uint64, sql.ConvertInRange, error) { 925 switch v := v.(type) { 926 case int: 927 if v < 0 { 928 return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil 929 } 930 return uint64(v), sql.InRange, nil 931 case int8: 932 if v < 0 { 933 return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil 934 } 935 return uint64(v), sql.InRange, nil 936 case int16: 937 if v < 0 { 938 return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil 939 } 940 return uint64(v), sql.InRange, nil 941 case int32: 942 if v < 0 { 943 return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil 944 } 945 return uint64(v), sql.InRange, nil 946 case int64: 947 if v < 0 { 948 return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil 949 } 950 return uint64(v), sql.InRange, nil 951 case uint: 952 return uint64(v), sql.InRange, nil 953 case uint8: 954 return uint64(v), sql.InRange, nil 955 case uint16: 956 return uint64(v), sql.InRange, nil 957 case uint32: 958 return uint64(v), sql.InRange, nil 959 case uint64: 960 return v, sql.InRange, nil 961 case float32: 962 if v > float32(math.MaxInt64) { 963 return math.MaxUint64, sql.OutOfRange, nil 964 } else if v < 0 { 965 return uint64(math.MaxUint64 - v), sql.OutOfRange, nil 966 } 967 return uint64(math.Round(float64(v))), sql.InRange, nil 968 case float64: 969 if v >= float64(math.MaxUint64) { 970 return math.MaxUint64, sql.OutOfRange, nil 971 } else if v <= 0 { 972 return uint64(math.MaxUint64 - v), sql.OutOfRange, nil 973 } 974 return uint64(math.Round(v)), sql.InRange, nil 975 case decimal.Decimal: 976 if v.GreaterThan(dec_uint64_max) { 977 return math.MaxUint64, sql.InRange, nil 978 } else if v.LessThan(dec_zero) { 979 ret, _ := dec_uint64_max.Sub(v).Float64() 980 return uint64(math.Round(ret)), sql.OutOfRange, nil 981 } 982 // TODO: If we ever internally switch to using Decimal for large numbers, this will need to be updated 983 f, _ := v.Float64() 984 return uint64(math.Round(f)), sql.InRange, nil 985 case []byte: 986 i, err := strconv.ParseUint(hex.EncodeToString(v), 16, 64) 987 if err != nil { 988 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 989 } 990 return i, sql.InRange, nil 991 case string: 992 i, err := strconv.ParseUint(v, 10, 64) 993 if err != nil { 994 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 995 } 996 return i, sql.InRange, nil 997 case bool: 998 if v { 999 return 1, sql.InRange, nil 1000 } 1001 return 0, sql.InRange, nil 1002 case nil: 1003 return 0, sql.InRange, nil 1004 default: 1005 return 0, sql.OutOfRange, sql.ErrInvalidValueType.New(v, t.String()) 1006 } 1007 } 1008 1009 func convertToUint32(t NumberTypeImpl_, v interface{}) (uint32, sql.ConvertInRange, error) { 1010 switch v := v.(type) { 1011 case int: 1012 if v < 0 { 1013 return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil 1014 } else if v > math.MaxUint32 { 1015 return uint32(math.MaxUint32), sql.OutOfRange, nil 1016 } 1017 return uint32(v), sql.InRange, nil 1018 case int8: 1019 if v < 0 { 1020 return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil 1021 } else if int(v) > math.MaxUint32 { 1022 return uint32(math.MaxUint32), sql.OutOfRange, nil 1023 } 1024 return uint32(v), sql.InRange, nil 1025 case int16: 1026 if v < 0 { 1027 return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil 1028 } else if int(v) > math.MaxUint32 { 1029 return uint32(math.MaxUint32), sql.OutOfRange, nil 1030 } 1031 return uint32(v), sql.InRange, nil 1032 case int32: 1033 if v < 0 { 1034 return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil 1035 } else if int(v) > math.MaxUint32 { 1036 return uint32(math.MaxUint32), sql.OutOfRange, nil 1037 } 1038 return uint32(v), sql.InRange, nil 1039 case int64: 1040 if v < 0 { 1041 return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil 1042 } else if v > math.MaxUint32 { 1043 return uint32(math.MaxUint32), sql.OutOfRange, nil 1044 } 1045 return uint32(v), sql.InRange, nil 1046 case uint: 1047 return uint32(v), sql.InRange, nil 1048 case uint8: 1049 return uint32(v), sql.InRange, nil 1050 case uint16: 1051 return uint32(v), sql.InRange, nil 1052 case uint32: 1053 return v, sql.InRange, nil 1054 case uint64: 1055 return uint32(v), sql.InRange, nil 1056 case float64: 1057 if float32(v) > float32(math.MaxInt32) { 1058 return math.MaxUint32, sql.OutOfRange, nil 1059 } else if v < 0 { 1060 return uint32(math.MaxUint32 - v), sql.OutOfRange, nil 1061 } 1062 return uint32(math.Round(float64(v))), sql.InRange, nil 1063 case float32: 1064 if v >= float32(math.MaxUint32) { 1065 return math.MaxUint32, sql.OutOfRange, nil 1066 } else if v <= 0 { 1067 return uint32(math.MaxUint32 - v), sql.OutOfRange, nil 1068 } 1069 return uint32(math.Round(float64(v))), sql.InRange, nil 1070 case decimal.Decimal: 1071 if v.GreaterThan(dec_uint32_max) { 1072 return math.MaxUint32, sql.InRange, nil 1073 } else if v.LessThan(dec_zero) { 1074 ret, _ := dec_uint32_max.Sub(v).Float64() 1075 return uint32(math.Round(ret)), sql.OutOfRange, nil 1076 } 1077 // TODO: If we ever internally switch to using Decimal for large numbers, this will need to be updated 1078 f, _ := v.Float64() 1079 return uint32(math.Round(f)), sql.InRange, nil 1080 case []byte: 1081 i, err := strconv.ParseUint(hex.EncodeToString(v), 16, 32) 1082 if err != nil { 1083 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 1084 } 1085 return uint32(i), sql.InRange, nil 1086 case string: 1087 i, err := strconv.ParseUint(v, 10, 32) 1088 if err != nil { 1089 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 1090 } 1091 return uint32(i), sql.InRange, nil 1092 case bool: 1093 if v { 1094 return 1, sql.InRange, nil 1095 } 1096 return 0, sql.InRange, nil 1097 case nil: 1098 return 0, sql.InRange, nil 1099 default: 1100 return 0, sql.OutOfRange, sql.ErrInvalidValueType.New(v, t.String()) 1101 } 1102 } 1103 1104 func convertToUint16(t NumberTypeImpl_, v interface{}) (uint16, sql.ConvertInRange, error) { 1105 switch v := v.(type) { 1106 case int: 1107 if v < 0 { 1108 return uint16(math.MaxUint16 - uint(-v-1)), sql.OutOfRange, nil 1109 } else if v > math.MaxUint16 { 1110 return uint16(math.MaxUint16), sql.OutOfRange, nil 1111 } 1112 return uint16(v), sql.InRange, nil 1113 case int8: 1114 if v < 0 { 1115 return uint16(math.MaxUint16 - uint(-v-1)), sql.OutOfRange, nil 1116 } 1117 return uint16(v), sql.InRange, nil 1118 case int16: 1119 if v < 0 { 1120 return uint16(math.MaxUint16 - uint(-v-1)), sql.OutOfRange, nil 1121 } 1122 return uint16(v), sql.InRange, nil 1123 case int32: 1124 if v < 0 { 1125 return uint16(math.MaxUint16 - uint(-v-1)), sql.OutOfRange, nil 1126 } else if v > math.MaxUint16 { 1127 return uint16(math.MaxUint16), sql.OutOfRange, nil 1128 } 1129 return uint16(v), sql.InRange, nil 1130 case int64: 1131 if v < 0 { 1132 return uint16(math.MaxUint16 - uint(-v-1)), sql.OutOfRange, nil 1133 } else if v > math.MaxUint16 { 1134 return uint16(math.MaxUint16), sql.OutOfRange, nil 1135 } 1136 return uint16(v), sql.InRange, nil 1137 case uint: 1138 return uint16(v), sql.InRange, nil 1139 case uint8: 1140 return uint16(v), sql.InRange, nil 1141 case uint64: 1142 return uint16(v), sql.InRange, nil 1143 case uint32: 1144 return uint16(v), sql.InRange, nil 1145 case uint16: 1146 return v, sql.InRange, nil 1147 case float32: 1148 if v > float32(math.MaxInt16) { 1149 return math.MaxUint16, sql.OutOfRange, nil 1150 } else if v < 0 { 1151 return uint16(math.MaxUint16 - v), sql.OutOfRange, nil 1152 } 1153 return uint16(math.Round(float64(v))), sql.InRange, nil 1154 case float64: 1155 if v >= float64(math.MaxUint16) { 1156 return math.MaxUint16, sql.OutOfRange, nil 1157 } else if v <= 0 { 1158 return uint16(math.MaxUint16 - v), sql.OutOfRange, nil 1159 } 1160 return uint16(math.Round(v)), sql.InRange, nil 1161 case decimal.Decimal: 1162 if v.GreaterThan(dec_uint16_max) { 1163 return math.MaxUint16, sql.InRange, nil 1164 } else if v.LessThan(dec_zero) { 1165 ret, _ := dec_uint16_max.Sub(v).Float64() 1166 return uint16(math.Round(ret)), sql.OutOfRange, nil 1167 } 1168 // TODO: If we ever internally switch to using Decimal for large numbers, this will need to be updated 1169 f, _ := v.Float64() 1170 return uint16(math.Round(f)), sql.InRange, nil 1171 case []byte: 1172 i, err := strconv.ParseUint(hex.EncodeToString(v), 16, 16) 1173 if err != nil { 1174 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 1175 } 1176 return uint16(i), sql.InRange, nil 1177 case string: 1178 i, err := strconv.ParseUint(v, 10, 16) 1179 if err != nil { 1180 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 1181 } 1182 return uint16(i), sql.InRange, nil 1183 case bool: 1184 if v { 1185 return 1, sql.InRange, nil 1186 } 1187 return 0, sql.InRange, nil 1188 case nil: 1189 return 0, sql.InRange, nil 1190 default: 1191 return 0, sql.OutOfRange, sql.ErrInvalidValueType.New(v, t.String()) 1192 } 1193 } 1194 1195 func convertToUint8(t NumberTypeImpl_, v interface{}) (uint8, sql.ConvertInRange, error) { 1196 switch v := v.(type) { 1197 case int: 1198 if v < 0 { 1199 return uint8(math.MaxUint8 - uint(-v-1)), sql.OutOfRange, nil 1200 } else if v > math.MaxUint8 { 1201 return uint8(math.MaxUint8), sql.OutOfRange, nil 1202 } 1203 return uint8(v), sql.InRange, nil 1204 case int16: 1205 if v < 0 { 1206 return uint8(math.MaxUint8 - uint(-v-1)), sql.OutOfRange, nil 1207 } else if v > math.MaxUint8 { 1208 return uint8(math.MaxUint8), sql.OutOfRange, nil 1209 } 1210 return uint8(v), sql.InRange, nil 1211 case int8: 1212 if v < 0 { 1213 return uint8(math.MaxUint8 - uint(-v-1)), sql.OutOfRange, nil 1214 } else if int(v) > math.MaxUint8 { 1215 return uint8(math.MaxUint8), sql.OutOfRange, nil 1216 } 1217 return uint8(v), sql.InRange, nil 1218 case int32: 1219 if v < 0 { 1220 return uint8(math.MaxUint8 - uint(-v-1)), sql.OutOfRange, nil 1221 } else if v > math.MaxUint8 { 1222 return uint8(math.MaxUint8), sql.OutOfRange, nil 1223 } 1224 return uint8(v), sql.InRange, nil 1225 case int64: 1226 if v < 0 { 1227 return uint8(math.MaxUint8 - uint(-v-1)), sql.OutOfRange, nil 1228 } else if v > math.MaxUint8 { 1229 return uint8(math.MaxUint8), sql.OutOfRange, nil 1230 } 1231 return uint8(v), sql.InRange, nil 1232 case uint: 1233 return uint8(v), sql.InRange, nil 1234 case uint16: 1235 return uint8(v), sql.InRange, nil 1236 case uint64: 1237 return uint8(v), sql.InRange, nil 1238 case uint32: 1239 return uint8(v), sql.InRange, nil 1240 case uint8: 1241 return v, sql.InRange, nil 1242 case float32: 1243 if v > float32(math.MaxInt8) { 1244 return math.MaxUint8, sql.OutOfRange, nil 1245 } else if v < 0 { 1246 return uint8(math.MaxUint8 - v), sql.OutOfRange, nil 1247 } 1248 return uint8(math.Round(float64(v))), sql.InRange, nil 1249 case float64: 1250 if v >= float64(math.MaxUint8) { 1251 return math.MaxUint8, sql.OutOfRange, nil 1252 } else if v <= 0 { 1253 return uint8(math.MaxUint8 - v), sql.OutOfRange, nil 1254 } 1255 return uint8(math.Round(v)), sql.InRange, nil 1256 case decimal.Decimal: 1257 if v.GreaterThan(dec_uint8_max) { 1258 return math.MaxUint8, sql.InRange, nil 1259 } else if v.LessThan(dec_zero) { 1260 ret, _ := dec_uint8_max.Sub(v).Float64() 1261 return uint8(math.Round(ret)), sql.OutOfRange, nil 1262 } 1263 // TODO: If we ever internally switch to using Decimal for large numbers, this will need to be updated 1264 f, _ := v.Float64() 1265 return uint8(math.Round(f)), sql.InRange, nil 1266 case []byte: 1267 i, err := strconv.ParseUint(hex.EncodeToString(v), 8, 8) 1268 if err != nil { 1269 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 1270 } 1271 return uint8(i), sql.InRange, nil 1272 case string: 1273 i, err := strconv.ParseUint(v, 10, 8) 1274 if err != nil { 1275 return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String()) 1276 } 1277 return uint8(i), sql.InRange, nil 1278 case bool: 1279 if v { 1280 return 1, sql.InRange, nil 1281 } 1282 return 0, sql.InRange, nil 1283 case nil: 1284 return 0, sql.InRange, nil 1285 default: 1286 return 0, sql.OutOfRange, sql.ErrInvalidValueType.New(v, t.String()) 1287 } 1288 } 1289 1290 func convertToFloat64(t NumberTypeImpl_, v interface{}) (float64, error) { 1291 switch v := v.(type) { 1292 case int: 1293 return float64(v), nil 1294 case int8: 1295 return float64(v), nil 1296 case int16: 1297 return float64(v), nil 1298 case int32: 1299 return float64(v), nil 1300 case int64: 1301 return float64(v), nil 1302 case uint: 1303 return float64(v), nil 1304 case uint8: 1305 return float64(v), nil 1306 case uint16: 1307 return float64(v), nil 1308 case uint32: 1309 return float64(v), nil 1310 case uint64: 1311 return float64(v), nil 1312 case float32: 1313 return float64(v), nil 1314 case float64: 1315 return v, nil 1316 case decimal.Decimal: 1317 f, _ := v.Float64() 1318 return f, nil 1319 case []byte: 1320 i, err := strconv.ParseUint(hex.EncodeToString(v), 16, 64) 1321 if err != nil { 1322 return 0, sql.ErrInvalidValue.New(v, t.String()) 1323 } 1324 return float64(i), nil 1325 case string: 1326 i, err := strconv.ParseFloat(v, 64) 1327 if err != nil { 1328 // parse the first longest valid numbers 1329 s := numre.FindString(v) 1330 i, _ = strconv.ParseFloat(s, 64) 1331 return i, sql.ErrInvalidValue.New(v, t.String()) 1332 } 1333 return i, nil 1334 case bool: 1335 if v { 1336 return 1, nil 1337 } 1338 return 0, nil 1339 case nil: 1340 return 0, nil 1341 default: 1342 return 0, sql.ErrInvalidValueType.New(v, t.String()) 1343 } 1344 } 1345 1346 func convertValueToFloat64(t NumberTypeImpl_, v sql.Value) (float64, error) { 1347 switch v.Typ { 1348 case query.Type_INT8: 1349 return float64(values.ReadInt8(v.Val)), nil 1350 case query.Type_INT16: 1351 return float64(values.ReadInt16(v.Val)), nil 1352 case query.Type_INT24: 1353 return float64(values.ReadInt24(v.Val)), nil 1354 case query.Type_INT32: 1355 return float64(values.ReadInt32(v.Val)), nil 1356 case query.Type_INT64: 1357 return float64(values.ReadInt64(v.Val)), nil 1358 case query.Type_UINT8: 1359 return float64(values.ReadUint8(v.Val)), nil 1360 case query.Type_UINT16: 1361 return float64(values.ReadUint16(v.Val)), nil 1362 case query.Type_UINT24: 1363 return float64(values.ReadUint24(v.Val)), nil 1364 case query.Type_UINT32: 1365 return float64(values.ReadUint32(v.Val)), nil 1366 case query.Type_UINT64: 1367 return float64(values.ReadUint64(v.Val)), nil 1368 case query.Type_FLOAT32: 1369 return float64(values.ReadFloat32(v.Val)), nil 1370 case query.Type_FLOAT64: 1371 return values.ReadFloat64(v.Val), nil 1372 default: 1373 panic(sql.ErrInvalidBaseType.New(t.baseType.String(), "number")) 1374 } 1375 } 1376 1377 func mustInt64(v interface{}) int64 { 1378 switch tv := v.(type) { 1379 case int: 1380 return int64(tv) 1381 case int8: 1382 return int64(tv) 1383 case int16: 1384 return int64(tv) 1385 case int32: 1386 return int64(tv) 1387 case int64: 1388 return tv 1389 case uint: 1390 return int64(tv) 1391 case uint8: 1392 return int64(tv) 1393 case uint16: 1394 return int64(tv) 1395 case uint32: 1396 return int64(tv) 1397 case uint64: 1398 return int64(tv) 1399 case bool: 1400 if tv { 1401 return int64(1) 1402 } 1403 return int64(0) 1404 case float32: 1405 return int64(tv) 1406 case float64: 1407 return int64(tv) 1408 default: 1409 panic(fmt.Sprintf("unexpected type %v", v)) 1410 } 1411 } 1412 1413 func mustUint64(v interface{}) uint64 { 1414 switch tv := v.(type) { 1415 case uint: 1416 return uint64(tv) 1417 case uint8: 1418 return uint64(tv) 1419 case uint16: 1420 return uint64(tv) 1421 case uint32: 1422 return uint64(tv) 1423 case uint64: 1424 return tv 1425 case int: 1426 return uint64(tv) 1427 case int8: 1428 return uint64(tv) 1429 case int16: 1430 return uint64(tv) 1431 case int32: 1432 return uint64(tv) 1433 case int64: 1434 return uint64(tv) 1435 case bool: 1436 if tv { 1437 return uint64(1) 1438 } 1439 return uint64(0) 1440 case float32: 1441 return uint64(tv) 1442 case float64: 1443 return uint64(tv) 1444 default: 1445 panic(fmt.Sprintf("unexpected type %v", v)) 1446 } 1447 } 1448 1449 func mustFloat64(v interface{}) float64 { 1450 switch tv := v.(type) { 1451 case uint: 1452 return float64(tv) 1453 case uint8: 1454 return float64(tv) 1455 case uint16: 1456 return float64(tv) 1457 case uint32: 1458 return float64(tv) 1459 case uint64: 1460 return float64(tv) 1461 case int: 1462 return float64(tv) 1463 case int8: 1464 return float64(tv) 1465 case int16: 1466 return float64(tv) 1467 case int32: 1468 return float64(tv) 1469 case int64: 1470 return float64(tv) 1471 case bool: 1472 if tv { 1473 return float64(1) 1474 } 1475 return float64(0) 1476 case float32: 1477 return float64(tv) 1478 case float64: 1479 return tv 1480 default: 1481 panic(fmt.Sprintf("unexpected type %v", v)) 1482 } 1483 } 1484 1485 func isString(v interface{}) bool { 1486 switch v.(type) { 1487 case []byte, string: 1488 return true 1489 default: 1490 return false 1491 } 1492 } 1493 1494 // CoalesceInt converts a int8/int16/... to int 1495 func CoalesceInt(val interface{}) (int, bool) { 1496 switch v := val.(type) { 1497 case int: 1498 return v, true 1499 case int8: 1500 return int(v), true 1501 case int16: 1502 return int(v), true 1503 case int32: 1504 return int(v), true 1505 case int64: 1506 return int(v), true 1507 case uint8: 1508 return int(v), true 1509 case uint16: 1510 return int(v), true 1511 case uint32: 1512 return int(v), true 1513 case uint64: 1514 return int(v), true 1515 default: 1516 return 0, false 1517 } 1518 }