go-sql-driver/mysql

`charset` option does not work.

Closed this issue · 1 comments

Since v1.9.0, when initializing sql.DB with the charset option set in config.Params as shown in the following code, an error occurs during query execution:

config := mysql.NewConfig()
config.Net = "tcp"
config.Addr = "127.0.0.1:3306"
// etc...
config.Params = map[string]string{
    "charset": "utf8mb4",
}

conn, err := mysql.NewConnector(config)
if err != nil {
    log.Fatal(err)
}
db := sql.OpenDB(conn)

if _, err := db.Exec("SELECT 1"); err != nil {
    log.Fatal(err)
}
// return Error 1193 (HY000): Unknown system variable 'charset'

However, it works without any issues when initialized using config.FormatDSN():

config := mysql.NewConfig()
config.Net = "tcp"
config.Addr = "127.0.0.1:3306"
// etc...
config.Params = map[string]string{
    "charset": "utf8mb4",
}
db, err := sql.Open("mysql", config.FormatDSN())
if err != nil {
    log.Fatal(err)
}

if _, err := db.Exec("SELECT 1"); err != nil {
    log.Fatal(err)
}

I believe this is due to the change in the timing of interpreting the charset option in #1604 .
In the current implementation, it is interpreted within the ParseDSN method and stored in the config.charsets field.

mysql/dsn.go

Lines 525 to 527 in 58941dd

// charset
case "charset":
cfg.charsets = strings.Split(value, ",")

However, in the way I wrote, the connection is created without going through the ParseDSN method, so charset is sent as an invalid option.

The charset option should be interpreted regardless of the connection establishment procedure.

Duplicate of #1664 and #1678.

See #1679 as fix PR.

And using mysql.ParseDSN("/?charset=utf8mb4") instead of mysql.NewConfig() is workaround for now.