Skip to content

Commit 4e1c200

Browse files
committed
Merge remote-tracking branch 'upstream/master' into connect_attr
2 parents 9071539 + a841e81 commit 4e1c200

File tree

5 files changed

+128
-55
lines changed

5 files changed

+128
-55
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Dave Protasowski <dprotaso at gmail.com>
3333
DisposaBoy <disposaboy at dby.me>
3434
Egor Smolyakov <egorsmkv at gmail.com>
3535
Erwan Martin <hello at erwan.io>
36+
Evan Elias <evan at skeema.net>
3637
Evan Shaw <evan at vendhq.com>
3738
Frederick Mayle <frederickmayle at gmail.com>
3839
Gustavo Kristic <gkristic at gmail.com>

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ user:password@/
474474
The connection pool is managed by Go's database/sql package. For details on how to configure the size of the pool and how long connections stay in the pool see `*DB.SetMaxOpenConns`, `*DB.SetMaxIdleConns`, and `*DB.SetConnMaxLifetime` in the [database/sql documentation](https://golang.org/pkg/database/sql/). The read, write, and dial timeouts for each individual connection are configured with the DSN parameters [`readTimeout`](#readtimeout), [`writeTimeout`](#writetimeout), and [`timeout`](#timeout), respectively.
475475

476476
## `ColumnType` Support
477-
This driver supports the [`ColumnType` interface](https://golang.org/pkg/database/sql/#ColumnType) introduced in Go 1.8, with the exception of [`ColumnType.Length()`](https://golang.org/pkg/database/sql/#ColumnType.Length), which is currently not supported. All Unsigned database type names will be returned `UNSIGNED ` with `INT`, `TINYINT`, `SMALLINT`, `BIGINT`.
477+
This driver supports the [`ColumnType` interface](https://golang.org/pkg/database/sql/#ColumnType) introduced in Go 1.8, with the exception of [`ColumnType.Length()`](https://golang.org/pkg/database/sql/#ColumnType.Length), which is currently not supported. All Unsigned database type names will be returned `UNSIGNED ` with `INT`, `TINYINT`, `SMALLINT`, `MEDIUMINT`, `BIGINT`.
478478

479479
## `context.Context` Support
480480
Go 1.8 added `database/sql` support for `context.Context`. This driver supports query timeouts and cancellation via contexts.

benchmark_test.go

+56
Original file line numberDiff line numberDiff line change
@@ -372,3 +372,59 @@ func BenchmarkQueryRawBytes(b *testing.B) {
372372
})
373373
}
374374
}
375+
376+
// BenchmarkReceiveMassiveRows measures performance of receiving large number of rows.
377+
func BenchmarkReceiveMassiveRows(b *testing.B) {
378+
// Setup -- prepare 10000 rows.
379+
db := initDB(b,
380+
"DROP TABLE IF EXISTS foo",
381+
"CREATE TABLE foo (id INT PRIMARY KEY, val TEXT)")
382+
defer db.Close()
383+
384+
sval := strings.Repeat("x", 50)
385+
stmt, err := db.Prepare(`INSERT INTO foo (id, val) VALUES (?, ?)` + strings.Repeat(",(?,?)", 99))
386+
if err != nil {
387+
b.Errorf("failed to prepare query: %v", err)
388+
return
389+
}
390+
for i := 0; i < 10000; i += 100 {
391+
args := make([]any, 200)
392+
for j := 0; j < 100; j++ {
393+
args[j*2] = i + j
394+
args[j*2+1] = sval
395+
}
396+
_, err := stmt.Exec(args...)
397+
if err != nil {
398+
b.Error(err)
399+
return
400+
}
401+
}
402+
stmt.Close()
403+
404+
// Use b.Run() to skip expensive setup.
405+
b.Run("query", func(b *testing.B) {
406+
b.ReportAllocs()
407+
408+
for i := 0; i < b.N; i++ {
409+
rows, err := db.Query(`SELECT id, val FROM foo`)
410+
if err != nil {
411+
b.Errorf("failed to select: %v", err)
412+
return
413+
}
414+
for rows.Next() {
415+
var i int
416+
var s sql.RawBytes
417+
err = rows.Scan(&i, &s)
418+
if err != nil {
419+
b.Errorf("failed to scan: %v", err)
420+
_ = rows.Close()
421+
return
422+
}
423+
}
424+
if err = rows.Err(); err != nil {
425+
b.Errorf("failed to read rows: %v", err)
426+
}
427+
_ = rows.Close()
428+
}
429+
})
430+
}

driver_test.go

+39-34
Original file line numberDiff line numberDiff line change
@@ -2778,13 +2778,18 @@ func TestRowsColumnTypes(t *testing.T) {
27782778
nd1 := sql.NullTime{Time: time.Date(2006, 01, 02, 0, 0, 0, 0, time.UTC), Valid: true}
27792779
nd2 := sql.NullTime{Time: time.Date(2006, 03, 04, 0, 0, 0, 0, time.UTC), Valid: true}
27802780
ndNULL := sql.NullTime{Time: time.Time{}, Valid: false}
2781-
rbNULL := sql.RawBytes(nil)
2782-
rb0 := sql.RawBytes("0")
2783-
rb42 := sql.RawBytes("42")
2784-
rbTest := sql.RawBytes("Test")
2785-
rb0pad4 := sql.RawBytes("0\x00\x00\x00") // BINARY right-pads values with 0x00
2786-
rbx0 := sql.RawBytes("\x00")
2787-
rbx42 := sql.RawBytes("\x42")
2781+
bNULL := []byte(nil)
2782+
nsNULL := sql.NullString{String: "", Valid: false}
2783+
// Helper function to build NullString from string literal.
2784+
ns := func(s string) sql.NullString { return sql.NullString{String: s, Valid: true} }
2785+
ns0 := ns("0")
2786+
b0 := []byte("0")
2787+
b42 := []byte("42")
2788+
nsTest := ns("Test")
2789+
bTest := []byte("Test")
2790+
b0pad4 := []byte("0\x00\x00\x00") // BINARY right-pads values with 0x00
2791+
bx0 := []byte("\x00")
2792+
bx42 := []byte("\x42")
27882793

27892794
var columns = []struct {
27902795
name string
@@ -2797,7 +2802,7 @@ func TestRowsColumnTypes(t *testing.T) {
27972802
valuesIn [3]string
27982803
valuesOut [3]interface{}
27992804
}{
2800-
{"bit8null", "BIT(8)", "BIT", scanTypeRawBytes, true, 0, 0, [3]string{"0x0", "NULL", "0x42"}, [3]interface{}{rbx0, rbNULL, rbx42}},
2805+
{"bit8null", "BIT(8)", "BIT", scanTypeBytes, true, 0, 0, [3]string{"0x0", "NULL", "0x42"}, [3]interface{}{bx0, bNULL, bx42}},
28012806
{"boolnull", "BOOL", "TINYINT", scanTypeNullInt, true, 0, 0, [3]string{"NULL", "true", "0"}, [3]interface{}{niNULL, ni1, ni0}},
28022807
{"bool", "BOOL NOT NULL", "TINYINT", scanTypeInt8, false, 0, 0, [3]string{"1", "0", "FALSE"}, [3]interface{}{int8(1), int8(0), int8(0)}},
28032808
{"intnull", "INTEGER", "INT", scanTypeNullInt, true, 0, 0, [3]string{"0", "NULL", "42"}, [3]interface{}{ni0, niNULL, ni42}},
@@ -2811,30 +2816,31 @@ func TestRowsColumnTypes(t *testing.T) {
28112816
{"tinyuint", "TINYINT UNSIGNED NOT NULL", "UNSIGNED TINYINT", scanTypeUint8, false, 0, 0, [3]string{"0", "255", "42"}, [3]interface{}{uint8(0), uint8(255), uint8(42)}},
28122817
{"smalluint", "SMALLINT UNSIGNED NOT NULL", "UNSIGNED SMALLINT", scanTypeUint16, false, 0, 0, [3]string{"0", "65535", "42"}, [3]interface{}{uint16(0), uint16(65535), uint16(42)}},
28132818
{"biguint", "BIGINT UNSIGNED NOT NULL", "UNSIGNED BIGINT", scanTypeUint64, false, 0, 0, [3]string{"0", "65535", "42"}, [3]interface{}{uint64(0), uint64(65535), uint64(42)}},
2819+
{"mediumuint", "MEDIUMINT UNSIGNED NOT NULL", "UNSIGNED MEDIUMINT", scanTypeUint32, false, 0, 0, [3]string{"0", "16777215", "42"}, [3]interface{}{uint32(0), uint32(16777215), uint32(42)}},
28142820
{"uint13", "INT(13) UNSIGNED NOT NULL", "UNSIGNED INT", scanTypeUint32, false, 0, 0, [3]string{"0", "1337", "42"}, [3]interface{}{uint32(0), uint32(1337), uint32(42)}},
28152821
{"float", "FLOAT NOT NULL", "FLOAT", scanTypeFloat32, false, math.MaxInt64, math.MaxInt64, [3]string{"0", "42", "13.37"}, [3]interface{}{float32(0), float32(42), float32(13.37)}},
28162822
{"floatnull", "FLOAT", "FLOAT", scanTypeNullFloat, true, math.MaxInt64, math.MaxInt64, [3]string{"0", "NULL", "13.37"}, [3]interface{}{nf0, nfNULL, nf1337}},
28172823
{"float74null", "FLOAT(7,4)", "FLOAT", scanTypeNullFloat, true, math.MaxInt64, 4, [3]string{"0", "NULL", "13.37"}, [3]interface{}{nf0, nfNULL, nf1337}},
28182824
{"double", "DOUBLE NOT NULL", "DOUBLE", scanTypeFloat64, false, math.MaxInt64, math.MaxInt64, [3]string{"0", "42", "13.37"}, [3]interface{}{float64(0), float64(42), float64(13.37)}},
28192825
{"doublenull", "DOUBLE", "DOUBLE", scanTypeNullFloat, true, math.MaxInt64, math.MaxInt64, [3]string{"0", "NULL", "13.37"}, [3]interface{}{nf0, nfNULL, nf1337}},
2820-
{"decimal1", "DECIMAL(10,6) NOT NULL", "DECIMAL", scanTypeRawBytes, false, 10, 6, [3]string{"0", "13.37", "1234.123456"}, [3]interface{}{sql.RawBytes("0.000000"), sql.RawBytes("13.370000"), sql.RawBytes("1234.123456")}},
2821-
{"decimal1null", "DECIMAL(10,6)", "DECIMAL", scanTypeRawBytes, true, 10, 6, [3]string{"0", "NULL", "1234.123456"}, [3]interface{}{sql.RawBytes("0.000000"), rbNULL, sql.RawBytes("1234.123456")}},
2822-
{"decimal2", "DECIMAL(8,4) NOT NULL", "DECIMAL", scanTypeRawBytes, false, 8, 4, [3]string{"0", "13.37", "1234.123456"}, [3]interface{}{sql.RawBytes("0.0000"), sql.RawBytes("13.3700"), sql.RawBytes("1234.1235")}},
2823-
{"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")}},
2824-
{"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")}},
2825-
{"decimal3null", "DECIMAL(5,0)", "DECIMAL", scanTypeRawBytes, true, 5, 0, [3]string{"0", "NULL", "-12345.123456"}, [3]interface{}{rb0, rbNULL, sql.RawBytes("-12345")}},
2826-
{"char25null", "CHAR(25)", "CHAR", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2827-
{"varchar42", "VARCHAR(42) NOT NULL", "VARCHAR", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2828-
{"binary4null", "BINARY(4)", "BINARY", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0pad4, rbNULL, rbTest}},
2829-
{"varbinary42", "VARBINARY(42) NOT NULL", "VARBINARY", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2830-
{"tinyblobnull", "TINYBLOB", "BLOB", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2831-
{"tinytextnull", "TINYTEXT", "TEXT", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2832-
{"blobnull", "BLOB", "BLOB", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2833-
{"textnull", "TEXT", "TEXT", scanTypeRawBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{rb0, rbNULL, rbTest}},
2834-
{"mediumblob", "MEDIUMBLOB NOT NULL", "BLOB", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2835-
{"mediumtext", "MEDIUMTEXT NOT NULL", "TEXT", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2836-
{"longblob", "LONGBLOB NOT NULL", "BLOB", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2837-
{"longtext", "LONGTEXT NOT NULL", "TEXT", scanTypeRawBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{rb0, rbTest, rb42}},
2826+
{"decimal1", "DECIMAL(10,6) NOT NULL", "DECIMAL", scanTypeString, false, 10, 6, [3]string{"0", "13.37", "1234.123456"}, [3]interface{}{"0.000000", "13.370000", "1234.123456"}},
2827+
{"decimal1null", "DECIMAL(10,6)", "DECIMAL", scanTypeNullString, true, 10, 6, [3]string{"0", "NULL", "1234.123456"}, [3]interface{}{ns("0.000000"), nsNULL, ns("1234.123456")}},
2828+
{"decimal2", "DECIMAL(8,4) NOT NULL", "DECIMAL", scanTypeString, false, 8, 4, [3]string{"0", "13.37", "1234.123456"}, [3]interface{}{"0.0000", "13.3700", "1234.1235"}},
2829+
{"decimal2null", "DECIMAL(8,4)", "DECIMAL", scanTypeNullString, true, 8, 4, [3]string{"0", "NULL", "1234.123456"}, [3]interface{}{ns("0.0000"), nsNULL, ns("1234.1235")}},
2830+
{"decimal3", "DECIMAL(5,0) NOT NULL", "DECIMAL", scanTypeString, false, 5, 0, [3]string{"0", "13.37", "-12345.123456"}, [3]interface{}{"0", "13", "-12345"}},
2831+
{"decimal3null", "DECIMAL(5,0)", "DECIMAL", scanTypeNullString, true, 5, 0, [3]string{"0", "NULL", "-12345.123456"}, [3]interface{}{ns0, nsNULL, ns("-12345")}},
2832+
{"char25null", "CHAR(25)", "CHAR", scanTypeNullString, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{ns0, nsNULL, nsTest}},
2833+
{"varchar42", "VARCHAR(42) NOT NULL", "VARCHAR", scanTypeString, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{"0", "Test", "42"}},
2834+
{"binary4null", "BINARY(4)", "BINARY", scanTypeBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{b0pad4, bNULL, bTest}},
2835+
{"varbinary42", "VARBINARY(42) NOT NULL", "VARBINARY", scanTypeBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{b0, bTest, b42}},
2836+
{"tinyblobnull", "TINYBLOB", "BLOB", scanTypeBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{b0, bNULL, bTest}},
2837+
{"tinytextnull", "TINYTEXT", "TEXT", scanTypeNullString, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{ns0, nsNULL, nsTest}},
2838+
{"blobnull", "BLOB", "BLOB", scanTypeBytes, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{b0, bNULL, bTest}},
2839+
{"textnull", "TEXT", "TEXT", scanTypeNullString, true, 0, 0, [3]string{"0", "NULL", "'Test'"}, [3]interface{}{ns0, nsNULL, nsTest}},
2840+
{"mediumblob", "MEDIUMBLOB NOT NULL", "BLOB", scanTypeBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{b0, bTest, b42}},
2841+
{"mediumtext", "MEDIUMTEXT NOT NULL", "TEXT", scanTypeString, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{"0", "Test", "42"}},
2842+
{"longblob", "LONGBLOB NOT NULL", "BLOB", scanTypeBytes, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{b0, bTest, b42}},
2843+
{"longtext", "LONGTEXT NOT NULL", "TEXT", scanTypeString, false, 0, 0, [3]string{"0", "'Test'", "42"}, [3]interface{}{"0", "Test", "42"}},
28382844
{"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}},
28392845
{"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}},
28402846
{"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}},
@@ -2945,7 +2951,10 @@ func TestRowsColumnTypes(t *testing.T) {
29452951
continue
29462952
}
29472953
}
2948-
2954+
// Avoid panic caused by nil scantype.
2955+
if t.Failed() {
2956+
return
2957+
}
29492958
values := make([]interface{}, len(tt))
29502959
for i := range values {
29512960
values[i] = reflect.New(types[i]).Interface()
@@ -2956,14 +2965,10 @@ func TestRowsColumnTypes(t *testing.T) {
29562965
if err != nil {
29572966
t.Fatalf("failed to scan values in %v", err)
29582967
}
2959-
for j := range values {
2960-
value := reflect.ValueOf(values[j]).Elem().Interface()
2968+
for j, value := range values {
2969+
value := reflect.ValueOf(value).Elem().Interface()
29612970
if !reflect.DeepEqual(value, columns[j].valuesOut[i]) {
2962-
if columns[j].scanType == scanTypeRawBytes {
2963-
t.Errorf("row %d, column %d: %v != %v", i, j, string(value.(sql.RawBytes)), string(columns[j].valuesOut[i].(sql.RawBytes)))
2964-
} else {
2965-
t.Errorf("row %d, column %d: %v != %v", i, j, value, columns[j].valuesOut[i])
2966-
}
2971+
t.Errorf("row %d, column %d: %v != %v", i, j, value, columns[j].valuesOut[i])
29672972
}
29682973
}
29692974
i++

fields.go

+31-20
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ func (mf *mysqlField) typeDatabaseName() string {
3737
case fieldTypeGeometry:
3838
return "GEOMETRY"
3939
case fieldTypeInt24:
40+
if mf.flags&flagUnsigned != 0 {
41+
return "UNSIGNED MEDIUMINT"
42+
}
4043
return "MEDIUMINT"
4144
case fieldTypeJSON:
4245
return "JSON"
@@ -110,21 +113,23 @@ func (mf *mysqlField) typeDatabaseName() string {
110113
}
111114

112115
var (
113-
scanTypeFloat32 = reflect.TypeOf(float32(0))
114-
scanTypeFloat64 = reflect.TypeOf(float64(0))
115-
scanTypeInt8 = reflect.TypeOf(int8(0))
116-
scanTypeInt16 = reflect.TypeOf(int16(0))
117-
scanTypeInt32 = reflect.TypeOf(int32(0))
118-
scanTypeInt64 = reflect.TypeOf(int64(0))
119-
scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
120-
scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
121-
scanTypeNullTime = reflect.TypeOf(sql.NullTime{})
122-
scanTypeUint8 = reflect.TypeOf(uint8(0))
123-
scanTypeUint16 = reflect.TypeOf(uint16(0))
124-
scanTypeUint32 = reflect.TypeOf(uint32(0))
125-
scanTypeUint64 = reflect.TypeOf(uint64(0))
126-
scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
127-
scanTypeUnknown = reflect.TypeOf(new(interface{}))
116+
scanTypeFloat32 = reflect.TypeOf(float32(0))
117+
scanTypeFloat64 = reflect.TypeOf(float64(0))
118+
scanTypeInt8 = reflect.TypeOf(int8(0))
119+
scanTypeInt16 = reflect.TypeOf(int16(0))
120+
scanTypeInt32 = reflect.TypeOf(int32(0))
121+
scanTypeInt64 = reflect.TypeOf(int64(0))
122+
scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
123+
scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
124+
scanTypeNullTime = reflect.TypeOf(sql.NullTime{})
125+
scanTypeUint8 = reflect.TypeOf(uint8(0))
126+
scanTypeUint16 = reflect.TypeOf(uint16(0))
127+
scanTypeUint32 = reflect.TypeOf(uint32(0))
128+
scanTypeUint64 = reflect.TypeOf(uint64(0))
129+
scanTypeString = reflect.TypeOf("")
130+
scanTypeNullString = reflect.TypeOf(sql.NullString{})
131+
scanTypeBytes = reflect.TypeOf([]byte{})
132+
scanTypeUnknown = reflect.TypeOf(new(interface{}))
128133
)
129134

130135
type mysqlField struct {
@@ -187,12 +192,18 @@ func (mf *mysqlField) scanType() reflect.Type {
187192
}
188193
return scanTypeNullFloat
189194

195+
case fieldTypeBit, fieldTypeTinyBLOB, fieldTypeMediumBLOB, fieldTypeLongBLOB,
196+
fieldTypeBLOB, fieldTypeVarString, fieldTypeString, fieldTypeGeometry:
197+
if mf.charSet == 63 /* binary */ {
198+
return scanTypeBytes
199+
}
200+
fallthrough
190201
case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
191-
fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
192-
fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
193-
fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON,
194-
fieldTypeTime:
195-
return scanTypeRawBytes
202+
fieldTypeEnum, fieldTypeSet, fieldTypeJSON, fieldTypeTime:
203+
if mf.flags&flagNotNULL != 0 {
204+
return scanTypeString
205+
}
206+
return scanTypeNullString
196207

197208
case fieldTypeDate, fieldTypeNewDate,
198209
fieldTypeTimestamp, fieldTypeDateTime:

0 commit comments

Comments
 (0)