]> Cypherpunks repositories - gostls13.git/commitdiff
Revert "database/sql: allow drivers to override Scan behavior"
authorAustin Clements <austin@google.com>
Thu, 11 Dec 2025 18:55:33 +0000 (13:55 -0500)
committerAustin Clements <austin@google.com>
Thu, 11 Dec 2025 19:57:52 +0000 (11:57 -0800)
This reverts CL 588435.

This new API is difficult to use correctly, and in many cases cannot
be used efficiently. We're going to work on this problem a bit more.

The release notes are removed by CL 729340, since they were moved to
the x/website repository since the original CL was made.

Reopens #67546.

Change-Id: I2a2bd25f2fce5f02e4d28cd33a9cc651bf35ab50
Reviewed-on: https://go-review.googlesource.com/c/go/+/729360
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sean Liao <sean@liao.dev>
api/go1.26.txt
src/database/sql/driver/driver.go
src/database/sql/sql.go
src/database/sql/sql_test.go

index 87bcebd1af546883ff1278d24d3da8b32dd94fdf..0706895bbdfef45004a9b499bfe1cf33f46c2ab9 100644 (file)
@@ -88,11 +88,6 @@ pkg crypto/x509, func OIDFromASN1OID(asn1.ObjectIdentifier) (OID, error) #75325
 pkg crypto/x509, method (ExtKeyUsage) OID() OID #75325
 pkg crypto/x509, method (ExtKeyUsage) String() string #56866
 pkg crypto/x509, method (KeyUsage) String() string #56866
-pkg database/sql/driver, type RowsColumnScanner interface { Close, Columns, Next, ScanColumn } #67546
-pkg database/sql/driver, type RowsColumnScanner interface, Close() error #67546
-pkg database/sql/driver, type RowsColumnScanner interface, Columns() []string #67546
-pkg database/sql/driver, type RowsColumnScanner interface, Next([]Value) error #67546
-pkg database/sql/driver, type RowsColumnScanner interface, ScanColumn(interface{}, int) error #67546
 pkg debug/elf, const R_LARCH_CALL36 = 110 #75562
 pkg debug/elf, const R_LARCH_CALL36 R_LARCH #75562
 pkg debug/elf, const R_LARCH_TLS_DESC32 = 13 #75562
index 487870be63209ebb711c97983e5a9c55db2b66ab..d0892e80fc28d5e54275751e2861306f926698bd 100644 (file)
@@ -515,18 +515,6 @@ type RowsColumnTypePrecisionScale interface {
        ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool)
 }
 
-// RowsColumnScanner may be implemented by [Rows]. It allows the driver to completely
-// take responsibility for how values are scanned and replace the normal [database/sql].
-// scanning path. This allows drivers to directly support types that do not implement
-// [database/sql.Scanner].
-type RowsColumnScanner interface {
-       Rows
-
-       // ScanColumn copies the column in the current row into the value pointed at by
-       // dest. It returns [ErrSkip] to fall back to the normal [database/sql] scanning path.
-       ScanColumn(dest any, index int) error
-}
-
 // Tx is a transaction.
 type Tx interface {
        Commit() error
index 85b9ffc37d9445c469cad271f7fa76686cad6657..4be450ca87687728797bafdb10e976adc5a71f58 100644 (file)
@@ -3396,16 +3396,7 @@ func (rs *Rows) scanLocked(dest ...any) error {
        }
 
        for i, sv := range rs.lastcols {
-               err := driver.ErrSkip
-
-               if rcs, ok := rs.rowsi.(driver.RowsColumnScanner); ok {
-                       err = rcs.ScanColumn(dest[i], i)
-               }
-
-               if err == driver.ErrSkip {
-                       err = convertAssignRows(dest[i], sv, rs)
-               }
-
+               err := convertAssignRows(dest[i], sv, rs)
                if err != nil {
                        return fmt.Errorf(`sql: Scan error on column index %d, name %q: %w`, i, rs.rowsi.Columns()[i], err)
                }
index 6ee850585589e4d4099f6043fa6c43ba637dc8d4..e8a65600973ba72b3960bb2a193999f414f3f2fa 100644 (file)
@@ -4200,102 +4200,6 @@ func TestNamedValueCheckerSkip(t *testing.T) {
        }
 }
 
-type rcsDriver struct {
-       fakeDriver
-}
-
-func (d *rcsDriver) Open(dsn string) (driver.Conn, error) {
-       c, err := d.fakeDriver.Open(dsn)
-       fc := c.(*fakeConn)
-       fc.db.allowAny = true
-       return &rcsConn{fc}, err
-}
-
-type rcsConn struct {
-       *fakeConn
-}
-
-func (c *rcsConn) PrepareContext(ctx context.Context, q string) (driver.Stmt, error) {
-       stmt, err := c.fakeConn.PrepareContext(ctx, q)
-       if err != nil {
-               return stmt, err
-       }
-       return &rcsStmt{stmt.(*fakeStmt)}, nil
-}
-
-type rcsStmt struct {
-       *fakeStmt
-}
-
-func (s *rcsStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
-       rows, err := s.fakeStmt.QueryContext(ctx, args)
-       if err != nil {
-               return rows, err
-       }
-       return &rcsRows{rows.(*rowsCursor)}, nil
-}
-
-type rcsRows struct {
-       *rowsCursor
-}
-
-func (r *rcsRows) ScanColumn(dest any, index int) error {
-       switch d := dest.(type) {
-       case *int64:
-               *d = 42
-               return nil
-       }
-
-       return driver.ErrSkip
-}
-
-func TestRowsColumnScanner(t *testing.T) {
-       Register("RowsColumnScanner", &rcsDriver{})
-       db, err := Open("RowsColumnScanner", "")
-       if err != nil {
-               t.Fatal(err)
-       }
-       defer db.Close()
-
-       ctx, cancel := context.WithCancel(context.Background())
-       defer cancel()
-
-       _, err = db.ExecContext(ctx, "CREATE|t|str=string,n=int64")
-       if err != nil {
-               t.Fatal("exec create", err)
-       }
-
-       _, err = db.ExecContext(ctx, "INSERT|t|str=?,n=?", "foo", int64(1))
-       if err != nil {
-               t.Fatal("exec insert", err)
-       }
-       var (
-               str string
-               i64 int64
-               i   int
-               f64 float64
-               ui  uint
-       )
-       err = db.QueryRowContext(ctx, "SELECT|t|str,n,n,n,n|").Scan(&str, &i64, &i, &f64, &ui)
-       if err != nil {
-               t.Fatal("select", err)
-       }
-
-       list := []struct{ got, want any }{
-               {str, "foo"},
-               {i64, int64(42)},
-               {i, int(1)},
-               {f64, float64(1)},
-               {ui, uint(1)},
-       }
-
-       for index, item := range list {
-               if !reflect.DeepEqual(item.got, item.want) {
-                       t.Errorf("got %#v wanted %#v for index %d", item.got, item.want, index)
-               }
-       }
-}
-
 func TestOpenConnector(t *testing.T) {
        Register("testctx", &fakeDriverCtx{})
        db, err := Open("testctx", "people")