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