Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@ jobs:
'1.26',
'1.25',
]
mysql = [ # LTS versions
# MySQL LTS versions. Upstream also covers MariaDB; this fork does
# not, because Block does not deploy against it.
mysql = [
'9.7',
'8.4',
'8.0',
'mariadb-12.3',
'mariadb-11.8',
'mariadb-11.4',
'mariadb-10.11',
]

includes = []
Expand All @@ -50,8 +48,10 @@ jobs:
includes.append({'os': 'ubuntu-latest', 'go': v, 'mysql': mysql[0]})

matrix = {
# OS vs MySQL versions
'os': [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ],
# MySQL versions. Upstream also runs macos-latest and
# windows-latest; this fork is Linux-only, which additionally
# avoids a Windows-runner TCP dial flake upstream sees too.
'os': [ 'ubuntu-latest' ],
'go': [ go[0] ],
'mysql': mysql,

Expand Down
103 changes: 99 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,100 @@
# block/mysql

**A tracking fork of [go-sql-driver/mysql](https://github.com/go-sql-driver/mysql).**

Block depends on a small number of additive capabilities that aren't in
upstream yet. This fork exists to carry them until they are, and nothing more:
upstream is merged forward regularly and the delta is kept deliberately small,
so the fork can be retired if and when upstream adopts them.

The upstream README follows below the separator, edited only where it names the
import path or driver name.

## What this fork adds

| Capability | What it is | Upstream status |
| --- | --- | --- |
| [`QueryResultContext`](unified.go) | Executes arbitrary SQL and returns the response in the shape the server chose — exactly one of `driver.Rows` or `driver.Result`. Callers handling SQL they did not write (a proxy, a REPL) otherwise have to classify statements up front to pick between `QueryContext` and `ExecContext`, and a misclassification either discards a resultset or loses the OK-packet metadata. | Raised upstream as [go-sql-driver/mysql#1793](https://github.com/go-sql-driver/mysql/issues/1793), still open. Merged here as [#1](https://github.com/block/mysql/pull/1). |
| [`Warnings()`](warnings.go) | Exposes the warning count from the OK/EOF packet that terminated the last statement — the same number MySQL reports as `@@warning_count`. Warnings themselves live in per-connection state that only `SHOW WARNINGS` can read, so the count is what makes surfacing them affordable: it says whether that round trip would return anything. | Not yet raised upstream. Merged here as [#2](https://github.com/block/mysql/pull/2). |

Both are reached through `(*sql.Conn).Raw` and a structural interface
assertion, so a consumer can depend on the *capability* without a compile-time
dependency on this module. See the doc comments in `unified.go` and
`warnings.go` for the exact contracts.

## What this fork changes

Two things, both for packaging reasons only. Neither alters protocol behaviour.

**The module path is `github.com/block/mysql`.** Upstream's path plus a
`replace` directive would work for a binary, but `replace` is not inherited
across module boundaries: a downstream module importing a *library* built on
this fork gets upstream go-sql-driver instead, with no diagnostic. Depending on
how the library reaches the fork's features that is either a compile failure or
— worse, and the case that motivated this change — a clean build that fails at
runtime. A distinct module path is the only mechanism Go has for expressing a
dependency that is not substitutable.

**The driver registers as `block-mysql`, not `mysql`.** This is required rather
than cosmetic. Because the module path now differs, a dependency graph that
still reaches upstream go-sql-driver anywhere links both packages into one
binary, and two `sql.Register` calls under the same name panic at init. Open
connections with:

```go
db, err := sql.Open("block-mysql", dsn)
```

The DSN format, `Config`, and the rest of the API are upstream's.

## Linking both drivers

Where a binary links this fork *and* upstream, remember that the two packages
declare distinct types even though the source is identical. Most importantly,
an `*mysql.MySQLError` produced by this package will not satisfy an
`errors.As` against upstream's `*mysql.MySQLError`, and vice versa — the check
silently returns false rather than failing loudly. Be deliberate about which
package each error-inspection site imports, and prefer moving code you control
onto one of the two.

## Staying current

```bash
git remote add upstream https://github.com/go-sql-driver/mysql.git
git fetch upstream
git merge upstream/master
```

Edits to upstream files are confined to two things: the module path and driver
name (`go.mod`, `driver.go`, plus doc comments and test call sites that spell
either one out), and the CI matrix (see below). The capabilities above live in
files upstream does not have, which is what keeps merges near-mechanical.
Additions are cheapest when they follow the same shape: new files, or new
methods on existing types, in preference to reworking an upstream code path.

## Supported platforms

Narrower than upstream, and deliberately so — CI covers **Linux with MySQL LTS
(9.7, 8.4, 8.0)**, plus the two previous Go releases against the newest MySQL.

Upstream additionally tests macOS and Windows runners and four MariaDB
versions. Block deploys none of those, so the fork drops them: 5 CI jobs rather
than 25, and no exposure to the Windows-runner TCP dial flake that upstream's
own CI also hits. Nothing about the driver is Linux- or MySQL-specific — the
platforms are merely untested here, so treat upstream as the authority on them.

## License

MPL-2.0, unchanged from upstream, as are `LICENSE` and `AUTHORS`. Modified and
added files stay under the MPL and are published here in satisfaction of it.
Copyright in the original work remains with The Go-MySQL-Driver Authors.

---------------------------------------

# Go-MySQL-Driver

*Upstream README follows.*

[![DeepWiki](https://img.shields.io/badge/DeepWiki-go--sql--driver%2Fmysql-blue.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK/AIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06/uv1saEDv4O3n3dV60RfP947Mm9/SQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH//PB8mnKqScAhsD0kYP3j/Yt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY/56ebRWeraTjMt/00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB/imwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h/U4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5/XFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb/vA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26/HfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr/FGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r/cKaoqr+27/XcrS5UwSMbQAAAABJRU5ErkJggg==)](https://deepwiki.com/go-sql-driver/mysql)


Expand Down Expand Up @@ -60,26 +155,26 @@ A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) pac
## Installation
Simple install the package to your [$GOPATH](https://github.com/golang/go/wiki/GOPATH "GOPATH") with the [go tool](https://golang.org/cmd/go/ "go command") from shell:
```bash
go get -u github.com/go-sql-driver/mysql
go get -u github.com/block/mysql
```
Comment thread
morgo marked this conversation as resolved.
Make sure [Git is installed](https://git-scm.com/downloads) on your machine and in your system's `PATH`.

## Usage
_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`:
Use `block-mysql` as `driverName` and a valid [DSN](#dsn-data-source-name) as `dataSourceName`:

```go
import (
"database/sql"
"time"

_ "github.com/go-sql-driver/mysql"
_ "github.com/block/mysql"
)

// ...

db, err := sql.Open("mysql", "user:password@/dbname")
db, err := sql.Open("block-mysql", "user:password@/dbname")
if err != nil {
panic(err)
}
Expand Down
19 changes: 13 additions & 6 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@

// Package mysql provides a MySQL driver for Go's database/sql package.
//
// The driver should be used via the database/sql package:
// This is Block's tracking fork of github.com/go-sql-driver/mysql. It
// registers itself as "block-mysql" rather than "mysql" so that it can be
// linked alongside upstream without a duplicate-registration panic:
//
// import "database/sql"
// import _ "github.com/go-sql-driver/mysql"
// import _ "github.com/block/mysql"
//
// db, err := sql.Open("mysql", "user:password@/dbname")
// db, err := sql.Open("block-mysql", "user:password@/dbname")
//
// See https://github.com/go-sql-driver/mysql#usage for details
// See https://github.com/block/mysql#usage for details, and the README for
// what this fork adds over upstream.
package mysql

import (
Expand Down Expand Up @@ -88,8 +91,12 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
}

// This variable can be replaced with -ldflags like below:
// go build "-ldflags=-X github.com/go-sql-driver/mysql.driverName=custom"
var driverName = "mysql"
// go build "-ldflags=-X github.com/block/mysql.driverName=custom"
//
// It is "block-mysql" rather than upstream's "mysql" because a build whose
// dependency graph still reaches upstream go-sql-driver links both packages,
// and two sql.Register calls under one name panic at init.
var driverName = "block-mysql"

func init() {
if driverName != "" {
Expand Down
8 changes: 4 additions & 4 deletions driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
)

// This variable can be replaced with -ldflags like below:
// go test "-ldflags=-X github.com/go-sql-driver/mysql.driverNameTest=custom"
// go test "-ldflags=-X github.com/block/mysql.driverNameTest=custom"
var driverNameTest string

func init() {
Expand Down Expand Up @@ -224,7 +224,7 @@ func runTestsParallel(t *testing.T, dsn string, tests ...func(dbt *DBTest, table
t.Parallel()

tableName := newTableName(t)
db, err := sql.Open("mysql", dsn)
db, err := sql.Open(driverNameTest, dsn)
if err != nil {
t.Fatalf("error connecting: %s", err.Error())
}
Expand All @@ -243,7 +243,7 @@ func runTestsParallel(t *testing.T, dsn string, tests ...func(dbt *DBTest, table
t.Parallel()

tableName := newTableName(t)
db, err := sql.Open("mysql", dsn2)
db, err := sql.Open(driverNameTest, dsn2)
if err != nil {
t.Fatalf("error connecting: %s", err.Error())
}
Expand Down Expand Up @@ -3583,7 +3583,7 @@ func TestErrorInMultiResult(t *testing.T) {
// https://github.com/go-sql-driver/mysql/issues/1361
var db *sql.DB
if _, err := ParseDSN(dsn); err != errInvalidDSNUnsafeCollation {
db, err = sql.Open("mysql", dsn)
db, err = sql.Open(driverNameTest, dsn)
if err != nil {
t.Fatalf("error connecting: %s", err.Error())
}
Expand Down
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
module github.com/go-sql-driver/mysql
// This is Block's tracking fork of github.com/go-sql-driver/mysql. The module
// path differs from upstream deliberately: a `replace` directive is not
// inherited across module boundaries, so consumers of a library built on this
// fork would silently link upstream instead. See README.md.
module github.com/block/mysql

go 1.25.0

Expand Down
2 changes: 1 addition & 1 deletion utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var (
// RootCAs: rootCertPool,
// Certificates: clientCert,
// })
// db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom")
// db, err := sql.Open("block-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)
Expand Down
Loading