mirror of
https://github.com/golang/go
synced 2024-11-23 14:20:05 -07:00
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>
This commit is contained in:
parent
37afd3e311
commit
cf6e4238b6
@ -2605,6 +2605,15 @@ type Rows struct {
|
|||||||
lastcols []driver.Value
|
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) {
|
func (rs *Rows) initContextClose(ctx, txctx context.Context) {
|
||||||
if ctx.Done() == nil && (txctx == nil || txctx.Done() == nil) {
|
if ctx.Done() == nil && (txctx == nil || txctx.Done() == nil) {
|
||||||
return
|
return
|
||||||
@ -2728,22 +2737,22 @@ func (rs *Rows) NextResultSet() bool {
|
|||||||
func (rs *Rows) Err() error {
|
func (rs *Rows) Err() error {
|
||||||
rs.closemu.RLock()
|
rs.closemu.RLock()
|
||||||
defer rs.closemu.RUnlock()
|
defer rs.closemu.RUnlock()
|
||||||
if rs.lasterr == io.EOF {
|
return rs.lasterrOrErrLocked(nil)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return rs.lasterr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errRowsClosed = errors.New("sql: Rows are closed")
|
||||||
|
var errNoRows = errors.New("sql: no Rows available")
|
||||||
|
|
||||||
// Columns returns the column names.
|
// Columns returns the column names.
|
||||||
// Columns returns an error if the rows are closed.
|
// Columns returns an error if the rows are closed.
|
||||||
func (rs *Rows) Columns() ([]string, error) {
|
func (rs *Rows) Columns() ([]string, error) {
|
||||||
rs.closemu.RLock()
|
rs.closemu.RLock()
|
||||||
defer rs.closemu.RUnlock()
|
defer rs.closemu.RUnlock()
|
||||||
if rs.closed {
|
if rs.closed {
|
||||||
return nil, errors.New("sql: Rows are closed")
|
return nil, rs.lasterrOrErrLocked(errRowsClosed)
|
||||||
}
|
}
|
||||||
if rs.rowsi == nil {
|
if rs.rowsi == nil {
|
||||||
return nil, errors.New("sql: no Rows available")
|
return nil, rs.lasterrOrErrLocked(errNoRows)
|
||||||
}
|
}
|
||||||
rs.dc.Lock()
|
rs.dc.Lock()
|
||||||
defer rs.dc.Unlock()
|
defer rs.dc.Unlock()
|
||||||
@ -2757,10 +2766,10 @@ func (rs *Rows) ColumnTypes() ([]*ColumnType, error) {
|
|||||||
rs.closemu.RLock()
|
rs.closemu.RLock()
|
||||||
defer rs.closemu.RUnlock()
|
defer rs.closemu.RUnlock()
|
||||||
if rs.closed {
|
if rs.closed {
|
||||||
return nil, errors.New("sql: Rows are closed")
|
return nil, rs.lasterrOrErrLocked(errRowsClosed)
|
||||||
}
|
}
|
||||||
if rs.rowsi == nil {
|
if rs.rowsi == nil {
|
||||||
return nil, errors.New("sql: no Rows available")
|
return nil, rs.lasterrOrErrLocked(errNoRows)
|
||||||
}
|
}
|
||||||
rs.dc.Lock()
|
rs.dc.Lock()
|
||||||
defer rs.dc.Unlock()
|
defer rs.dc.Unlock()
|
||||||
@ -2916,8 +2925,9 @@ func (rs *Rows) Scan(dest ...interface{}) error {
|
|||||||
return rs.lasterr
|
return rs.lasterr
|
||||||
}
|
}
|
||||||
if rs.closed {
|
if rs.closed {
|
||||||
|
err := rs.lasterrOrErrLocked(errRowsClosed)
|
||||||
rs.closemu.RUnlock()
|
rs.closemu.RUnlock()
|
||||||
return errors.New("sql: Rows are closed")
|
return err
|
||||||
}
|
}
|
||||||
rs.closemu.RUnlock()
|
rs.closemu.RUnlock()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user