|
27 | 27 | // ErrConvertingToTime is thrown when a value cannot be converted to a Time
|
28 | 28 | ErrConvertingToTime = errors.NewKind("value %q can't be converted to time.Time")
|
29 | 29 |
|
| 30 | + // ErrVarCharTruncation is thrown when a value is textually longer than the destination capacity |
| 31 | + ErrVarCharTruncation = errors.NewKind("string value of %q is longer than destination capacity %d") |
| 32 | + |
30 | 33 | // ErrValueNotNil is thrown when a value that was expected to be nil, is not
|
31 | 34 | ErrValueNotNil = errors.NewKind("value not nil: %#v")
|
32 | 35 |
|
@@ -197,6 +200,8 @@ var (
|
197 | 200 | Date dateT
|
198 | 201 | // Text is a string type.
|
199 | 202 | Text textT
|
| 203 | + // VarChar is a string type with a length. |
| 204 | + VarChar varcharT |
200 | 205 | // Boolean is a boolean type.
|
201 | 206 | Boolean booleanT
|
202 | 207 | // JSON is a type that holds any valid JSON object.
|
@@ -244,7 +249,9 @@ func MysqlTypeToType(sql query.Type) (Type, error) {
|
244 | 249 | return Timestamp, nil
|
245 | 250 | case sqltypes.Date:
|
246 | 251 | return Date, nil
|
247 |
| - case sqltypes.Text, sqltypes.VarChar: |
| 252 | + case sqltypes.VarChar: |
| 253 | + return VarChar, nil |
| 254 | + case sqltypes.Text: |
248 | 255 | return Text, nil
|
249 | 256 | case sqltypes.Bit:
|
250 | 257 | return Boolean, nil
|
@@ -550,6 +557,43 @@ func (t dateT) Compare(a, b interface{}) (int, error) {
|
550 | 557 | return 0, nil
|
551 | 558 | }
|
552 | 559 |
|
| 560 | +type varcharT struct{ |
| 561 | + length int |
| 562 | +} |
| 563 | + |
| 564 | +func (t varcharT) String() string { return fmt.Sprintf("VARCHAR(%d)", t.length) } |
| 565 | + |
| 566 | +// Type implements Type interface |
| 567 | +func (t varcharT) Type() query.Type { |
| 568 | + return sqltypes.VarChar |
| 569 | +} |
| 570 | + |
| 571 | +// SQL implements Type interface |
| 572 | +func (t varcharT) SQL(v interface{}) sqltypes.Value { |
| 573 | + if _, ok := v.(nullT); ok { |
| 574 | + return sqltypes.NULL |
| 575 | + } |
| 576 | + |
| 577 | + return sqltypes.MakeTrusted(sqltypes.VarChar, []byte(MustConvert(t, v).(string))) |
| 578 | +} |
| 579 | + |
| 580 | +// Convert implements Type interface |
| 581 | +func (t varcharT) Convert(v interface{}) (interface{}, error) { |
| 582 | + val, err := cast.ToStringE(v) |
| 583 | + if err != nil { |
| 584 | + return nil, ErrConvertToSQL.New(t) |
| 585 | + } |
| 586 | + |
| 587 | + if len(val) > t.length { |
| 588 | + return nil, ErrVarCharTruncation.New(val, t.length) |
| 589 | + } |
| 590 | + return val, nil |
| 591 | +} |
| 592 | + |
| 593 | +// Compare implements Type interface. |
| 594 | +func (t varcharT) Compare(a interface{}, b interface{}) (int, error) { |
| 595 | + return strings.Compare(a.(string), b.(string)), nil |
| 596 | +} |
553 | 597 | type textT struct{}
|
554 | 598 |
|
555 | 599 | func (t textT) String() string { return "TEXT" }
|
@@ -928,7 +972,11 @@ func IsDecimal(t Type) bool {
|
928 | 972 |
|
929 | 973 | // IsText checks if t is a text type.
|
930 | 974 | func IsText(t Type) bool {
|
931 |
| - return t == Text || t == Blob || t == JSON |
| 975 | + return t == Text || t == Blob || t == JSON || t == VarChar |
| 976 | +} |
| 977 | + |
| 978 | +func IsVarChar(t Type) bool { |
| 979 | + return t == VarChar |
932 | 980 | }
|
933 | 981 |
|
934 | 982 | // IsTuple checks if t is a tuple type.
|
@@ -982,7 +1030,9 @@ func MySQLTypeName(t Type) string {
|
982 | 1030 | return "DATETIME"
|
983 | 1031 | case sqltypes.Date:
|
984 | 1032 | return "DATE"
|
985 |
| - case sqltypes.Text, sqltypes.VarChar: |
| 1033 | + case sqltypes.VarChar: |
| 1034 | + return "VARCHAR" |
| 1035 | + case sqltypes.Text: |
986 | 1036 | return "TEXT"
|
987 | 1037 | case sqltypes.Bit:
|
988 | 1038 | return "BIT"
|
|
0 commit comments