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 }