diff --git a/go.mod b/go.mod index a377637d237..63db5213fac 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/eggsampler/acme/v3 v3.4.0 github.com/go-logr/stdr v1.2.2 github.com/go-redis/redis/v8 v8.11.5 - github.com/go-sql-driver/mysql v1.7.1 + github.com/go-sql-driver/mysql v1.5.0 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da github.com/google/certificate-transparency-go v1.1.4 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 @@ -94,7 +94,11 @@ require ( k8s.io/klog/v2 v2.80.1 // indirect ) +// Versions of go-sql-driver/mysql >1.5.0 introduce performance regressions for +// us, so we exclude them. + // This version is required by parts of the honeycombio/beeline-go package -// that we do not rely upon. It appears to introduce performance regressions -// for us. exclude github.com/go-sql-driver/mysql v1.6.0 + +// This version is required by borp +exclude github.com/go-sql-driver/mysql v1.7.1 diff --git a/go.sum b/go.sum index eb38cea048c..3497647eb2d 100644 --- a/go.sum +++ b/go.sum @@ -168,8 +168,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= diff --git a/vendor/github.com/go-sql-driver/mysql/.travis.yml b/vendor/github.com/go-sql-driver/mysql/.travis.yml new file mode 100644 index 00000000000..56fcf25f207 --- /dev/null +++ b/vendor/github.com/go-sql-driver/mysql/.travis.yml @@ -0,0 +1,129 @@ +sudo: false +language: go +go: + - 1.10.x + - 1.11.x + - 1.12.x + - 1.13.x + - master + +before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + +before_script: + - echo -e "[server]\ninnodb_log_file_size=256MB\ninnodb_buffer_pool_size=512MB\nmax_allowed_packet=16MB" | sudo tee -a /etc/mysql/my.cnf + - sudo service mysql restart + - .travis/wait_mysql.sh + - mysql -e 'create database gotest;' + +matrix: + include: + - env: DB=MYSQL8 + sudo: required + dist: trusty + go: 1.10.x + services: + - docker + before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - docker pull mysql:8.0 + - docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret + mysql:8.0 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1 + - cp .travis/docker.cnf ~/.my.cnf + - .travis/wait_mysql.sh + before_script: + - export MYSQL_TEST_USER=gotest + - export MYSQL_TEST_PASS=secret + - export MYSQL_TEST_ADDR=127.0.0.1:3307 + - export MYSQL_TEST_CONCURRENT=1 + + - env: DB=MYSQL57 + sudo: required + dist: trusty + go: 1.10.x + services: + - docker + before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - docker pull mysql:5.7 + - docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret + mysql:5.7 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1 + - cp .travis/docker.cnf ~/.my.cnf + - .travis/wait_mysql.sh + before_script: + - export MYSQL_TEST_USER=gotest + - export MYSQL_TEST_PASS=secret + - export MYSQL_TEST_ADDR=127.0.0.1:3307 + - export MYSQL_TEST_CONCURRENT=1 + + - env: DB=MARIA55 + sudo: required + dist: trusty + go: 1.10.x + services: + - docker + before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - docker pull mariadb:5.5 + - docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret + mariadb:5.5 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1 + - cp .travis/docker.cnf ~/.my.cnf + - .travis/wait_mysql.sh + before_script: + - export MYSQL_TEST_USER=gotest + - export MYSQL_TEST_PASS=secret + - export MYSQL_TEST_ADDR=127.0.0.1:3307 + - export MYSQL_TEST_CONCURRENT=1 + + - env: DB=MARIA10_1 + sudo: required + dist: trusty + go: 1.10.x + services: + - docker + before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - docker pull mariadb:10.1 + - docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret + mariadb:10.1 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1 + - cp .travis/docker.cnf ~/.my.cnf + - .travis/wait_mysql.sh + before_script: + - export MYSQL_TEST_USER=gotest + - export MYSQL_TEST_PASS=secret + - export MYSQL_TEST_ADDR=127.0.0.1:3307 + - export MYSQL_TEST_CONCURRENT=1 + + - os: osx + osx_image: xcode10.1 + addons: + homebrew: + packages: + - mysql + update: true + go: 1.12.x + before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + before_script: + - echo -e "[server]\ninnodb_log_file_size=256MB\ninnodb_buffer_pool_size=512MB\nmax_allowed_packet=16MB\nlocal_infile=1" >> /usr/local/etc/my.cnf + - mysql.server start + - mysql -uroot -e 'CREATE USER gotest IDENTIFIED BY "secret"' + - mysql -uroot -e 'GRANT ALL ON *.* TO gotest' + - mysql -uroot -e 'create database gotest;' + - export MYSQL_TEST_USER=gotest + - export MYSQL_TEST_PASS=secret + - export MYSQL_TEST_ADDR=127.0.0.1:3306 + - export MYSQL_TEST_CONCURRENT=1 + +script: + - go test -v -covermode=count -coverprofile=coverage.out + - go vet ./... + - .travis/gofmt.sh +after_script: + - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci diff --git a/vendor/github.com/go-sql-driver/mysql/AUTHORS b/vendor/github.com/go-sql-driver/mysql/AUTHORS index fb1478c3bc6..ad598980069 100644 --- a/vendor/github.com/go-sql-driver/mysql/AUTHORS +++ b/vendor/github.com/go-sql-driver/mysql/AUTHORS @@ -13,17 +13,12 @@ Aaron Hopkins Achille Roussel -Alex Snast Alexey Palazhchenko Andrew Reid -Animesh Ray Arne Hormann -Ariel Mashraki Asta Xie Bulat Gaifullin -Caine Jette Carlos Nieto -Chris Kirkland Chris Moos Craig Wilson Daniel Montoya @@ -46,7 +41,6 @@ Ilia Cimpoes INADA Naoki Jacek Szwec James Harr -Janek Vedock Jeff Hodges Jeffrey Charles Jerome Meyer @@ -58,17 +52,14 @@ Julien Schmidt Justin Li Justin Nuß Kamil Dziedzic -Kei Kamikawa Kevin Malachowski Kieron Woodhouse -Lance Tian Lennart Rudolph Leonardo YongUk Kim Linh Tran Tuan Lion Yang Luca Looz Lucas Liu -Lunny Xiao Luke Scott Maciej Zimnoch Michael Woolnough @@ -78,42 +69,31 @@ Olivier Mengué oscarzhao Paul Bonser Peter Schultz -Phil Porada Rebecca Chin Reed Allman Richard Wilkes Robert Russell Runrioter Wung -Samantha Frank -Santhosh Kumar Tekuri -Sho Iizuka -Sho Ikeda Shuode Li Simon J Mudd Soroush Pour Stan Putrya Stanley Gunawan Steven Hartland -Tan Jinhua <312841925 at qq.com> Thomas Wodarek Tim Ruffles Tom Jenkinson Vladimir Kovpak -Vladyslav Zhelezniak Xiangyu Hu Xiaobing Jiang Xiuming Chen -Xuehong Chan Zhenye Xie -Zhixin Wen -Ziheng Lyu # Organizations Barracuda Networks, Inc. Counting Ltd. DigitalOcean Inc. -dyves labs AG Facebook Inc. GitHub Inc. Google Inc. @@ -123,4 +103,3 @@ Multiplay Ltd. Percona LLC Pivotal Inc. Stripe Inc. -Zendesk Inc. diff --git a/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md b/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md index 5166e4adb57..9cb97b38de2 100644 --- a/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md +++ b/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md @@ -1,63 +1,3 @@ -## Version 1.7.1 (2023-04-25) - -Changes: - - - bump actions/checkout@v3 and actions/setup-go@v3 (#1375) - - Add go1.20 and mariadb10.11 to the testing matrix (#1403) - - Increase default maxAllowedPacket size. (#1411) - -Bugfixes: - - - Use SET syntax as specified in the MySQL documentation (#1402) - - -## Version 1.7 (2022-11-29) - -Changes: - - - Drop support of Go 1.12 (#1211) - - Refactoring `(*textRows).readRow` in a more clear way (#1230) - - util: Reduce boundary check in escape functions. (#1316) - - enhancement for mysqlConn handleAuthResult (#1250) - -New Features: - - - support Is comparison on MySQLError (#1210) - - return unsigned in database type name when necessary (#1238) - - Add API to express like a --ssl-mode=PREFERRED MySQL client (#1370) - - Add SQLState to MySQLError (#1321) - -Bugfixes: - - - Fix parsing 0 year. (#1257) - - -## Version 1.6 (2021-04-01) - -Changes: - - - Migrate the CI service from travis-ci to GitHub Actions (#1176, #1183, #1190) - - `NullTime` is deprecated (#960, #1144) - - Reduce allocations when building SET command (#1111) - - Performance improvement for time formatting (#1118) - - Performance improvement for time parsing (#1098, #1113) - -New Features: - - - Implement `driver.Validator` interface (#1106, #1174) - - Support returning `uint64` from `Valuer` in `ConvertValue` (#1143) - - Add `json.RawMessage` for converter and prepared statement (#1059) - - Interpolate `json.RawMessage` as `string` (#1058) - - Implements `CheckNamedValue` (#1090) - -Bugfixes: - - - Stop rounding times (#1121, #1172) - - Put zero filler into the SSL handshake packet (#1066) - - Fix checking cancelled connections back into the connection pool (#1095) - - Fix remove last 0 byte for mysql_old_password when password is empty (#1133) - - ## Version 1.5 (2020-01-07) Changes: diff --git a/vendor/github.com/go-sql-driver/mysql/README.md b/vendor/github.com/go-sql-driver/mysql/README.md index 3b5d229aae9..d2627a41a7f 100644 --- a/vendor/github.com/go-sql-driver/mysql/README.md +++ b/vendor/github.com/go-sql-driver/mysql/README.md @@ -35,12 +35,12 @@ A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) pac * Supports queries larger than 16MB * Full [`sql.RawBytes`](https://golang.org/pkg/database/sql/#RawBytes) support. * Intelligent `LONG DATA` handling in prepared statements - * Secure `LOAD DATA LOCAL INFILE` support with file allowlisting and `io.Reader` support + * Secure `LOAD DATA LOCAL INFILE` support with file Whitelisting and `io.Reader` support * Optional `time.Time` parsing * Optional placeholder interpolation ## Requirements - * Go 1.13 or higher. We aim to support the 3 latest versions of Go. + * Go 1.10 or higher. We aim to support the 3 latest versions of Go. * MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+) --------------------------------------- @@ -56,37 +56,15 @@ Make sure [Git is installed](https://git-scm.com/downloads) on your machine and _Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](https://golang.org/pkg/database/sql/) API then. Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name) as `dataSourceName`: - ```go -import ( - "database/sql" - "time" - - _ "github.com/go-sql-driver/mysql" -) - -// ... +import "database/sql" +import _ "github.com/go-sql-driver/mysql" db, err := sql.Open("mysql", "user:password@/dbname") -if err != nil { - panic(err) -} -// See "Important settings" section. -db.SetConnMaxLifetime(time.Minute * 3) -db.SetMaxOpenConns(10) -db.SetMaxIdleConns(10) ``` [Examples are available in our Wiki](https://github.com/go-sql-driver/mysql/wiki/Examples "Go-MySQL-Driver Examples"). -### Important settings - -`db.SetConnMaxLifetime()` is required to ensure connections are closed by the driver safely before connection is closed by MySQL server, OS, or other middlewares. Since some middlewares close idle connections by 5 minutes, we recommend timeout shorter than 5 minutes. This setting helps load balancing and changing system variables too. - -`db.SetMaxOpenConns()` is highly recommended to limit the number of connection used by the application. There is no recommended limit number because it depends on application and MySQL server. - -`db.SetMaxIdleConns()` is recommended to be set same to `db.SetMaxOpenConns()`. When it is smaller than `SetMaxOpenConns()`, connections can be opened and closed much more frequently than you expect. Idle connections can be closed by the `db.SetConnMaxLifetime()`. If you want to close idle connections more rapidly, you can use `db.SetConnMaxIdleTime()` since Go 1.15. - ### DSN (Data Source Name) @@ -144,7 +122,7 @@ Valid Values: true, false Default: false ``` -`allowAllFiles=true` disables the file allowlist for `LOAD DATA LOCAL INFILE` and allows *all* files. +`allowAllFiles=true` disables the file Whitelist for `LOAD DATA LOCAL INFILE` and allows *all* files. [*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html) ##### `allowCleartextPasswords` @@ -155,18 +133,7 @@ Valid Values: true, false Default: false ``` -`allowCleartextPasswords=true` allows using the [cleartext client side plugin](https://dev.mysql.com/doc/en/cleartext-pluggable-authentication.html) if required by an account, such as one defined with the [PAM authentication plugin](http://dev.mysql.com/doc/en/pam-authentication-plugin.html). Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include [TLS / SSL](#tls), IPsec, or a private network. - - -##### `allowFallbackToPlaintext` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -`allowFallbackToPlaintext=true` acts like a `--ssl-mode=PREFERRED` MySQL client as described in [Command Options for Connecting to the Server](https://dev.mysql.com/doc/refman/5.7/en/connection-options.html#option_general_ssl-mode) +`allowCleartextPasswords=true` allows using the [cleartext client side plugin](http://dev.mysql.com/doc/en/cleartext-authentication-plugin.html) if required by an account, such as one defined with the [PAM authentication plugin](http://dev.mysql.com/doc/en/pam-authentication-plugin.html). Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include [TLS / SSL](#tls), IPsec, or a private network. ##### `allowNativePasswords` @@ -263,7 +230,7 @@ Default: false If `interpolateParams` is true, placeholders (`?`) in calls to `db.Query()` and `db.Exec()` are interpolated into a single query string with given parameters. This reduces the number of roundtrips, since the driver has to prepare a statement, execute it with given parameters and close the statement again with `interpolateParams=false`. -*This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are rejected as they may [introduce a SQL injection vulnerability](http://stackoverflow.com/a/12118602/3430118)!* +*This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are blacklisted as they may [introduce a SQL injection vulnerability](http://stackoverflow.com/a/12118602/3430118)!* ##### `loc` @@ -282,10 +249,10 @@ Please keep in mind, that param values must be [url.QueryEscape](https://golang. ##### `maxAllowedPacket` ``` Type: decimal number -Default: 64*1024*1024 +Default: 4194304 ``` -Max packet size allowed in bytes. The default value is 64 MiB and should be adjusted to match the server settings. `maxAllowedPacket=0` can be used to automatically fetch the `max_allowed_packet` variable from server *on every connection*. +Max packet size allowed in bytes. The default value is 4 MiB and should be adjusted to match the server settings. `maxAllowedPacket=0` can be used to automatically fetch the `max_allowed_packet` variable from server *on every connection*. ##### `multiStatements` @@ -409,7 +376,7 @@ Rules: Examples: * `autocommit=1`: `SET autocommit=1` * [`time_zone=%27Europe%2FParis%27`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `SET time_zone='Europe/Paris'` - * [`transaction_isolation=%27REPEATABLE-READ%27`](https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_transaction_isolation): `SET transaction_isolation='REPEATABLE-READ'` + * [`tx_isolation=%27REPEATABLE-READ%27`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `SET tx_isolation='REPEATABLE-READ'` #### Examples @@ -465,7 +432,7 @@ user:password@/ 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. ## `ColumnType` Support -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`. +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. ## `context.Context` Support Go 1.8 added `database/sql` support for `context.Context`. This driver supports query timeouts and cancellation via contexts. @@ -478,7 +445,7 @@ For this feature you need direct access to the package. Therefore you must chang import "github.com/go-sql-driver/mysql" ``` -Files must be explicitly allowed by registering them with `mysql.RegisterLocalFile(filepath)` (recommended) or the allowlist check must be deactivated by using the DSN parameter `allowAllFiles=true` ([*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)). +Files must be whitelisted by registering them with `mysql.RegisterLocalFile(filepath)` (recommended) or the Whitelist check must be deactivated by using the DSN parameter `allowAllFiles=true` ([*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)). To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::` then. Choose different names for different handlers and `DeregisterReaderHandler` when you don't need it anymore. @@ -492,6 +459,8 @@ However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` v **Caution:** As of Go 1.1, this makes `time.Time` the only variable type you can scan `DATE` and `DATETIME` values into. This breaks for example [`sql.RawBytes` support](https://github.com/go-sql-driver/mysql/wiki/Examples#rawbytes). +Alternatively you can use the [`NullTime`](https://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`. + ### Unicode support Since version 1.5 Go-MySQL-Driver automatically uses the collation ` utf8mb4_general_ci` by default. @@ -508,7 +477,7 @@ To run the driver tests you may need to adjust the configuration. See the [Testi Go-MySQL-Driver is not feature-complete yet. Your help is very appreciated. If you want to contribute, you can work on an [open issue](https://github.com/go-sql-driver/mysql/issues?state=open) or review a [pull request](https://github.com/go-sql-driver/mysql/pulls). -See the [Contribution Guidelines](https://github.com/go-sql-driver/mysql/blob/master/.github/CONTRIBUTING.md) for details. +See the [Contribution Guidelines](https://github.com/go-sql-driver/mysql/blob/master/CONTRIBUTING.md) for details. --------------------------------------- @@ -529,3 +498,4 @@ Please read the [MPL 2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) if you You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE). ![Go Gopher and MySQL Dolphin](https://raw.github.com/wiki/go-sql-driver/mysql/go-mysql-driver_m.jpg "Golang Gopher transporting the MySQL Dolphin in a wheelbarrow") + diff --git a/vendor/github.com/go-sql-driver/mysql/atomic_bool.go b/vendor/github.com/go-sql-driver/mysql/atomic_bool.go deleted file mode 100644 index 1b7e19f3e39..00000000000 --- a/vendor/github.com/go-sql-driver/mysql/atomic_bool.go +++ /dev/null @@ -1,19 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package. -// -// Copyright 2022 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. -//go:build go1.19 -// +build go1.19 - -package mysql - -import "sync/atomic" - -/****************************************************************************** -* Sync utils * -******************************************************************************/ - -type atomicBool = atomic.Bool diff --git a/vendor/github.com/go-sql-driver/mysql/atomic_bool_go118.go b/vendor/github.com/go-sql-driver/mysql/atomic_bool_go118.go deleted file mode 100644 index 2e9a7f0b61b..00000000000 --- a/vendor/github.com/go-sql-driver/mysql/atomic_bool_go118.go +++ /dev/null @@ -1,47 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package. -// -// Copyright 2022 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. -//go:build !go1.19 -// +build !go1.19 - -package mysql - -import "sync/atomic" - -/****************************************************************************** -* Sync utils * -******************************************************************************/ - -// atomicBool is an implementation of atomic.Bool for older version of Go. -// it is a wrapper around uint32 for usage as a boolean value with -// atomic access. -type atomicBool struct { - _ noCopy - value uint32 -} - -// Load returns whether the current boolean value is true -func (ab *atomicBool) Load() bool { - return atomic.LoadUint32(&ab.value) > 0 -} - -// Store sets the value of the bool regardless of the previous value -func (ab *atomicBool) Store(value bool) { - if value { - atomic.StoreUint32(&ab.value, 1) - } else { - atomic.StoreUint32(&ab.value, 0) - } -} - -// Swap sets the value of the bool and returns the old value. -func (ab *atomicBool) Swap(value bool) bool { - if value { - return atomic.SwapUint32(&ab.value, 1) > 0 - } - return atomic.SwapUint32(&ab.value, 0) > 0 -} diff --git a/vendor/github.com/go-sql-driver/mysql/auth.go b/vendor/github.com/go-sql-driver/mysql/auth.go index 1ff203e57bb..fec7040d4a2 100644 --- a/vendor/github.com/go-sql-driver/mysql/auth.go +++ b/vendor/github.com/go-sql-driver/mysql/auth.go @@ -15,7 +15,6 @@ import ( "crypto/sha256" "crypto/x509" "encoding/pem" - "fmt" "sync" ) @@ -33,26 +32,27 @@ var ( // Note: The provided rsa.PublicKey instance is exclusively owned by the driver // after registering it and may not be modified. // -// data, err := ioutil.ReadFile("mykey.pem") -// if err != nil { -// log.Fatal(err) -// } +// data, err := ioutil.ReadFile("mykey.pem") +// if err != nil { +// log.Fatal(err) +// } // -// block, _ := pem.Decode(data) -// if block == nil || block.Type != "PUBLIC KEY" { -// log.Fatal("failed to decode PEM block containing public key") -// } +// block, _ := pem.Decode(data) +// if block == nil || block.Type != "PUBLIC KEY" { +// log.Fatal("failed to decode PEM block containing public key") +// } // -// pub, err := x509.ParsePKIXPublicKey(block.Bytes) -// if err != nil { -// log.Fatal(err) -// } +// pub, err := x509.ParsePKIXPublicKey(block.Bytes) +// if err != nil { +// log.Fatal(err) +// } +// +// if rsaPubKey, ok := pub.(*rsa.PublicKey); ok { +// mysql.RegisterServerPubKey("mykey", rsaPubKey) +// } else { +// log.Fatal("not a RSA public key") +// } // -// if rsaPubKey, ok := pub.(*rsa.PublicKey); ok { -// mysql.RegisterServerPubKey("mykey", rsaPubKey) -// } else { -// log.Fatal("not a RSA public key") -// } func RegisterServerPubKey(name string, pubKey *rsa.PublicKey) { serverPubKeyLock.Lock() if serverPubKeyRegistry == nil { @@ -136,6 +136,10 @@ func pwHash(password []byte) (result [2]uint32) { // Hash password using insecure pre 4.1 method func scrambleOldPassword(scramble []byte, password string) []byte { + if len(password) == 0 { + return nil + } + scramble = scramble[:8] hashPw := pwHash([]byte(password)) @@ -243,9 +247,6 @@ func (mc *mysqlConn) auth(authData []byte, plugin string) ([]byte, error) { if !mc.cfg.AllowOldPasswords { return nil, ErrOldPassword } - if len(mc.cfg.Passwd) == 0 { - return nil, nil - } // Note: there are edge cases where this should work but doesn't; // this is currently "wontfix": // https://github.com/go-sql-driver/mysql/issues/184 @@ -273,9 +274,7 @@ func (mc *mysqlConn) auth(authData []byte, plugin string) ([]byte, error) { if len(mc.cfg.Passwd) == 0 { return []byte{0}, nil } - // unlike caching_sha2_password, sha256_password does not accept - // cleartext password on unix transport. - if mc.cfg.TLS != nil { + if mc.cfg.tls != nil || mc.cfg.Net == "unix" { // write cleartext auth packet return append([]byte(mc.cfg.Passwd), 0), nil } @@ -351,7 +350,7 @@ func (mc *mysqlConn) handleAuthResult(oldAuthData []byte, plugin string) error { } case cachingSha2PasswordPerformFullAuthentication: - if mc.cfg.TLS != nil || mc.cfg.Net == "unix" { + if mc.cfg.tls != nil || mc.cfg.Net == "unix" { // write cleartext auth packet err = mc.writeAuthSwitchPacket(append([]byte(mc.cfg.Passwd), 0)) if err != nil { @@ -366,24 +365,14 @@ func (mc *mysqlConn) handleAuthResult(oldAuthData []byte, plugin string) error { return err } data[4] = cachingSha2PasswordRequestPublicKey - err = mc.writePacket(data) - if err != nil { - return err - } + mc.writePacket(data) + // parse public key if data, err = mc.readPacket(); err != nil { return err } - if data[0] != iAuthMoreData { - return fmt.Errorf("unexpect resp from server for caching_sha2_password perform full authentication") - } - - // parse public key - block, rest := pem.Decode(data[1:]) - if block == nil { - return fmt.Errorf("No Pem data found, data: %s", rest) - } + block, _ := pem.Decode(data[1:]) pkix, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return err @@ -412,10 +401,6 @@ func (mc *mysqlConn) handleAuthResult(oldAuthData []byte, plugin string) error { return nil // auth successful default: block, _ := pem.Decode(authData) - if block == nil { - return fmt.Errorf("no Pem data found, data: %s", authData) - } - pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return err diff --git a/vendor/github.com/go-sql-driver/mysql/collations.go b/vendor/github.com/go-sql-driver/mysql/collations.go index 295bfbe52af..8d2b5567679 100644 --- a/vendor/github.com/go-sql-driver/mysql/collations.go +++ b/vendor/github.com/go-sql-driver/mysql/collations.go @@ -13,8 +13,7 @@ const binaryCollation = "binary" // A list of available collations mapped to the internal ID. // To update this map use the following MySQL query: -// -// SELECT COLLATION_NAME, ID FROM information_schema.COLLATIONS WHERE ID<256 ORDER BY ID +// SELECT COLLATION_NAME, ID FROM information_schema.COLLATIONS WHERE ID<256 ORDER BY ID // // Handshake packet have only 1 byte for collation_id. So we can't use collations with ID > 255. // @@ -248,7 +247,7 @@ var collations = map[string]byte{ "utf8mb4_0900_ai_ci": 255, } -// A denylist of collations which is unsafe to interpolate parameters. +// A blacklist of collations which is unsafe to interpolate parameters. // These multibyte encodings may contains 0x5c (`\`) in their trailing bytes. var unsafeCollations = map[string]bool{ "big5_chinese_ci": true, diff --git a/vendor/github.com/go-sql-driver/mysql/conncheck.go b/vendor/github.com/go-sql-driver/mysql/conncheck.go index 0ea721720c9..024eb28589e 100644 --- a/vendor/github.com/go-sql-driver/mysql/conncheck.go +++ b/vendor/github.com/go-sql-driver/mysql/conncheck.go @@ -6,7 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -//go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || illumos // +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos package mysql diff --git a/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go b/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go index a56c138f2d3..ea7fb607ac4 100644 --- a/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go +++ b/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go @@ -6,7 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -//go:build !linux && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !illumos // +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!illumos package mysql diff --git a/vendor/github.com/go-sql-driver/mysql/connection.go b/vendor/github.com/go-sql-driver/mysql/connection.go index 947a883e304..e4bb59e67c3 100644 --- a/vendor/github.com/go-sql-driver/mysql/connection.go +++ b/vendor/github.com/go-sql-driver/mysql/connection.go @@ -12,7 +12,6 @@ import ( "context" "database/sql" "database/sql/driver" - "encoding/json" "io" "net" "strconv" @@ -47,10 +46,9 @@ type mysqlConn struct { // Handles parameters set in DSN after the connection is established func (mc *mysqlConn) handleParams() (err error) { - var cmdSet strings.Builder for param, val := range mc.cfg.Params { switch param { - // Charset: character_set_connection, character_set_client, character_set_results + // Charset case "charset": charsets := strings.Split(val, ",") for i := range charsets { @@ -64,25 +62,12 @@ func (mc *mysqlConn) handleParams() (err error) { return } - // Other system vars accumulated in a single SET command + // System Vars default: - if cmdSet.Len() == 0 { - // Heuristic: 29 chars for each other key=value to reduce reallocations - cmdSet.Grow(4 + len(param) + 1 + len(val) + 30*(len(mc.cfg.Params)-1)) - cmdSet.WriteString("SET ") - } else { - cmdSet.WriteString(", ") + err = mc.exec("SET " + param + "=" + val + "") + if err != nil { + return } - cmdSet.WriteString(param) - cmdSet.WriteString(" = ") - cmdSet.WriteString(val) - } - } - - if cmdSet.Len() > 0 { - err = mc.exec(cmdSet.String()) - if err != nil { - return } } @@ -104,7 +89,7 @@ func (mc *mysqlConn) Begin() (driver.Tx, error) { } func (mc *mysqlConn) begin(readOnly bool) (driver.Tx, error) { - if mc.closed.Load() { + if mc.closed.IsSet() { errLog.Print(ErrInvalidConn) return nil, driver.ErrBadConn } @@ -123,7 +108,7 @@ func (mc *mysqlConn) begin(readOnly bool) (driver.Tx, error) { func (mc *mysqlConn) Close() (err error) { // Makes Close idempotent - if !mc.closed.Load() { + if !mc.closed.IsSet() { err = mc.writeCommandPacket(comQuit) } @@ -137,7 +122,7 @@ func (mc *mysqlConn) Close() (err error) { // is called before auth or on auth failure because MySQL will have already // closed the network connection. func (mc *mysqlConn) cleanup() { - if mc.closed.Swap(true) { + if !mc.closed.TrySet(true) { return } @@ -152,7 +137,7 @@ func (mc *mysqlConn) cleanup() { } func (mc *mysqlConn) error() error { - if mc.closed.Load() { + if mc.closed.IsSet() { if err := mc.canceled.Value(); err != nil { return err } @@ -162,7 +147,7 @@ func (mc *mysqlConn) error() error { } func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) { - if mc.closed.Load() { + if mc.closed.IsSet() { errLog.Print(ErrInvalidConn) return nil, driver.ErrBadConn } @@ -245,21 +230,47 @@ func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (strin if v.IsZero() { buf = append(buf, "'0000-00-00'"...) } else { - buf = append(buf, '\'') - buf, err = appendDateTime(buf, v.In(mc.cfg.Loc)) - if err != nil { - return "", err + v := v.In(mc.cfg.Loc) + v = v.Add(time.Nanosecond * 500) // To round under microsecond + year := v.Year() + year100 := year / 100 + year1 := year % 100 + month := v.Month() + day := v.Day() + hour := v.Hour() + minute := v.Minute() + second := v.Second() + micro := v.Nanosecond() / 1000 + + buf = append(buf, []byte{ + '\'', + digits10[year100], digits01[year100], + digits10[year1], digits01[year1], + '-', + digits10[month], digits01[month], + '-', + digits10[day], digits01[day], + ' ', + digits10[hour], digits01[hour], + ':', + digits10[minute], digits01[minute], + ':', + digits10[second], digits01[second], + }...) + + if micro != 0 { + micro10000 := micro / 10000 + micro100 := micro / 100 % 100 + micro1 := micro % 100 + buf = append(buf, []byte{ + '.', + digits10[micro10000], digits01[micro10000], + digits10[micro100], digits01[micro100], + digits10[micro1], digits01[micro1], + }...) } buf = append(buf, '\'') } - case json.RawMessage: - buf = append(buf, '\'') - if mc.status&statusNoBackslashEscapes == 0 { - buf = escapeBytesBackslash(buf, v) - } else { - buf = escapeBytesQuotes(buf, v) - } - buf = append(buf, '\'') case []byte: if v == nil { buf = append(buf, "NULL"...) @@ -295,7 +306,7 @@ func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (strin } func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, error) { - if mc.closed.Load() { + if mc.closed.IsSet() { errLog.Print(ErrInvalidConn) return nil, driver.ErrBadConn } @@ -356,7 +367,7 @@ func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, erro } func (mc *mysqlConn) query(query string, args []driver.Value) (*textRows, error) { - if mc.closed.Load() { + if mc.closed.IsSet() { errLog.Print(ErrInvalidConn) return nil, driver.ErrBadConn } @@ -450,7 +461,7 @@ func (mc *mysqlConn) finish() { // Ping implements driver.Pinger interface func (mc *mysqlConn) Ping(ctx context.Context) (err error) { - if mc.closed.Load() { + if mc.closed.IsSet() { errLog.Print(ErrInvalidConn) return driver.ErrBadConn } @@ -469,10 +480,6 @@ func (mc *mysqlConn) Ping(ctx context.Context) (err error) { // BeginTx implements driver.ConnBeginTx interface func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { - if mc.closed.Load() { - return nil, driver.ErrBadConn - } - if err := mc.watchCancel(ctx); err != nil { return nil, err } @@ -636,15 +643,9 @@ func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) { // ResetSession implements driver.SessionResetter. // (From Go 1.10) func (mc *mysqlConn) ResetSession(ctx context.Context) error { - if mc.closed.Load() { + if mc.closed.IsSet() { return driver.ErrBadConn } mc.reset = true return nil } - -// IsValid implements driver.Validator interface -// (From Go 1.15) -func (mc *mysqlConn) IsValid() bool { - return !mc.closed.Load() -} diff --git a/vendor/github.com/go-sql-driver/mysql/const.go b/vendor/github.com/go-sql-driver/mysql/const.go index 64e2bced6f8..b1e6b85efca 100644 --- a/vendor/github.com/go-sql-driver/mysql/const.go +++ b/vendor/github.com/go-sql-driver/mysql/const.go @@ -10,7 +10,7 @@ package mysql const ( defaultAuthPlugin = "mysql_native_password" - defaultMaxAllowedPacket = 64 << 20 // 64 MiB. See https://github.com/go-sql-driver/mysql/issues/1355 + defaultMaxAllowedPacket = 4 << 20 // 4 MiB minProtocolVersion = 10 maxPacketSize = 1<<24 - 1 timeFormat = "2006-01-02 15:04:05.999999" diff --git a/vendor/github.com/go-sql-driver/mysql/driver.go b/vendor/github.com/go-sql-driver/mysql/driver.go index ad7aec215c6..c1bdf1199b6 100644 --- a/vendor/github.com/go-sql-driver/mysql/driver.go +++ b/vendor/github.com/go-sql-driver/mysql/driver.go @@ -8,10 +8,10 @@ // // The driver should be used via the database/sql package: // -// import "database/sql" -// import _ "github.com/go-sql-driver/mysql" +// import "database/sql" +// import _ "github.com/go-sql-driver/mysql" // -// db, err := sql.Open("mysql", "user:password@/dbname") +// db, err := sql.Open("mysql", "user:password@/dbname") // // See https://github.com/go-sql-driver/mysql#usage for details package mysql diff --git a/vendor/github.com/go-sql-driver/mysql/dsn.go b/vendor/github.com/go-sql-driver/mysql/dsn.go index 4b71aaab0bf..75c8c248966 100644 --- a/vendor/github.com/go-sql-driver/mysql/dsn.go +++ b/vendor/github.com/go-sql-driver/mysql/dsn.go @@ -46,23 +46,22 @@ type Config struct { ServerPubKey string // Server public key name pubKey *rsa.PublicKey // Server public key TLSConfig string // TLS configuration name - TLS *tls.Config // TLS configuration, its priority is higher than TLSConfig + tls *tls.Config // TLS configuration Timeout time.Duration // Dial timeout ReadTimeout time.Duration // I/O read timeout WriteTimeout time.Duration // I/O write timeout - AllowAllFiles bool // Allow all files to be used with LOAD DATA LOCAL INFILE - AllowCleartextPasswords bool // Allows the cleartext client side plugin - AllowFallbackToPlaintext bool // Allows fallback to unencrypted connection if server does not support TLS - AllowNativePasswords bool // Allows the native password authentication method - AllowOldPasswords bool // Allows the old insecure password method - CheckConnLiveness bool // Check connections for liveness before using them - ClientFoundRows bool // Return number of matching rows instead of rows changed - ColumnsWithAlias bool // Prepend table alias to column names - InterpolateParams bool // Interpolate placeholders into query string - MultiStatements bool // Allow multiple statements in one query - ParseTime bool // Parse time values to time.Time - RejectReadOnly bool // Reject read-only connections + AllowAllFiles bool // Allow all files to be used with LOAD DATA LOCAL INFILE + AllowCleartextPasswords bool // Allows the cleartext client side plugin + AllowNativePasswords bool // Allows the native password authentication method + AllowOldPasswords bool // Allows the old insecure password method + CheckConnLiveness bool // Check connections for liveness before using them + ClientFoundRows bool // Return number of matching rows instead of rows changed + ColumnsWithAlias bool // Prepend table alias to column names + InterpolateParams bool // Interpolate placeholders into query string + MultiStatements bool // Allow multiple statements in one query + ParseTime bool // Parse time values to time.Time + RejectReadOnly bool // Reject read-only connections } // NewConfig creates a new Config and sets default values. @@ -78,8 +77,8 @@ func NewConfig() *Config { func (cfg *Config) Clone() *Config { cp := *cfg - if cp.TLS != nil { - cp.TLS = cfg.TLS.Clone() + if cp.tls != nil { + cp.tls = cfg.tls.Clone() } if len(cp.Params) > 0 { cp.Params = make(map[string]string, len(cfg.Params)) @@ -120,29 +119,24 @@ func (cfg *Config) normalize() error { cfg.Addr = ensureHavePort(cfg.Addr) } - if cfg.TLS == nil { - switch cfg.TLSConfig { - case "false", "": - // don't set anything - case "true": - cfg.TLS = &tls.Config{} - case "skip-verify": - cfg.TLS = &tls.Config{InsecureSkipVerify: true} - case "preferred": - cfg.TLS = &tls.Config{InsecureSkipVerify: true} - cfg.AllowFallbackToPlaintext = true - default: - cfg.TLS = getTLSConfigClone(cfg.TLSConfig) - if cfg.TLS == nil { - return errors.New("invalid value / unknown config name: " + cfg.TLSConfig) - } + switch cfg.TLSConfig { + case "false", "": + // don't set anything + case "true": + cfg.tls = &tls.Config{} + case "skip-verify", "preferred": + cfg.tls = &tls.Config{InsecureSkipVerify: true} + default: + cfg.tls = getTLSConfigClone(cfg.TLSConfig) + if cfg.tls == nil { + return errors.New("invalid value / unknown config name: " + cfg.TLSConfig) } } - if cfg.TLS != nil && cfg.TLS.ServerName == "" && !cfg.TLS.InsecureSkipVerify { + if cfg.tls != nil && cfg.tls.ServerName == "" && !cfg.tls.InsecureSkipVerify { host, _, err := net.SplitHostPort(cfg.Addr) if err == nil { - cfg.TLS.ServerName = host + cfg.tls.ServerName = host } } @@ -210,10 +204,6 @@ func (cfg *Config) FormatDSN() string { writeDSNParam(&buf, &hasParam, "allowCleartextPasswords", "true") } - if cfg.AllowFallbackToPlaintext { - writeDSNParam(&buf, &hasParam, "allowFallbackToPlaintext", "true") - } - if !cfg.AllowNativePasswords { writeDSNParam(&buf, &hasParam, "allowNativePasswords", "false") } @@ -385,7 +375,7 @@ func parseDSNParams(cfg *Config, params string) (err error) { // cfg params switch value := param[1]; param[0] { - // Disable INFILE allowlist / enable all files + // Disable INFILE whitelist / enable all files case "allowAllFiles": var isBool bool cfg.AllowAllFiles, isBool = readBool(value) @@ -401,14 +391,6 @@ func parseDSNParams(cfg *Config, params string) (err error) { return errors.New("invalid bool value: " + value) } - // Allow fallback to unencrypted connection if server does not support TLS - case "allowFallbackToPlaintext": - var isBool bool - cfg.AllowFallbackToPlaintext, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - // Use native password authentication case "allowNativePasswords": var isBool bool @@ -444,6 +426,7 @@ func parseDSNParams(cfg *Config, params string) (err error) { // Collation case "collation": cfg.Collation = value + break case "columnsWithAlias": var isBool bool diff --git a/vendor/github.com/go-sql-driver/mysql/errors.go b/vendor/github.com/go-sql-driver/mysql/errors.go index ff9a8f088c3..760782ff2fb 100644 --- a/vendor/github.com/go-sql-driver/mysql/errors.go +++ b/vendor/github.com/go-sql-driver/mysql/errors.go @@ -27,7 +27,7 @@ var ( ErrOldProtocol = errors.New("MySQL server does not support required protocol 41+") ErrPktSync = errors.New("commands out of sync. You can't run this command now") ErrPktSyncMul = errors.New("commands out of sync. Did you run multiple statements at once?") - ErrPktTooLarge = errors.New("packet for query is too large. Try adjusting the `Config.MaxAllowedPacket`") + ErrPktTooLarge = errors.New("packet for query is too large. Try adjusting the 'max_allowed_packet' variable on the server") ErrBusyBuffer = errors.New("busy buffer") // errBadConnNoWrite is used for connection errors where nothing was sent to the database yet. @@ -56,22 +56,10 @@ func SetLogger(logger Logger) error { // MySQLError is an error type which represents a single MySQL error type MySQLError struct { - Number uint16 - SQLState [5]byte - Message string + Number uint16 + Message string } func (me *MySQLError) Error() string { - if me.SQLState != [5]byte{} { - return fmt.Sprintf("Error %d (%s): %s", me.Number, me.SQLState, me.Message) - } - return fmt.Sprintf("Error %d: %s", me.Number, me.Message) } - -func (me *MySQLError) Is(err error) bool { - if merr, ok := err.(*MySQLError); ok { - return merr.Number == me.Number - } - return false -} diff --git a/vendor/github.com/go-sql-driver/mysql/fields.go b/vendor/github.com/go-sql-driver/mysql/fields.go index e0654a83d99..e1e2ece4b16 100644 --- a/vendor/github.com/go-sql-driver/mysql/fields.go +++ b/vendor/github.com/go-sql-driver/mysql/fields.go @@ -41,9 +41,6 @@ func (mf *mysqlField) typeDatabaseName() string { case fieldTypeJSON: return "JSON" case fieldTypeLong: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED INT" - } return "INT" case fieldTypeLongBLOB: if mf.charSet != collations[binaryCollation] { @@ -51,9 +48,6 @@ func (mf *mysqlField) typeDatabaseName() string { } return "LONGBLOB" case fieldTypeLongLong: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED BIGINT" - } return "BIGINT" case fieldTypeMediumBLOB: if mf.charSet != collations[binaryCollation] { @@ -69,9 +63,6 @@ func (mf *mysqlField) typeDatabaseName() string { case fieldTypeSet: return "SET" case fieldTypeShort: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED SMALLINT" - } return "SMALLINT" case fieldTypeString: if mf.charSet == collations[binaryCollation] { @@ -83,9 +74,6 @@ func (mf *mysqlField) typeDatabaseName() string { case fieldTypeTimestamp: return "TIMESTAMP" case fieldTypeTiny: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED TINYINT" - } return "TINYINT" case fieldTypeTinyBLOB: if mf.charSet != collations[binaryCollation] { @@ -118,7 +106,7 @@ var ( scanTypeInt64 = reflect.TypeOf(int64(0)) scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{}) scanTypeNullInt = reflect.TypeOf(sql.NullInt64{}) - scanTypeNullTime = reflect.TypeOf(sql.NullTime{}) + scanTypeNullTime = reflect.TypeOf(NullTime{}) scanTypeUint8 = reflect.TypeOf(uint8(0)) scanTypeUint16 = reflect.TypeOf(uint16(0)) scanTypeUint32 = reflect.TypeOf(uint32(0)) diff --git a/vendor/github.com/go-sql-driver/mysql/fuzz.go b/vendor/github.com/go-sql-driver/mysql/fuzz.go deleted file mode 100644 index 3a4ec25a9e4..00000000000 --- a/vendor/github.com/go-sql-driver/mysql/fuzz.go +++ /dev/null @@ -1,25 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package. -// -// Copyright 2020 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -//go:build gofuzz -// +build gofuzz - -package mysql - -import ( - "database/sql" -) - -func Fuzz(data []byte) int { - db, err := sql.Open("mysql", string(data)) - if err != nil { - return 0 - } - db.Close() - return 1 -} diff --git a/vendor/github.com/go-sql-driver/mysql/infile.go b/vendor/github.com/go-sql-driver/mysql/infile.go index 3279dcffd7e..273cb0ba500 100644 --- a/vendor/github.com/go-sql-driver/mysql/infile.go +++ b/vendor/github.com/go-sql-driver/mysql/infile.go @@ -23,16 +23,17 @@ var ( readerRegisterLock sync.RWMutex ) -// RegisterLocalFile adds the given file to the file allowlist, +// RegisterLocalFile adds the given file to the file whitelist, // so that it can be used by "LOAD DATA LOCAL INFILE ". // Alternatively you can allow the use of all local files with // the DSN parameter 'allowAllFiles=true' // -// filePath := "/home/gopher/data.csv" -// mysql.RegisterLocalFile(filePath) -// err := db.Exec("LOAD DATA LOCAL INFILE '" + filePath + "' INTO TABLE foo") -// if err != nil { -// ... +// filePath := "/home/gopher/data.csv" +// mysql.RegisterLocalFile(filePath) +// err := db.Exec("LOAD DATA LOCAL INFILE '" + filePath + "' INTO TABLE foo") +// if err != nil { +// ... +// func RegisterLocalFile(filePath string) { fileRegisterLock.Lock() // lazy map init @@ -44,7 +45,7 @@ func RegisterLocalFile(filePath string) { fileRegisterLock.Unlock() } -// DeregisterLocalFile removes the given filepath from the allowlist. +// DeregisterLocalFile removes the given filepath from the whitelist. func DeregisterLocalFile(filePath string) { fileRegisterLock.Lock() delete(fileRegister, strings.Trim(filePath, `"`)) @@ -57,14 +58,15 @@ func DeregisterLocalFile(filePath string) { // If the handler returns a io.ReadCloser Close() is called when the // request is finished. // -// mysql.RegisterReaderHandler("data", func() io.Reader { -// var csvReader io.Reader // Some Reader that returns CSV data -// ... // Open Reader here -// return csvReader -// }) -// err := db.Exec("LOAD DATA LOCAL INFILE 'Reader::data' INTO TABLE foo") -// if err != nil { -// ... +// mysql.RegisterReaderHandler("data", func() io.Reader { +// var csvReader io.Reader // Some Reader that returns CSV data +// ... // Open Reader here +// return csvReader +// }) +// err := db.Exec("LOAD DATA LOCAL INFILE 'Reader::data' INTO TABLE foo") +// if err != nil { +// ... +// func RegisterReaderHandler(name string, handler func() io.Reader) { readerRegisterLock.Lock() // lazy map init @@ -91,12 +93,10 @@ func deferredClose(err *error, closer io.Closer) { } } -const defaultPacketSize = 16 * 1024 // 16KB is small enough for disk readahead and large enough for TCP - func (mc *mysqlConn) handleInFileRequest(name string) (err error) { var rdr io.Reader var data []byte - packetSize := defaultPacketSize + packetSize := 16 * 1024 // 16KB is small enough for disk readahead and large enough for TCP if mc.maxWriteSize < packetSize { packetSize = mc.maxWriteSize } diff --git a/vendor/github.com/go-sql-driver/mysql/nulltime.go b/vendor/github.com/go-sql-driver/mysql/nulltime.go index 36c8a42c57b..afa8a89e9ae 100644 --- a/vendor/github.com/go-sql-driver/mysql/nulltime.go +++ b/vendor/github.com/go-sql-driver/mysql/nulltime.go @@ -9,32 +9,11 @@ package mysql import ( - "database/sql" "database/sql/driver" "fmt" "time" ) -// NullTime represents a time.Time that may be NULL. -// NullTime implements the Scanner interface so -// it can be used as a scan destination: -// -// var nt NullTime -// err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt) -// ... -// if nt.Valid { -// // use nt.Time -// } else { -// // NULL value -// } -// -// # This NullTime implementation is not driver-specific -// -// Deprecated: NullTime doesn't honor the loc DSN parameter. -// NullTime.Scan interprets a time as UTC, not the loc DSN parameter. -// Use sql.NullTime instead. -type NullTime sql.NullTime - // Scan implements the Scanner interface. // The value type must be time.Time or string / []byte (formatted time-string), // otherwise Scan fails. @@ -49,11 +28,11 @@ func (nt *NullTime) Scan(value interface{}) (err error) { nt.Time, nt.Valid = v, true return case []byte: - nt.Time, err = parseDateTime(v, time.UTC) + nt.Time, err = parseDateTime(string(v), time.UTC) nt.Valid = (err == nil) return case string: - nt.Time, err = parseDateTime([]byte(v), time.UTC) + nt.Time, err = parseDateTime(v, time.UTC) nt.Valid = (err == nil) return } diff --git a/vendor/github.com/go-sql-driver/mysql/nulltime_go113.go b/vendor/github.com/go-sql-driver/mysql/nulltime_go113.go new file mode 100644 index 00000000000..c392594dd44 --- /dev/null +++ b/vendor/github.com/go-sql-driver/mysql/nulltime_go113.go @@ -0,0 +1,31 @@ +// Go MySQL Driver - A MySQL-Driver for Go's database/sql package +// +// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +// +build go1.13 + +package mysql + +import ( + "database/sql" +) + +// NullTime represents a time.Time that may be NULL. +// NullTime implements the Scanner interface so +// it can be used as a scan destination: +// +// var nt NullTime +// err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt) +// ... +// if nt.Valid { +// // use nt.Time +// } else { +// // NULL value +// } +// +// This NullTime implementation is not driver-specific +type NullTime sql.NullTime diff --git a/vendor/github.com/go-sql-driver/mysql/nulltime_legacy.go b/vendor/github.com/go-sql-driver/mysql/nulltime_legacy.go new file mode 100644 index 00000000000..86d159d4416 --- /dev/null +++ b/vendor/github.com/go-sql-driver/mysql/nulltime_legacy.go @@ -0,0 +1,34 @@ +// Go MySQL Driver - A MySQL-Driver for Go's database/sql package +// +// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +// +build !go1.13 + +package mysql + +import ( + "time" +) + +// NullTime represents a time.Time that may be NULL. +// NullTime implements the Scanner interface so +// it can be used as a scan destination: +// +// var nt NullTime +// err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt) +// ... +// if nt.Valid { +// // use nt.Time +// } else { +// // NULL value +// } +// +// This NullTime implementation is not driver-specific +type NullTime struct { + Time time.Time + Valid bool // Valid is true if Time is not NULL +} diff --git a/vendor/github.com/go-sql-driver/mysql/packets.go b/vendor/github.com/go-sql-driver/mysql/packets.go index ee05c95a870..82ad7a20095 100644 --- a/vendor/github.com/go-sql-driver/mysql/packets.go +++ b/vendor/github.com/go-sql-driver/mysql/packets.go @@ -13,7 +13,6 @@ import ( "crypto/tls" "database/sql/driver" "encoding/binary" - "encoding/json" "errors" "fmt" "io" @@ -110,13 +109,14 @@ func (mc *mysqlConn) writePacket(data []byte) error { conn = mc.rawConn } var err error - if mc.cfg.CheckConnLiveness { - if mc.cfg.ReadTimeout != 0 { - err = conn.SetReadDeadline(time.Now().Add(mc.cfg.ReadTimeout)) - } - if err == nil { - err = connCheck(conn) - } + // If this connection has a ReadTimeout which we've been setting on + // reads, reset it to its default value before we attempt a non-blocking + // read, otherwise the scheduler will just time us out before we can read + if mc.cfg.ReadTimeout != 0 { + err = conn.SetReadDeadline(time.Time{}) + } + if err == nil && mc.cfg.CheckConnLiveness { + err = connCheck(conn) } if err != nil { errLog.Print("closing bad idle connection: ", err) @@ -222,9 +222,9 @@ func (mc *mysqlConn) readHandshakePacket() (data []byte, plugin string, err erro if mc.flags&clientProtocol41 == 0 { return nil, "", ErrOldProtocol } - if mc.flags&clientSSL == 0 && mc.cfg.TLS != nil { - if mc.cfg.AllowFallbackToPlaintext { - mc.cfg.TLS = nil + if mc.flags&clientSSL == 0 && mc.cfg.tls != nil { + if mc.cfg.TLSConfig == "preferred" { + mc.cfg.tls = nil } else { return nil, "", ErrNoTLS } @@ -292,7 +292,7 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string } // To enable TLS / SSL - if mc.cfg.TLS != nil { + if mc.cfg.tls != nil { clientFlags |= clientSSL } @@ -348,22 +348,16 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string return errors.New("unknown collation") } - // Filler [23 bytes] (all 0x00) - pos := 13 - for ; pos < 13+23; pos++ { - data[pos] = 0 - } - // SSL Connection Request Packet // http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest - if mc.cfg.TLS != nil { + if mc.cfg.tls != nil { // Send TLS / SSL request packet if err := mc.writePacket(data[:(4+4+1+23)+4]); err != nil { return err } // Switch to TLS - tlsConn := tls.Client(mc.netConn, mc.cfg.TLS) + tlsConn := tls.Client(mc.netConn, mc.cfg.tls) if err := tlsConn.Handshake(); err != nil { return err } @@ -372,6 +366,12 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string mc.buf.nc = tlsConn } + // Filler [23 bytes] (all 0x00) + pos := 13 + for ; pos < 13+23; pos++ { + data[pos] = 0 + } + // User [null terminated string] if len(mc.cfg.User) > 0 { pos += copy(data[pos:], mc.cfg.User) @@ -587,20 +587,19 @@ func (mc *mysqlConn) handleErrorPacket(data []byte) error { return driver.ErrBadConn } - me := &MySQLError{Number: errno} - pos := 3 // SQL State [optional: # + 5bytes string] if data[3] == 0x23 { - copy(me.SQLState[:], data[4:4+5]) + //sqlstate := string(data[4 : 4+5]) pos = 9 } // Error Message [string] - me.Message = string(data[pos:]) - - return me + return &MySQLError{ + Number: errno, + Message: string(data[pos:]), + } } func readStatus(b []byte) statusFlag { @@ -761,40 +760,40 @@ func (rows *textRows) readRow(dest []driver.Value) error { } // RowSet Packet - var ( - n int - isNull bool - pos int = 0 - ) + var n int + var isNull bool + pos := 0 for i := range dest { // Read bytes and convert to string dest[i], isNull, n, err = readLengthEncodedString(data[pos:]) pos += n + if err == nil { + if !isNull { + if !mc.parseTime { + continue + } else { + switch rows.rs.columns[i].fieldType { + case fieldTypeTimestamp, fieldTypeDateTime, + fieldTypeDate, fieldTypeNewDate: + dest[i], err = parseDateTime( + string(dest[i].([]byte)), + mc.cfg.Loc, + ) + if err == nil { + continue + } + default: + continue + } + } - if err != nil { - return err - } - - if isNull { - dest[i] = nil - continue - } - - if !mc.parseTime { - continue - } - - // Parse time field - switch rows.rs.columns[i].fieldType { - case fieldTypeTimestamp, - fieldTypeDateTime, - fieldTypeDate, - fieldTypeNewDate: - if dest[i], err = parseDateTime(dest[i].([]byte), mc.cfg.Loc); err != nil { - return err + } else { + dest[i] = nil + continue } } + return err // err != nil } return nil @@ -1004,9 +1003,6 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error { continue } - if v, ok := arg.(json.RawMessage); ok { - arg = []byte(v) - } // cache types and values switch v := arg.(type) { case int64: @@ -1116,10 +1112,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error { if v.IsZero() { b = append(b, "0000-00-00"...) } else { - b, err = appendDateTime(b, v.In(mc.cfg.Loc)) - if err != nil { - return err - } + b = v.In(mc.cfg.Loc).AppendFormat(b, timeFormat) } paramValues = appendLengthEncodedInteger(paramValues, diff --git a/vendor/github.com/go-sql-driver/mysql/statement.go b/vendor/github.com/go-sql-driver/mysql/statement.go index 10ece8bd6a1..f7e370939a1 100644 --- a/vendor/github.com/go-sql-driver/mysql/statement.go +++ b/vendor/github.com/go-sql-driver/mysql/statement.go @@ -10,7 +10,6 @@ package mysql import ( "database/sql/driver" - "encoding/json" "fmt" "io" "reflect" @@ -23,7 +22,7 @@ type mysqlStmt struct { } func (stmt *mysqlStmt) Close() error { - if stmt.mc == nil || stmt.mc.closed.Load() { + if stmt.mc == nil || stmt.mc.closed.IsSet() { // driver.Stmt.Close can be called more than once, thus this function // has to be idempotent. // See also Issue #450 and golang/go#16019. @@ -44,13 +43,8 @@ func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter { return converter{} } -func (stmt *mysqlStmt) CheckNamedValue(nv *driver.NamedValue) (err error) { - nv.Value, err = converter{}.ConvertValue(nv.Value) - return -} - func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) { - if stmt.mc.closed.Load() { + if stmt.mc.closed.IsSet() { errLog.Print(ErrInvalidConn) return nil, driver.ErrBadConn } @@ -98,7 +92,7 @@ func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) { } func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) { - if stmt.mc.closed.Load() { + if stmt.mc.closed.IsSet() { errLog.Print(ErrInvalidConn) return nil, driver.ErrBadConn } @@ -135,8 +129,6 @@ func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) { return rows, err } -var jsonType = reflect.TypeOf(json.RawMessage{}) - type converter struct{} // ConvertValue mirrors the reference/default converter in database/sql/driver @@ -154,17 +146,12 @@ func (c converter) ConvertValue(v interface{}) (driver.Value, error) { if err != nil { return nil, err } - if driver.IsValue(sv) { - return sv, nil + if !driver.IsValue(sv) { + return nil, fmt.Errorf("non-Value type %T returned from Value", sv) } - // A value returned from the Valuer interface can be "a type handled by - // a database driver's NamedValueChecker interface" so we should accept - // uint64 here as well. - if u, ok := sv.(uint64); ok { - return u, nil - } - return nil, fmt.Errorf("non-Value type %T returned from Value", sv) + return sv, nil } + rv := reflect.ValueOf(v) switch rv.Kind() { case reflect.Ptr: @@ -183,14 +170,11 @@ func (c converter) ConvertValue(v interface{}) (driver.Value, error) { case reflect.Bool: return rv.Bool(), nil case reflect.Slice: - switch t := rv.Type(); { - case t == jsonType: - return v, nil - case t.Elem().Kind() == reflect.Uint8: + ek := rv.Type().Elem().Kind() + if ek == reflect.Uint8 { return rv.Bytes(), nil - default: - return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, t.Elem().Kind()) } + return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, ek) case reflect.String: return rv.String(), nil } diff --git a/vendor/github.com/go-sql-driver/mysql/transaction.go b/vendor/github.com/go-sql-driver/mysql/transaction.go index 4a4b6100103..417d72793b1 100644 --- a/vendor/github.com/go-sql-driver/mysql/transaction.go +++ b/vendor/github.com/go-sql-driver/mysql/transaction.go @@ -13,7 +13,7 @@ type mysqlTx struct { } func (tx *mysqlTx) Commit() (err error) { - if tx.mc == nil || tx.mc.closed.Load() { + if tx.mc == nil || tx.mc.closed.IsSet() { return ErrInvalidConn } err = tx.mc.exec("COMMIT") @@ -22,7 +22,7 @@ func (tx *mysqlTx) Commit() (err error) { } func (tx *mysqlTx) Rollback() (err error) { - if tx.mc == nil || tx.mc.closed.Load() { + if tx.mc == nil || tx.mc.closed.IsSet() { return ErrInvalidConn } err = tx.mc.exec("ROLLBACK") diff --git a/vendor/github.com/go-sql-driver/mysql/utils.go b/vendor/github.com/go-sql-driver/mysql/utils.go index 15dbd8d16ab..9552e80b5ac 100644 --- a/vendor/github.com/go-sql-driver/mysql/utils.go +++ b/vendor/github.com/go-sql-driver/mysql/utils.go @@ -35,25 +35,26 @@ var ( // Note: The provided tls.Config is exclusively owned by the driver after // registering it. // -// rootCertPool := x509.NewCertPool() -// pem, err := ioutil.ReadFile("/path/ca-cert.pem") -// if err != nil { -// log.Fatal(err) -// } -// if ok := rootCertPool.AppendCertsFromPEM(pem); !ok { -// log.Fatal("Failed to append PEM.") -// } -// clientCert := make([]tls.Certificate, 0, 1) -// certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-key.pem") -// if err != nil { -// log.Fatal(err) -// } -// clientCert = append(clientCert, certs) -// mysql.RegisterTLSConfig("custom", &tls.Config{ -// RootCAs: rootCertPool, -// Certificates: clientCert, -// }) -// db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom") +// rootCertPool := x509.NewCertPool() +// pem, err := ioutil.ReadFile("/path/ca-cert.pem") +// if err != nil { +// log.Fatal(err) +// } +// if ok := rootCertPool.AppendCertsFromPEM(pem); !ok { +// log.Fatal("Failed to append PEM.") +// } +// clientCert := make([]tls.Certificate, 0, 1) +// certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-key.pem") +// if err != nil { +// log.Fatal(err) +// } +// clientCert = append(clientCert, certs) +// mysql.RegisterTLSConfig("custom", &tls.Config{ +// RootCAs: rootCertPool, +// Certificates: clientCert, +// }) +// db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom") +// func RegisterTLSConfig(key string, config *tls.Config) error { if _, isBool := readBool(key); isBool || strings.ToLower(key) == "skip-verify" || strings.ToLower(key) == "preferred" { return fmt.Errorf("key '%s' is reserved", key) @@ -105,126 +106,27 @@ func readBool(input string) (value bool, valid bool) { * Time related utils * ******************************************************************************/ -func parseDateTime(b []byte, loc *time.Location) (time.Time, error) { - const base = "0000-00-00 00:00:00.000000" - switch len(b) { +func parseDateTime(str string, loc *time.Location) (t time.Time, err error) { + base := "0000-00-00 00:00:00.0000000" + switch len(str) { case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM" - if string(b) == base[:len(b)] { - return time.Time{}, nil - } - - year, err := parseByteYear(b) - if err != nil { - return time.Time{}, err - } - if b[4] != '-' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[4]) - } - - m, err := parseByte2Digits(b[5], b[6]) - if err != nil { - return time.Time{}, err - } - month := time.Month(m) - - if b[7] != '-' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[7]) - } - - day, err := parseByte2Digits(b[8], b[9]) - if err != nil { - return time.Time{}, err - } - if len(b) == 10 { - return time.Date(year, month, day, 0, 0, 0, 0, loc), nil - } - - if b[10] != ' ' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[10]) - } - - hour, err := parseByte2Digits(b[11], b[12]) - if err != nil { - return time.Time{}, err - } - if b[13] != ':' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[13]) - } - - min, err := parseByte2Digits(b[14], b[15]) - if err != nil { - return time.Time{}, err - } - if b[16] != ':' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[16]) - } - - sec, err := parseByte2Digits(b[17], b[18]) - if err != nil { - return time.Time{}, err + if str == base[:len(str)] { + return } - if len(b) == 19 { - return time.Date(year, month, day, hour, min, sec, 0, loc), nil - } - - if b[19] != '.' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[19]) - } - nsec, err := parseByteNanoSec(b[20:]) - if err != nil { - return time.Time{}, err - } - return time.Date(year, month, day, hour, min, sec, nsec, loc), nil + t, err = time.Parse(timeFormat[:len(str)], str) default: - return time.Time{}, fmt.Errorf("invalid time bytes: %s", b) - } -} - -func parseByteYear(b []byte) (int, error) { - year, n := 0, 1000 - for i := 0; i < 4; i++ { - v, err := bToi(b[i]) - if err != nil { - return 0, err - } - year += v * n - n /= 10 - } - return year, nil -} - -func parseByte2Digits(b1, b2 byte) (int, error) { - d1, err := bToi(b1) - if err != nil { - return 0, err - } - d2, err := bToi(b2) - if err != nil { - return 0, err + err = fmt.Errorf("invalid time string: %s", str) + return } - return d1*10 + d2, nil -} -func parseByteNanoSec(b []byte) (int, error) { - ns, digit := 0, 100000 // max is 6-digits - for i := 0; i < len(b); i++ { - v, err := bToi(b[i]) - if err != nil { - return 0, err - } - ns += v * digit - digit /= 10 + // Adjust location + if err == nil && loc != time.UTC { + y, mo, d := t.Date() + h, mi, s := t.Clock() + t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil } - // nanoseconds has 10-digits. (needs to scale digits) - // 10 - 6 = 4, so we have to multiple 1000. - return ns * 1000, nil -} -func bToi(b byte) (int, error) { - if b < '0' || b > '9' { - return 0, errors.New("not [0-9]") - } - return int(b - '0'), nil + return } func parseBinaryDateTime(num uint64, data []byte, loc *time.Location) (driver.Value, error) { @@ -265,64 +167,6 @@ func parseBinaryDateTime(num uint64, data []byte, loc *time.Location) (driver.Va return nil, fmt.Errorf("invalid DATETIME packet length %d", num) } -func appendDateTime(buf []byte, t time.Time) ([]byte, error) { - year, month, day := t.Date() - hour, min, sec := t.Clock() - nsec := t.Nanosecond() - - if year < 1 || year > 9999 { - return buf, errors.New("year is not in the range [1, 9999]: " + strconv.Itoa(year)) // use errors.New instead of fmt.Errorf to avoid year escape to heap - } - year100 := year / 100 - year1 := year % 100 - - var localBuf [len("2006-01-02T15:04:05.999999999")]byte // does not escape - localBuf[0], localBuf[1], localBuf[2], localBuf[3] = digits10[year100], digits01[year100], digits10[year1], digits01[year1] - localBuf[4] = '-' - localBuf[5], localBuf[6] = digits10[month], digits01[month] - localBuf[7] = '-' - localBuf[8], localBuf[9] = digits10[day], digits01[day] - - if hour == 0 && min == 0 && sec == 0 && nsec == 0 { - return append(buf, localBuf[:10]...), nil - } - - localBuf[10] = ' ' - localBuf[11], localBuf[12] = digits10[hour], digits01[hour] - localBuf[13] = ':' - localBuf[14], localBuf[15] = digits10[min], digits01[min] - localBuf[16] = ':' - localBuf[17], localBuf[18] = digits10[sec], digits01[sec] - - if nsec == 0 { - return append(buf, localBuf[:19]...), nil - } - nsec100000000 := nsec / 100000000 - nsec1000000 := (nsec / 1000000) % 100 - nsec10000 := (nsec / 10000) % 100 - nsec100 := (nsec / 100) % 100 - nsec1 := nsec % 100 - localBuf[19] = '.' - - // milli second - localBuf[20], localBuf[21], localBuf[22] = - digits01[nsec100000000], digits10[nsec1000000], digits01[nsec1000000] - // micro second - localBuf[23], localBuf[24], localBuf[25] = - digits10[nsec10000], digits01[nsec10000], digits10[nsec100] - // nano second - localBuf[26], localBuf[27], localBuf[28] = - digits01[nsec100], digits10[nsec1], digits01[nsec1] - - // trim trailing zeros - n := len(localBuf) - for n > 0 && localBuf[n-1] == '0' { - n-- - } - - return append(buf, localBuf[:n]...), nil -} - // zeroDateTime is used in formatBinaryDateTime to avoid an allocation // if the DATE or DATETIME has the zero value. // It must never be changed. @@ -531,7 +375,7 @@ func stringToInt(b []byte) int { return val } -// returns the string read as a bytes slice, whether the value is NULL, +// returns the string read as a bytes slice, wheter the value is NULL, // the number of bytes read and an error, in case the string is longer than // the input slice func readLengthEncodedString(b []byte) ([]byte, bool, int, error) { @@ -641,32 +485,32 @@ func escapeBytesBackslash(buf, v []byte) []byte { for _, c := range v { switch c { case '\x00': - buf[pos+1] = '0' buf[pos] = '\\' + buf[pos+1] = '0' pos += 2 case '\n': - buf[pos+1] = 'n' buf[pos] = '\\' + buf[pos+1] = 'n' pos += 2 case '\r': - buf[pos+1] = 'r' buf[pos] = '\\' + buf[pos+1] = 'r' pos += 2 case '\x1a': - buf[pos+1] = 'Z' buf[pos] = '\\' + buf[pos+1] = 'Z' pos += 2 case '\'': - buf[pos+1] = '\'' buf[pos] = '\\' + buf[pos+1] = '\'' pos += 2 case '"': - buf[pos+1] = '"' buf[pos] = '\\' + buf[pos+1] = '"' pos += 2 case '\\': - buf[pos+1] = '\\' buf[pos] = '\\' + buf[pos+1] = '\\' pos += 2 default: buf[pos] = c @@ -686,32 +530,32 @@ func escapeStringBackslash(buf []byte, v string) []byte { c := v[i] switch c { case '\x00': - buf[pos+1] = '0' buf[pos] = '\\' + buf[pos+1] = '0' pos += 2 case '\n': - buf[pos+1] = 'n' buf[pos] = '\\' + buf[pos+1] = 'n' pos += 2 case '\r': - buf[pos+1] = 'r' buf[pos] = '\\' + buf[pos+1] = 'r' pos += 2 case '\x1a': - buf[pos+1] = 'Z' buf[pos] = '\\' + buf[pos+1] = 'Z' pos += 2 case '\'': - buf[pos+1] = '\'' buf[pos] = '\\' + buf[pos+1] = '\'' pos += 2 case '"': - buf[pos+1] = '"' buf[pos] = '\\' + buf[pos+1] = '"' pos += 2 case '\\': - buf[pos+1] = '\\' buf[pos] = '\\' + buf[pos+1] = '\\' pos += 2 default: buf[pos] = c @@ -733,8 +577,8 @@ func escapeBytesQuotes(buf, v []byte) []byte { for _, c := range v { if c == '\'' { - buf[pos+1] = '\'' buf[pos] = '\'' + buf[pos+1] = '\'' pos += 2 } else { buf[pos] = c @@ -753,8 +597,8 @@ func escapeStringQuotes(buf []byte, v string) []byte { for i := 0; i < len(v); i++ { c := v[i] if c == '\'' { - buf[pos+1] = '\'' buf[pos] = '\'' + buf[pos+1] = '\'' pos += 2 } else { buf[pos] = c @@ -779,16 +623,39 @@ type noCopy struct{} // Lock is a no-op used by -copylocks checker from `go vet`. func (*noCopy) Lock() {} -// Unlock is a no-op used by -copylocks checker from `go vet`. -// noCopy should implement sync.Locker from Go 1.11 -// https://github.com/golang/go/commit/c2eba53e7f80df21d51285879d51ab81bcfbf6bc -// https://github.com/golang/go/issues/26165 -func (*noCopy) Unlock() {} +// atomicBool is a wrapper around uint32 for usage as a boolean value with +// atomic access. +type atomicBool struct { + _noCopy noCopy + value uint32 +} + +// IsSet returns whether the current boolean value is true +func (ab *atomicBool) IsSet() bool { + return atomic.LoadUint32(&ab.value) > 0 +} + +// Set sets the value of the bool regardless of the previous value +func (ab *atomicBool) Set(value bool) { + if value { + atomic.StoreUint32(&ab.value, 1) + } else { + atomic.StoreUint32(&ab.value, 0) + } +} + +// TrySet sets the value of the bool and returns whether the value changed +func (ab *atomicBool) TrySet(value bool) bool { + if value { + return atomic.SwapUint32(&ab.value, 1) == 0 + } + return atomic.SwapUint32(&ab.value, 0) > 0 +} // atomicError is a wrapper for atomically accessed error values type atomicError struct { - _ noCopy - value atomic.Value + _noCopy noCopy + value atomic.Value } // Set sets the error value regardless of the previous value. diff --git a/vendor/modules.txt b/vendor/modules.txt index efc6bee5539..024383f16ae 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -156,8 +156,8 @@ github.com/go-redis/redis/v8/internal/pool github.com/go-redis/redis/v8/internal/proto github.com/go-redis/redis/v8/internal/rand github.com/go-redis/redis/v8/internal/util -# github.com/go-sql-driver/mysql v1.7.1 -## explicit; go 1.13 +# github.com/go-sql-driver/mysql v1.5.0 +## explicit; go 1.10 github.com/go-sql-driver/mysql # github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da ## explicit