|
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 |
| 30 | + // ErrCharTruncation is thrown when a Char value is textually longer than the destination capacity |
| 31 | + ErrCharTruncation = errors.NewKind("string value of %q is longer than destination capacity %d") |
| 32 | + |
| 33 | + // ErrVarCharTruncation is thrown when a VarChar value is textually longer than the destination capacity |
31 | 34 | ErrVarCharTruncation = errors.NewKind("string value of %q is longer than destination capacity %d") |
32 | 35 |
|
33 | 36 | // ErrValueNotNil is thrown when a value that was expected to be nil, is not |
@@ -220,6 +223,11 @@ func Array(underlying Type) Type { |
220 | 223 | return arrayT{underlying} |
221 | 224 | } |
222 | 225 |
|
| 226 | +// Char returns a new Char type of the given length. |
| 227 | +func Char(length int) Type { |
| 228 | + return charT{length: length} |
| 229 | +} |
| 230 | + |
223 | 231 | // VarChar returns a new VarChar type of the given length. |
224 | 232 | func VarChar(length int) Type { |
225 | 233 | return varCharT{length: length} |
@@ -256,6 +264,10 @@ func MysqlTypeToType(sql query.Type) (Type, error) { |
256 | 264 | return Date, nil |
257 | 265 | case sqltypes.Text: |
258 | 266 | return Text, nil |
| 267 | + case sqltypes.Char: |
| 268 | + // Since we can't get the size of the sqltypes.Char to instantiate a |
| 269 | + // specific Char(length) type we return a Text here |
| 270 | + return Text, nil |
259 | 271 | case sqltypes.VarChar: |
260 | 272 | // Since we can't get the size of the sqltypes.VarChar to instantiate a |
261 | 273 | // specific VarChar(length) type we return a Text here |
@@ -660,6 +672,50 @@ func (t datetimeT) Compare(a, b interface{}) (int, error) { |
660 | 672 | return 0, nil |
661 | 673 | } |
662 | 674 |
|
| 675 | +type charT struct { |
| 676 | + length int |
| 677 | +} |
| 678 | + |
| 679 | +func (t charT) Capacity() int { return t.length } |
| 680 | + |
| 681 | +func (t charT) String() string { return fmt.Sprintf("CHAR(%d)", t.length) } |
| 682 | + |
| 683 | +func (t charT) Type() query.Type { |
| 684 | + return sqltypes.Char |
| 685 | +} |
| 686 | + |
| 687 | +func (t charT) SQL(v interface{}) (sqltypes.Value, error) { |
| 688 | + if v == nil { |
| 689 | + return sqltypes.MakeTrusted(sqltypes.Char, nil), nil |
| 690 | + } |
| 691 | + |
| 692 | + v, err := t.Convert(v) |
| 693 | + if err != nil { |
| 694 | + return sqltypes.Value{}, err |
| 695 | + } |
| 696 | + |
| 697 | + return sqltypes.MakeTrusted(sqltypes.Char, []byte(v.(string))), nil |
| 698 | +} |
| 699 | + |
| 700 | +// Converts any value that can be casted to a string |
| 701 | +func (t charT) Convert(v interface{}) (interface{}, error) { |
| 702 | + val, err := cast.ToStringE(v) |
| 703 | + if err != nil { |
| 704 | + return nil, ErrConvertToSQL.New(t) |
| 705 | + } |
| 706 | + |
| 707 | + if len(val) > t.length { |
| 708 | + return nil, ErrCharTruncation.New(val, t.length) |
| 709 | + } |
| 710 | + return val, nil |
| 711 | +} |
| 712 | + |
| 713 | +// Compares two strings lexicographically |
| 714 | +func (t charT) Compare(a interface{}, b interface{}) (int, error) { |
| 715 | + return strings.Compare(a.(string), b.(string)), nil |
| 716 | +} |
| 717 | + |
| 718 | + |
663 | 719 | type varCharT struct { |
664 | 720 | length int |
665 | 721 | } |
@@ -1088,7 +1144,13 @@ func IsDecimal(t Type) bool { |
1088 | 1144 |
|
1089 | 1145 | // IsText checks if t is a text type. |
1090 | 1146 | func IsText(t Type) bool { |
1091 | | - return t == Text || t == Blob || t == JSON || IsVarChar(t) |
| 1147 | + return t == Text || t == Blob || t == JSON || IsVarChar(t) || IsChar(t) |
| 1148 | +} |
| 1149 | + |
| 1150 | +// IsChar checks if t is a Char type. |
| 1151 | +func IsChar(t Type) bool { |
| 1152 | + _, ok := t.(charT) |
| 1153 | + return ok |
1092 | 1154 | } |
1093 | 1155 |
|
1094 | 1156 | // IsVarChar checks if t is a varchar type. |
@@ -1150,6 +1212,8 @@ func MySQLTypeName(t Type) string { |
1150 | 1212 | return "DATETIME" |
1151 | 1213 | case sqltypes.Date: |
1152 | 1214 | return "DATE" |
| 1215 | + case sqltypes.Char: |
| 1216 | + return "CHAR" |
1153 | 1217 | case sqltypes.VarChar: |
1154 | 1218 | return "VARCHAR" |
1155 | 1219 | case sqltypes.Text: |
|
0 commit comments