Skip to content

Commit 179de68

Browse files
committed
Return true from NpgsqlDataReader.HasRows even after all rows have been read.
1 parent 57d97d0 commit 179de68

2 files changed

Lines changed: 27 additions & 16 deletions

File tree

Npgsql/Npgsql/NpgsqlDataReader.cs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ internal class ForwardsOnlyDataReader : NpgsqlDataReader, IStreamOwner
978978
private long? _lastInsertOID = null;
979979
private long? _nextInsertOID = null;
980980
internal bool _cleanedUp = false;
981+
private bool _hasRows = false;
981982
private readonly NpgsqlConnector.NotificationThreadBlock _threadBlock;
982983

983984
//Unfortunately we sometimes don't know we're going to be dealing with
@@ -1247,6 +1248,11 @@ private NpgsqlRow GetNextRow(bool clearPending)
12471248
{
12481249
_pendingRow = null;
12491250
}
1251+
if (!_hasRows)
1252+
{
1253+
// when rows are found, store that this result has rows.
1254+
_hasRows = (ret != null);
1255+
}
12501256
return ret;
12511257
}
12521258
CurrentRow = null;
@@ -1260,6 +1266,11 @@ private NpgsqlRow GetNextRow(bool clearPending)
12601266
_pendingDescription = objNext as NpgsqlRowDescription;
12611267
return null;
12621268
}
1269+
if (!_hasRows)
1270+
{
1271+
// when rows are found, store that this result has rows.
1272+
_hasRows = objNext is NpgsqlRow;
1273+
}
12631274
return objNext as NpgsqlRow;
12641275
}
12651276

@@ -1302,7 +1313,12 @@ internal override long? LastInsertedOID
13021313
/// </summary>
13031314
public override Boolean HasRows
13041315
{
1305-
get { return GetNextRow(false) != null; }
1316+
get
1317+
{
1318+
// Return true even after the last row has been read in this result.
1319+
// the first call to GetNextRow will set _hasRows to true if rows are found.
1320+
return _hasRows || (GetNextRow(false) != null);
1321+
}
13061322
}
13071323

13081324
private void CleanUp(bool finishedMessages)
@@ -1366,6 +1382,7 @@ private Boolean NextResultInternal()
13661382
{
13671383
CurrentRow = null;
13681384
_currentResultsetSchema = null;
1385+
_hasRows = false; // set to false and let the reading code determine if the set has rows.
13691386
return (_currentDescription = GetNextRowDescription()) != null;
13701387
}
13711388
catch (System.IO.IOException ex)
@@ -1510,6 +1527,7 @@ public long? LastInsertedOID
15101527
private ResultSet _currentResult;
15111528
private DataRow _currentRow;
15121529
private int _lastRecordsAffected;
1530+
private bool _hasRows;
15131531

15141532
public CachingDataReader(ForwardsOnlyDataReader reader, CommandBehavior behavior)
15151533
: base(reader._command, behavior)
@@ -1579,21 +1597,7 @@ internal override NpgsqlRowDescription CurrentDescription
15791597

15801598
public override bool HasRows
15811599
{
1582-
get
1583-
{
1584-
if (_currentRow != null || _currentResult.Count != 0)
1585-
{
1586-
return true;
1587-
}
1588-
foreach (ResultSet rs in _results)
1589-
{
1590-
if (rs.Count != 0)
1591-
{
1592-
return true;
1593-
}
1594-
}
1595-
return false;
1596-
}
1600+
get { return _hasRows; }
15971601
}
15981602

15991603
public override int RecordsAffected
@@ -1664,9 +1668,14 @@ public override bool NextResult()
16641668
if (_results.Count == 0)
16651669
{
16661670
_currentResult = null;
1671+
// clear HasRows after moving past the end of the results.
1672+
_hasRows = false;
16671673
return false;
16681674
}
16691675
_lastRecordsAffected = (_currentResult = _results.Dequeue()).RecordsAffected;
1676+
// HasRows stores if the results has rows even after they have been read for the current results
1677+
// reset as you move to the next results.
1678+
_hasRows = _results.Count != 0;
16701679
return true;
16711680
}
16721681

tests/DataReaderTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ public void HasRowsGetValue()
980980
{
981981
Assert.IsTrue(dr.HasRows);
982982
Assert.IsTrue(dr.Read());
983+
Assert.IsTrue(dr.HasRows);
983984
Assert.AreEqual(1, dr.GetValue(0));
984985
}
985986
}
@@ -996,6 +997,7 @@ public void IntervalAsTimeSpan()
996997
{
997998
Assert.IsTrue(dr.HasRows);
998999
Assert.IsTrue(dr.Read());
1000+
Assert.IsTrue(dr.HasRows);
9991001
var ts = dr.GetTimeSpan(0);
10001002
}
10011003
}

0 commit comments

Comments
 (0)