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  }