Skip to content

Commit fdd0987

Browse files
committed
Merge remote-tracking branch 'upstream/master' into fix_bigint_unsigned_scan_type
2 parents 4a5269c + f62f523 commit fdd0987

File tree

11 files changed

+83
-72
lines changed

11 files changed

+83
-72
lines changed

Diff for: .github/workflows/test.yml

+3-5
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- uses: actions/checkout@v4
18-
- uses: dominikh/[email protected]
19-
with:
20-
version: "2023.1.6"
18+
- uses: dominikh/[email protected]
2119

2220
list:
2321
runs-on: ubuntu-latest
@@ -31,10 +29,10 @@ jobs:
3129
import os
3230
go = [
3331
# Keep the most recent production release at the top
34-
'1.22',
32+
'1.23',
3533
# Older production releases
34+
'1.22',
3635
'1.21',
37-
'1.20',
3836
]
3937
mysql = [
4038
'9.0',

Diff for: AUTHORS

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ ICHINOSE Shogo <shogo82148 at gmail.com>
5151
Ilia Cimpoes <ichimpoesh at gmail.com>
5252
INADA Naoki <songofacandy at gmail.com>
5353
Jacek Szwec <szwec.jacek at gmail.com>
54+
Jakub Adamus <kratky at zobak.cz>
5455
James Harr <james.harr at gmail.com>
5556
Janek Vedock <janekvedock at comcast.net>
5657
Jason Ng <oblitorum at gmail.com>
@@ -81,6 +82,7 @@ Lunny Xiao <xiaolunwen at gmail.com>
8182
Luke Scott <luke at webconnex.com>
8283
Maciej Zimnoch <maciej.zimnoch at codilime.com>
8384
Michael Woolnough <michael.woolnough at gmail.com>
85+
Nao Yokotsuka <yokotukanao at gmail.com>
8486
Nathanial Murphy <nathanial.murphy at gmail.com>
8587
Nicola Peduzzi <thenikso at gmail.com>
8688
Oliver Bone <owbone at github.com>

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) pac
4141

4242
## Requirements
4343

44-
* Go 1.20 or higher. We aim to support the 3 latest versions of Go.
44+
* Go 1.21 or higher. We aim to support the 3 latest versions of Go.
4545
* MySQL (5.7+) and MariaDB (10.5+) are supported.
4646
* [TiDB](https://github.com/pingcap/tidb) is supported by PingCAP.
4747
* Do not ask questions about TiDB in our issue tracker or forum.

Diff for: collations.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
package mysql
1010

11-
const defaultCollation = "utf8mb4_general_ci"
11+
const defaultCollationID = 45 // utf8mb4_general_ci
1212
const binaryCollationID = 63
1313

1414
// A list of available collations mapped to the internal ID.

Diff for: connection.go

+9-34
Original file line numberDiff line numberDiff line change
@@ -67,45 +67,20 @@ func (mc *mysqlConn) handleParams() (err error) {
6767
var cmdSet strings.Builder
6868

6969
for param, val := range mc.cfg.Params {
70-
switch param {
71-
// Charset: character_set_connection, character_set_client, character_set_results
72-
case "charset":
73-
charsets := strings.Split(val, ",")
74-
for _, cs := range charsets {
75-
// ignore errors here - a charset may not exist
76-
if mc.cfg.Collation != "" {
77-
err = mc.exec("SET NAMES " + cs + " COLLATE " + mc.cfg.Collation)
78-
} else {
79-
err = mc.exec("SET NAMES " + cs)
80-
}
81-
if err == nil {
82-
break
83-
}
84-
}
85-
if err != nil {
86-
return
87-
}
88-
89-
// Other system vars accumulated in a single SET command
90-
default:
91-
if cmdSet.Len() == 0 {
92-
// Heuristic: 29 chars for each other key=value to reduce reallocations
93-
cmdSet.Grow(4 + len(param) + 3 + len(val) + 30*(len(mc.cfg.Params)-1))
94-
cmdSet.WriteString("SET ")
95-
} else {
96-
cmdSet.WriteString(", ")
97-
}
98-
cmdSet.WriteString(param)
99-
cmdSet.WriteString(" = ")
100-
cmdSet.WriteString(val)
70+
if cmdSet.Len() == 0 {
71+
// Heuristic: 29 chars for each other key=value to reduce reallocations
72+
cmdSet.Grow(4 + len(param) + 3 + len(val) + 30*(len(mc.cfg.Params)-1))
73+
cmdSet.WriteString("SET ")
74+
} else {
75+
cmdSet.WriteString(", ")
10176
}
77+
cmdSet.WriteString(param)
78+
cmdSet.WriteString(" = ")
79+
cmdSet.WriteString(val)
10280
}
10381

10482
if cmdSet.Len() > 0 {
10583
err = mc.exec(cmdSet.String())
106-
if err != nil {
107-
return
108-
}
10984
}
11085

11186
return

Diff for: connector.go

+37-13
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,25 @@ func (c *connector) Connect(ctx context.Context) (driver.Conn, error) {
8787
mc.parseTime = mc.cfg.ParseTime
8888

8989
// Connect to Server
90-
dialsLock.RLock()
91-
dial, ok := dials[mc.cfg.Net]
92-
dialsLock.RUnlock()
93-
if ok {
94-
dctx := ctx
95-
if mc.cfg.Timeout > 0 {
96-
var cancel context.CancelFunc
97-
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
98-
defer cancel()
99-
}
100-
mc.netConn, err = dial(dctx, mc.cfg.Addr)
90+
dctx := ctx
91+
if mc.cfg.Timeout > 0 {
92+
var cancel context.CancelFunc
93+
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
94+
defer cancel()
95+
}
96+
97+
if c.cfg.DialFunc != nil {
98+
mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Net, mc.cfg.Addr)
10199
} else {
102-
nd := net.Dialer{Timeout: mc.cfg.Timeout}
103-
mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
100+
dialsLock.RLock()
101+
dial, ok := dials[mc.cfg.Net]
102+
dialsLock.RUnlock()
103+
if ok {
104+
mc.netConn, err = dial(dctx, mc.cfg.Addr)
105+
} else {
106+
nd := net.Dialer{}
107+
mc.netConn, err = nd.DialContext(dctx, mc.cfg.Net, mc.cfg.Addr)
108+
}
104109
}
105110
if err != nil {
106111
return nil, err
@@ -180,6 +185,25 @@ func (c *connector) Connect(ctx context.Context) (driver.Conn, error) {
180185
mc.maxWriteSize = mc.maxAllowedPacket
181186
}
182187

188+
// Charset: character_set_connection, character_set_client, character_set_results
189+
if len(mc.cfg.charsets) > 0 {
190+
for _, cs := range mc.cfg.charsets {
191+
// ignore errors here - a charset may not exist
192+
if mc.cfg.Collation != "" {
193+
err = mc.exec("SET NAMES " + cs + " COLLATE " + mc.cfg.Collation)
194+
} else {
195+
err = mc.exec("SET NAMES " + cs)
196+
}
197+
if err == nil {
198+
break
199+
}
200+
}
201+
if err != nil {
202+
mc.Close()
203+
return nil, err
204+
}
205+
}
206+
183207
// Handle DSN Params
184208
err = mc.handleParams()
185209
if err != nil {

Diff for: dsn.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ type Config struct {
4444
DBName string // Database name
4545
Params map[string]string // Connection parameters
4646
ConnectionAttributes string // Connection Attributes, comma-delimited string of user-defined "key:value" pairs
47-
Collation string // Connection collation
47+
charsets []string // Connection charset. When set, this will be set in SET NAMES <charset> query
48+
Collation string // Connection collation. When set, this will be set in SET NAMES <charset> COLLATE <collation> query
4849
Loc *time.Location // Location for time.Time values
4950
MaxAllowedPacket int // Max packet size allowed
5051
ServerPubKey string // Server public key name
@@ -54,6 +55,8 @@ type Config struct {
5455
ReadTimeout time.Duration // I/O read timeout
5556
WriteTimeout time.Duration // I/O write timeout
5657
Logger Logger // Logger
58+
// DialFunc specifies the dial function for creating connections
59+
DialFunc func(ctx context.Context, network, addr string) (net.Conn, error)
5760

5861
// boolean fields
5962

@@ -282,6 +285,10 @@ func (cfg *Config) FormatDSN() string {
282285
writeDSNParam(&buf, &hasParam, "clientFoundRows", "true")
283286
}
284287

288+
if charsets := cfg.charsets; len(charsets) > 0 {
289+
writeDSNParam(&buf, &hasParam, "charset", strings.Join(charsets, ","))
290+
}
291+
285292
if col := cfg.Collation; col != "" {
286293
writeDSNParam(&buf, &hasParam, "collation", col)
287294
}
@@ -501,6 +508,10 @@ func parseDSNParams(cfg *Config, params string) (err error) {
501508
return errors.New("invalid bool value: " + value)
502509
}
503510

511+
// charset
512+
case "charset":
513+
cfg.charsets = strings.Split(value, ",")
514+
504515
// Collation
505516
case "collation":
506517
cfg.Collation = value

Diff for: dsn_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ var testDSNs = []struct {
3131
&Config{User: "username", Passwd: "password", Net: "protocol", Addr: "address", DBName: "dbname", Params: map[string]string{"param": "value"}, Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, Logger: defaultLogger, AllowNativePasswords: true, CheckConnLiveness: true, ColumnsWithAlias: true, MultiStatements: true},
3232
}, {
3333
"user@unix(/path/to/socket)/dbname?charset=utf8",
34-
&Config{User: "user", Net: "unix", Addr: "/path/to/socket", DBName: "dbname", Params: map[string]string{"charset": "utf8"}, Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, Logger: defaultLogger, AllowNativePasswords: true, CheckConnLiveness: true},
34+
&Config{User: "user", Net: "unix", Addr: "/path/to/socket", DBName: "dbname", charsets: []string{"utf8"}, Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, Logger: defaultLogger, AllowNativePasswords: true, CheckConnLiveness: true},
3535
}, {
3636
"user:password@tcp(localhost:5555)/dbname?charset=utf8&tls=true",
37-
&Config{User: "user", Passwd: "password", Net: "tcp", Addr: "localhost:5555", DBName: "dbname", Params: map[string]string{"charset": "utf8"}, Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, Logger: defaultLogger, AllowNativePasswords: true, CheckConnLiveness: true, TLSConfig: "true"},
37+
&Config{User: "user", Passwd: "password", Net: "tcp", Addr: "localhost:5555", DBName: "dbname", charsets: []string{"utf8"}, Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, Logger: defaultLogger, AllowNativePasswords: true, CheckConnLiveness: true, TLSConfig: "true"},
3838
}, {
3939
"user:password@tcp(localhost:5555)/dbname?charset=utf8mb4,utf8&tls=skip-verify",
40-
&Config{User: "user", Passwd: "password", Net: "tcp", Addr: "localhost:5555", DBName: "dbname", Params: map[string]string{"charset": "utf8mb4,utf8"}, Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, Logger: defaultLogger, AllowNativePasswords: true, CheckConnLiveness: true, TLSConfig: "skip-verify"},
40+
&Config{User: "user", Passwd: "password", Net: "tcp", Addr: "localhost:5555", DBName: "dbname", charsets: []string{"utf8mb4", "utf8"}, Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, Logger: defaultLogger, AllowNativePasswords: true, CheckConnLiveness: true, TLSConfig: "skip-verify"},
4141
}, {
4242
"user:password@/dbname?loc=UTC&timeout=30s&readTimeout=1s&writeTimeout=1s&allowAllFiles=1&clientFoundRows=true&allowOldPasswords=TRUE&collation=utf8mb4_unicode_ci&maxAllowedPacket=16777216&tls=false&allowCleartextPasswords=true&parseTime=true&rejectReadOnly=true",
4343
&Config{User: "user", Passwd: "password", Net: "tcp", Addr: "127.0.0.1:3306", DBName: "dbname", Collation: "utf8mb4_unicode_ci", Loc: time.UTC, TLSConfig: "false", AllowCleartextPasswords: true, AllowNativePasswords: true, Timeout: 30 * time.Second, ReadTimeout: time.Second, WriteTimeout: time.Second, Logger: defaultLogger, AllowAllFiles: true, AllowOldPasswords: true, CheckConnLiveness: true, ClientFoundRows: true, MaxAllowedPacket: 16777216, ParseTime: true, RejectReadOnly: true},

Diff for: go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module github.com/go-sql-driver/mysql
22

3-
go 1.20
3+
go 1.21
44

55
require filippo.io/edwards25519 v1.1.0

Diff for: packets.go

+13-12
Original file line numberDiff line numberDiff line change
@@ -322,17 +322,15 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string
322322
data[11] = 0x00
323323

324324
// Collation ID [1 byte]
325-
cname := mc.cfg.Collation
326-
if cname == "" {
327-
cname = defaultCollation
328-
}
329-
var found bool
330-
data[12], found = collations[cname]
331-
if !found {
332-
// Note possibility for false negatives:
333-
// could be triggered although the collation is valid if the
334-
// collations map does not contain entries the server supports.
335-
return fmt.Errorf("unknown collation: %q", cname)
325+
data[12] = defaultCollationID
326+
if cname := mc.cfg.Collation; cname != "" {
327+
colID, ok := collations[cname]
328+
if ok {
329+
data[12] = colID
330+
} else if len(mc.cfg.charsets) > 0 {
331+
// When cfg.charset is set, the collation is set by `SET NAMES <charset> COLLATE <collation>`.
332+
return fmt.Errorf("unknown collation: %q", cname)
333+
}
336334
}
337335

338336
// Filler [23 bytes] (all 0x00)
@@ -352,6 +350,9 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string
352350
// Switch to TLS
353351
tlsConn := tls.Client(mc.netConn, mc.cfg.TLS)
354352
if err := tlsConn.Handshake(); err != nil {
353+
if cerr := mc.canceled.Value(); cerr != nil {
354+
return cerr
355+
}
355356
return err
356357
}
357358
mc.netConn = tlsConn
@@ -391,7 +392,7 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string
391392
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
392393
func (mc *mysqlConn) writeAuthSwitchPacket(authData []byte) error {
393394
pktLen := 4 + len(authData)
394-
data, err := mc.buf.takeSmallBuffer(pktLen)
395+
data, err := mc.buf.takeBuffer(pktLen)
395396
if err != nil {
396397
// cannot take the buffer. Something must be wrong with the connection
397398
mc.log(err)

Diff for: utils_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ func TestAppendDateTime(t *testing.T) {
339339
buf, err := appendDateTime(buf, v.t, v.timeTruncate)
340340
if err != nil {
341341
if !v.expectedErr {
342-
t.Errorf("appendDateTime(%v) returned an errror: %v", v.t, err)
342+
t.Errorf("appendDateTime(%v) returned an error: %v", v.t, err)
343343
}
344344
continue
345345
}

0 commit comments

Comments
 (0)