Skip to content

Commit 5ee934f

Browse files
j-forstermethane
authored andcommitted
Add string type to ColumnTypeScanType(). (go-sql-driver#976)
ColumnTypeScanType() now returns string and sql.NullString.
1 parent 14bb9c0 commit 5ee934f

File tree

3 files changed

+42
-26
lines changed

3 files changed

+42
-26
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Jeff Hodges <jeff at somethingsimilar.com>
4545
Jeffrey Charles <jeffreycharles at gmail.com>
4646
Jerome Meyer <jxmeyer at gmail.com>
4747
Jian Zhen <zhenjl at gmail.com>
48+
Johann Forster <johannforster15 at gmail.com>
4849
Joshua Prunier <joshua.prunier at gmail.com>
4950
Julien Lefevre <julien.lefevr at gmail.com>
5051
Julien Schmidt <go-sql-driver at julienschmidt.com>

driver_test.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -2733,6 +2733,9 @@ func TestRowsColumnTypes(t *testing.T) {
27332733
rb0pad4 := sql.RawBytes("0\x00\x00\x00") // BINARY right-pads values with 0x00
27342734
rbx0 := sql.RawBytes("\x00")
27352735
rbx42 := sql.RawBytes("\x42")
2736+
s0 := sql.NullString{String: "0", Valid: true}
2737+
sNULL := sql.NullString{String: "", Valid: false}
2738+
sTest := sql.NullString{String: "Test", Valid: true}
27362739

27372740
var columns = []struct {
27382741
name string
@@ -2771,18 +2774,18 @@ func TestRowsColumnTypes(t *testing.T) {
27712774
{"decimal2null", "DECIMAL(8,4)", "DECIMAL", scanTypeRawBytes, true, 8, 4, [3]string{"0", "NULL", "1234.123456"}, [3]interface{}{sql.RawBytes("0.0000"), rbNULL, sql.RawBytes("1234.1235")}},
27722775
{"decimal3", "DECIMAL(5,0) NOT NULL", "DECIMAL", scanTypeRawBytes, false, 5, 0, [3]string{"0", "13.37", "-12345.123456"}, [3]interface{}{rb0, sql.RawBytes("13"), sql.RawBytes("-12345")}},
27732776
{"decimal3null", "DECIMAL(5,0)", "DECIMAL", scanTypeRawBytes, true, 5, 0, [3]string{"0", "NULL", "-12345.123456"}, [3]interface{}{rb0, rbNULL, sql.RawBytes("-12345")}},
2774-
{"char25null", "CHAR(25)", "CHAR", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2775-
{"varchar42", "VARCHAR(42) NOT NULL", "VARCHAR", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2777+
{"char25null", "CHAR(25)", "CHAR", scanTypeNullString, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{s0, sNULL, sTest}},
2778+
{"varchar42", "VARCHAR(42) NOT NULL", "VARCHAR", scanTypeString, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{"0", "Test", "42"}},
27762779
{"binary4null", "BINARY(4)", "BINARY", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0pad4, rbNULL, rbTest}},
27772780
{"varbinary42", "VARBINARY(42) NOT NULL", "VARBINARY", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
27782781
{"tinyblobnull", "TINYBLOB", "BLOB", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2779-
{"tinytextnull", "TINYTEXT", "TEXT", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2782+
{"tinytextnull", "TINYTEXT", "TEXT", scanTypeNullString, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{s0, sNULL, sTest}},
27802783
{"blobnull", "BLOB", "BLOB", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2781-
{"textnull", "TEXT", "TEXT", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2784+
{"textnull", "TEXT", "TEXT", scanTypeNullString, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{s0, sNULL, sTest}},
27822785
{"mediumblob", "MEDIUMBLOB NOT NULL", "BLOB", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2783-
{"mediumtext", "MEDIUMTEXT NOT NULL", "TEXT", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2786+
{"mediumtext", "MEDIUMTEXT NOT NULL", "TEXT", scanTypeString, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{"0", "Test", "42"}},
27842787
{"longblob", "LONGBLOB NOT NULL", "BLOB", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2785-
{"longtext", "LONGTEXT NOT NULL", "TEXT", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2788+
{"longtext", "LONGTEXT NOT NULL", "TEXT", scanTypeString, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{"0", "Test", "42"}},
27862789
{"datetime", "DATETIME", "DATETIME", scanTypeNullTime, true, 0, 0, [3]string{"'2006-01-02 15:04:05'", "'2006-01-02 15:04:05.1'", "'2006-01-02 15:04:05.111111'"}, [3]interface{}{nt0, nt0, nt0}},
27872790
{"datetime2", "DATETIME(2)", "DATETIME", scanTypeNullTime, true, 2, 2, [3]string{"'2006-01-02 15:04:05'", "'2006-01-02 15:04:05.1'", "'2006-01-02 15:04:05.111111'"}, [3]interface{}{nt0, nt1, nt2}},
27882791
{"datetime6", "DATETIME(6)", "DATETIME", scanTypeNullTime, true, 6, 6, [3]string{"'2006-01-02 15:04:05'", "'2006-01-02 15:04:05.1'", "'2006-01-02 15:04:05.111111'"}, [3]interface{}{nt0, nt1, nt6}},

fields.go

+32-20
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,23 @@ func (mf *mysqlField) typeDatabaseName() string {
9898
}
9999

100100
var (
101-
scanTypeFloat32 = reflect.TypeOf(float32(0))
102-
scanTypeFloat64 = reflect.TypeOf(float64(0))
103-
scanTypeInt8 = reflect.TypeOf(int8(0))
104-
scanTypeInt16 = reflect.TypeOf(int16(0))
105-
scanTypeInt32 = reflect.TypeOf(int32(0))
106-
scanTypeInt64 = reflect.TypeOf(int64(0))
107-
scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
108-
scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
109-
scanTypeNullTime = reflect.TypeOf(NullTime{})
110-
scanTypeUint8 = reflect.TypeOf(uint8(0))
111-
scanTypeUint16 = reflect.TypeOf(uint16(0))
112-
scanTypeUint32 = reflect.TypeOf(uint32(0))
113-
scanTypeUint64 = reflect.TypeOf(uint64(0))
114-
scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
115-
scanTypeUnknown = reflect.TypeOf(new(interface{}))
101+
scanTypeFloat32 = reflect.TypeOf(float32(0))
102+
scanTypeFloat64 = reflect.TypeOf(float64(0))
103+
scanTypeInt8 = reflect.TypeOf(int8(0))
104+
scanTypeInt16 = reflect.TypeOf(int16(0))
105+
scanTypeInt32 = reflect.TypeOf(int32(0))
106+
scanTypeInt64 = reflect.TypeOf(int64(0))
107+
scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
108+
scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
109+
scanTypeNullTime = reflect.TypeOf(NullTime{})
110+
scanTypeUint8 = reflect.TypeOf(uint8(0))
111+
scanTypeUint16 = reflect.TypeOf(uint16(0))
112+
scanTypeUint32 = reflect.TypeOf(uint32(0))
113+
scanTypeUint64 = reflect.TypeOf(uint64(0))
114+
scanTypeString = reflect.TypeOf(string(""))
115+
scanTypeNullString = reflect.TypeOf(sql.NullString{})
116+
scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
117+
scanTypeUnknown = reflect.TypeOf(new(interface{}))
116118
)
117119

118120
type mysqlField struct {
@@ -175,11 +177,21 @@ func (mf *mysqlField) scanType() reflect.Type {
175177
}
176178
return scanTypeNullFloat
177179

178-
case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
179-
fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
180-
fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
181-
fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON,
182-
fieldTypeTime:
180+
case fieldTypeVarChar, fieldTypeString, fieldTypeVarString, fieldTypeTinyBLOB,
181+
fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB:
182+
// charsetnr == 63 means this column is binary.
183+
// https://dev.mysql.com/doc/refman/8.0/en/c-api-data-structures.html
184+
if mf.charSet == 63 {
185+
return scanTypeRawBytes
186+
}
187+
if mf.flags&flagNotNULL != 0 {
188+
return scanTypeString
189+
}
190+
return scanTypeNullString
191+
192+
case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeBit,
193+
fieldTypeEnum, fieldTypeSet,
194+
fieldTypeGeometry, fieldTypeJSON, fieldTypeTime:
183195
return scanTypeRawBytes
184196

185197
case fieldTypeDate, fieldTypeNewDate,

0 commit comments

Comments
 (0)