github.com/dolthub/go-mysql-server@v0.18.0/sql/type.go (about)

     1  // Copyright 2020-2021 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 sql
    16  
    17  import (
    18  	"fmt"
    19  	"reflect"
    20  	"time"
    21  
    22  	"github.com/dolthub/vitess/go/sqltypes"
    23  	"github.com/dolthub/vitess/go/vt/proto/query"
    24  	"github.com/shopspring/decimal"
    25  	"gopkg.in/src-d/go-errors.v1"
    26  )
    27  
    28  var (
    29  	// ErrNotTuple is returned when the value is not a tuple.
    30  	ErrNotTuple = errors.NewKind("value of type %T is not a tuple")
    31  
    32  	// ErrInvalidColumnNumber is returned when a tuple has an invalid number of
    33  	// arguments.
    34  	ErrInvalidColumnNumber = errors.NewKind("tuple should contain %d column(s), but has %d")
    35  
    36  	ErrInvalidBaseType = errors.NewKind("%v is not a valid %v base type")
    37  
    38  	// ErrConvertToSQL is returned when Convert failed.
    39  	// It makes an error less verbose comparing to what spf13/cast returns.
    40  	ErrConvertToSQL = errors.NewKind("incompatible conversion to SQL type: '%v'->%s")
    41  )
    42  
    43  const (
    44  	// DateLayout is the layout of the MySQL date format in the representation
    45  	// Go understands.
    46  	DateLayout = "2006-01-02"
    47  
    48  	// TimestampDatetimeLayout is the formatting string with the layout of the timestamp
    49  	// using the format of Go "time" package.
    50  	TimestampDatetimeLayout = "2006-01-02 15:04:05.999999"
    51  )
    52  
    53  const (
    54  	// False is the numeric representation of False as defined by MySQL.
    55  	False = int8(0)
    56  	// True is the numeric representation of True as defined by MySQL.
    57  	True = int8(1)
    58  )
    59  
    60  type ConvertInRange bool
    61  
    62  const (
    63  	InRange    ConvertInRange = true
    64  	OutOfRange                = false
    65  )
    66  
    67  // Type represents a SQL type.
    68  type Type interface {
    69  	CollationCoercible
    70  	// Compare returns an integer comparing two values.
    71  	// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
    72  	Compare(interface{}, interface{}) (int, error)
    73  	// Convert a value of a compatible type to a most accurate type, returning
    74  	// the new value, whether the value in range, or an error. If |inRange| is
    75  	// false, the value was coerced according to MySQL's rules.
    76  	Convert(interface{}) (interface{}, ConvertInRange, error)
    77  	// Equals returns whether the given type is equivalent to the calling type. All parameters are included in the
    78  	// comparison, so ENUM("a", "b") is not equivalent to ENUM("a", "b", "c").
    79  	Equals(otherType Type) bool
    80  	// MaxTextResponseByteLength returns the maximum number of bytes needed to serialize an instance of this type
    81  	// as a string in a response over the wire for MySQL's text protocol – in other words, this is the maximum bytes
    82  	// needed to serialize any value of this type as human-readable text, NOT in a more compact, binary representation.
    83  	MaxTextResponseByteLength(ctx *Context) uint32
    84  	// Promote will promote the current type to the largest representing type of the same kind, such as Int8 to Int64.
    85  	Promote() Type
    86  	// SQL returns the sqltypes.Value for the given value.
    87  	// Implementations can optionally use |dest| to append
    88  	// serialized data, but should not mutate existing data.
    89  	SQL(ctx *Context, dest []byte, v interface{}) (sqltypes.Value, error)
    90  	// Type returns the query.Type for the given Type.
    91  	Type() query.Type
    92  	// ValueType returns the Go type of the value returned by Convert().
    93  	ValueType() reflect.Type
    94  	// Zero returns the golang zero value for this type
    95  	Zero() interface{}
    96  	fmt.Stringer
    97  }
    98  
    99  // NullType represents the type of NULL values
   100  type NullType interface {
   101  	Type
   102  }
   103  
   104  // DeferredType is a placeholder for prepared statements
   105  // that is replaced by the BindVar type on re-analysis.
   106  type DeferredType interface {
   107  	Type
   108  	IsDeferred() bool
   109  	Name() string
   110  }
   111  
   112  // NumberType represents all integer and floating point types.
   113  // https://dev.mysql.com/doc/refman/8.0/en/integer-types.html
   114  // https://dev.mysql.com/doc/refman/8.0/en/floating-point-types.html
   115  // The type of the returned value is one of the following: int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64.
   116  type NumberType interface {
   117  	Type
   118  	IsSigned() bool
   119  	IsFloat() bool
   120  	DisplayWidth() int
   121  }
   122  
   123  // StringType represents all string types, including VARCHAR and BLOB.
   124  // https://dev.mysql.com/doc/refman/8.0/en/char.html
   125  // https://dev.mysql.com/doc/refman/8.0/en/binary-varbinary.html
   126  // https://dev.mysql.com/doc/refman/8.0/en/blob.html
   127  // The type of the returned value is string.
   128  type StringType interface {
   129  	Type
   130  	CharacterSet() CharacterSetID
   131  	Collation() CollationID
   132  	// MaxCharacterLength returns the maximum number of chars that can safely be stored in this type, based on
   133  	// the current character set.
   134  	MaxCharacterLength() int64
   135  	// MaxByteLength returns the maximum number of bytes that may be consumed by a value stored in this type.
   136  	MaxByteLength() int64
   137  	// Length returns the maximum length, in characters, allowed for this string type.
   138  	Length() int64
   139  }
   140  
   141  // DatetimeType represents DATE, DATETIME, and TIMESTAMP.
   142  // https://dev.mysql.com/doc/refman/8.0/en/datetime.html
   143  // The type of the returned value is time.Time.
   144  type DatetimeType interface {
   145  	Type
   146  	ConvertWithoutRangeCheck(v interface{}) (time.Time, error)
   147  	MaximumTime() time.Time
   148  	MinimumTime() time.Time
   149  	Precision() int
   150  }
   151  
   152  // YearType represents the YEAR type.
   153  // https://dev.mysql.com/doc/refman/8.0/en/year.html
   154  // The type of the returned value is int16.
   155  type YearType interface {
   156  	Type
   157  }
   158  
   159  // SetType represents the SET type.
   160  // https://dev.mysql.com/doc/refman/8.0/en/set.html
   161  // The type of the returned value is uint64.
   162  type SetType interface {
   163  	Type
   164  	CharacterSet() CharacterSetID
   165  	Collation() CollationID
   166  	// NumberOfElements returns the number of elements in this set.
   167  	NumberOfElements() uint16
   168  	// BitsToString takes a previously-converted value and returns it as a string.
   169  	BitsToString(bits uint64) (string, error)
   170  	// Values returns all of the set's values in ascending order according to their corresponding bit value.
   171  	Values() []string
   172  }
   173  
   174  // EnumType represents the ENUM type.
   175  // https://dev.mysql.com/doc/refman/8.0/en/enum.html
   176  // The type of the returned value is uint16.
   177  type EnumType interface {
   178  	Type
   179  	// At returns the string at the given index, as well if the string was found.
   180  	At(index int) (string, bool)
   181  	CharacterSet() CharacterSetID
   182  	Collation() CollationID
   183  	// IndexOf returns the index of the given string. If the string was not found, then this returns -1.
   184  	IndexOf(v string) int
   185  	// NumberOfElements returns the number of enumerations.
   186  	NumberOfElements() uint16
   187  	// Values returns the elements, in order, of every enumeration.
   188  	Values() []string
   189  }
   190  
   191  // DecimalType represents the DECIMAL type.
   192  // https://dev.mysql.com/doc/refman/8.0/en/fixed-point-types.html
   193  // The type of the returned value is decimal.Decimal.
   194  type DecimalType interface {
   195  	Type
   196  	// ConvertToNullDecimal converts the given value to a decimal.NullDecimal if it has a compatible type. It is worth
   197  	// noting that Convert() returns a nil value for nil inputs, and also returns decimal.Decimal rather than
   198  	// decimal.NullDecimal.
   199  	ConvertToNullDecimal(v interface{}) (decimal.NullDecimal, error)
   200  	//ConvertNoBoundsCheck normalizes an interface{} to a decimal type without performing expensive bound checks
   201  	ConvertNoBoundsCheck(v interface{}) (decimal.Decimal, error)
   202  	// BoundsCheck rounds and validates a decimal, returning the decimal,
   203  	// whether the value was out of range, and an error.
   204  	BoundsCheck(v decimal.Decimal) (decimal.Decimal, ConvertInRange, error)
   205  	// ExclusiveUpperBound returns the exclusive upper bound for this Decimal.
   206  	// For example, DECIMAL(5,2) would return 1000, as 999.99 is the max represented.
   207  	ExclusiveUpperBound() decimal.Decimal
   208  	// MaximumScale returns the maximum scale allowed for the current precision.
   209  	MaximumScale() uint8
   210  	// Precision returns the base-10 precision of the type, which is the total number of digits. For example, a
   211  	// precision of 3 means that 999, 99.9, 9.99, and .999 are all valid maximums (depending on the scale).
   212  	Precision() uint8
   213  	// Scale returns the scale, or number of digits after the decimal, that may be held.
   214  	// This will always be less than or equal to the precision.
   215  	Scale() uint8
   216  }
   217  
   218  type Type2 interface {
   219  	Type
   220  
   221  	// Compare2 returns an integer comparing two Values.
   222  	Compare2(Value, Value) (int, error)
   223  	// Convert2 converts a value of a compatible type.
   224  	Convert2(Value) (Value, error)
   225  	// Zero2 returns the zero Value for this type.
   226  	Zero2() Value
   227  	// SQL2 returns the sqltypes.Value for the given value
   228  	SQL2(Value) (sqltypes.Value, error)
   229  }
   230  
   231  // SpatialColumnType is a node that contains a reference to all spatial types.
   232  type SpatialColumnType interface {
   233  	// GetSpatialTypeSRID returns the SRID value for spatial types.
   234  	GetSpatialTypeSRID() (uint32, bool)
   235  	// SetSRID sets SRID value for spatial types.
   236  	SetSRID(uint32) Type
   237  	// MatchSRID returns nil if column type SRID matches given value SRID otherwise returns error.
   238  	MatchSRID(interface{}) error
   239  }
   240  
   241  // SystemVariableType represents a SQL type specifically (and only) used in system variables. Assigning any non-system
   242  // variables a SystemVariableType will cause errors.
   243  type SystemVariableType interface {
   244  	Type
   245  	// EncodeValue returns the given value as a string for storage.
   246  	EncodeValue(interface{}) (string, error)
   247  	// DecodeValue returns the original value given to EncodeValue from the given string. This is different from `Convert`,
   248  	// as the encoded value may technically be an "illegal" value according to the type rules.
   249  	DecodeValue(string) (interface{}, error)
   250  	// UnderlyingType returns the underlying type that this system variable type is based on.
   251  	UnderlyingType() Type
   252  }