@@ -2605,6 +2605,15 @@ type Rows struct {
2605
2605
lastcols []driver.Value
2606
2606
}
2607
2607
2608
+ // lasterrOrErrLocked returns either lasterr or the provided err.
2609
+ // rs.closemu must be read-locked.
2610
+ func (rs * Rows ) lasterrOrErrLocked (err error ) error {
2611
+ if rs .lasterr != nil && rs .lasterr != io .EOF {
2612
+ return rs .lasterr
2613
+ }
2614
+ return err
2615
+ }
2616
+
2608
2617
func (rs * Rows ) initContextClose (ctx , txctx context.Context ) {
2609
2618
if ctx .Done () == nil && (txctx == nil || txctx .Done () == nil ) {
2610
2619
return
@@ -2728,22 +2737,22 @@ func (rs *Rows) NextResultSet() bool {
2728
2737
func (rs * Rows ) Err () error {
2729
2738
rs .closemu .RLock ()
2730
2739
defer rs .closemu .RUnlock ()
2731
- if rs .lasterr == io .EOF {
2732
- return nil
2733
- }
2734
- return rs .lasterr
2740
+ return rs .lasterrOrErrLocked (nil )
2735
2741
}
2736
2742
2743
+ var errRowsClosed = errors .New ("sql: Rows are closed" )
2744
+ var errNoRows = errors .New ("sql: no Rows available" )
2745
+
2737
2746
// Columns returns the column names.
2738
2747
// Columns returns an error if the rows are closed.
2739
2748
func (rs * Rows ) Columns () ([]string , error ) {
2740
2749
rs .closemu .RLock ()
2741
2750
defer rs .closemu .RUnlock ()
2742
2751
if rs .closed {
2743
- return nil , errors . New ( "sql: Rows are closed" )
2752
+ return nil , rs . lasterrOrErrLocked ( errRowsClosed )
2744
2753
}
2745
2754
if rs .rowsi == nil {
2746
- return nil , errors . New ( "sql: no Rows available" )
2755
+ return nil , rs . lasterrOrErrLocked ( errNoRows )
2747
2756
}
2748
2757
rs .dc .Lock ()
2749
2758
defer rs .dc .Unlock ()
@@ -2757,10 +2766,10 @@ func (rs *Rows) ColumnTypes() ([]*ColumnType, error) {
2757
2766
rs .closemu .RLock ()
2758
2767
defer rs .closemu .RUnlock ()
2759
2768
if rs .closed {
2760
- return nil , errors . New ( "sql: Rows are closed" )
2769
+ return nil , rs . lasterrOrErrLocked ( errRowsClosed )
2761
2770
}
2762
2771
if rs .rowsi == nil {
2763
- return nil , errors . New ( "sql: no Rows available" )
2772
+ return nil , rs . lasterrOrErrLocked ( errNoRows )
2764
2773
}
2765
2774
rs .dc .Lock ()
2766
2775
defer rs .dc .Unlock ()
@@ -2916,8 +2925,9 @@ func (rs *Rows) Scan(dest ...interface{}) error {
2916
2925
return rs .lasterr
2917
2926
}
2918
2927
if rs .closed {
2928
+ err := rs .lasterrOrErrLocked (errRowsClosed )
2919
2929
rs .closemu .RUnlock ()
2920
- return errors . New ( "sql: Rows are closed" )
2930
+ return err
2921
2931
}
2922
2932
rs .closemu .RUnlock ()
2923
2933
0 commit comments