aboutsummaryrefslogtreecommitdiff
path: root/src/database
diff options
context:
space:
mode:
authorDaniel Theophanes <kardianos@gmail.com>2018-10-27 14:12:52 -0700
committerDaniel Theophanes <kardianos@gmail.com>2018-10-29 16:11:22 +0000
commitcf6e4238b63a180abd5a390dc8f11d50f024ba35 (patch)
tree820a76602dd6b1743e75f9f43f07b25683d26e02 /src/database
parent37afd3e31100a06229da61549abf5210a1dae8d0 (diff)
downloadgo-cf6e4238b63a180abd5a390dc8f11d50f024ba35.tar.gz
go-cf6e4238b63a180abd5a390dc8f11d50f024ba35.zip
database/sql: prefer to return Rows.lasterr rather then a static error
Fixes #25829 Change-Id: I400fdaf0ef3a23bc0d61c4873ffa298e0cf0fc6a Reviewed-on: https://go-review.googlesource.com/c/145204 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/database')
-rw-r--r--src/database/sql/sql.go28
1 files changed, 19 insertions, 9 deletions
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index 1ffe252ee3..31db7a47d6 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -2605,6 +2605,15 @@ type Rows struct {
lastcols []driver.Value
}
+// lasterrOrErrLocked returns either lasterr or the provided err.
+// rs.closemu must be read-locked.
+func (rs *Rows) lasterrOrErrLocked(err error) error {
+ if rs.lasterr != nil && rs.lasterr != io.EOF {
+ return rs.lasterr
+ }
+ return err
+}
+
func (rs *Rows) initContextClose(ctx, txctx context.Context) {
if ctx.Done() == nil && (txctx == nil || txctx.Done() == nil) {
return
@@ -2728,22 +2737,22 @@ func (rs *Rows) NextResultSet() bool {
func (rs *Rows) Err() error {
rs.closemu.RLock()
defer rs.closemu.RUnlock()
- if rs.lasterr == io.EOF {
- return nil
- }
- return rs.lasterr
+ return rs.lasterrOrErrLocked(nil)
}
+var errRowsClosed = errors.New("sql: Rows are closed")
+var errNoRows = errors.New("sql: no Rows available")
+
// Columns returns the column names.
// Columns returns an error if the rows are closed.
func (rs *Rows) Columns() ([]string, error) {
rs.closemu.RLock()
defer rs.closemu.RUnlock()
if rs.closed {
- return nil, errors.New("sql: Rows are closed")
+ return nil, rs.lasterrOrErrLocked(errRowsClosed)
}
if rs.rowsi == nil {
- return nil, errors.New("sql: no Rows available")
+ return nil, rs.lasterrOrErrLocked(errNoRows)
}
rs.dc.Lock()
defer rs.dc.Unlock()
@@ -2757,10 +2766,10 @@ func (rs *Rows) ColumnTypes() ([]*ColumnType, error) {
rs.closemu.RLock()
defer rs.closemu.RUnlock()
if rs.closed {
- return nil, errors.New("sql: Rows are closed")
+ return nil, rs.lasterrOrErrLocked(errRowsClosed)
}
if rs.rowsi == nil {
- return nil, errors.New("sql: no Rows available")
+ return nil, rs.lasterrOrErrLocked(errNoRows)
}
rs.dc.Lock()
defer rs.dc.Unlock()
@@ -2916,8 +2925,9 @@ func (rs *Rows) Scan(dest ...interface{}) error {
return rs.lasterr
}
if rs.closed {
+ err := rs.lasterrOrErrLocked(errRowsClosed)
rs.closemu.RUnlock()
- return errors.New("sql: Rows are closed")
+ return err
}
rs.closemu.RUnlock()