You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2023/01/25 08:21:33 UTC
[ignite-3] branch main updated: IGNITE-18627 .NET: Fix empty result set handling in IgniteDbDataReader (#1573)
This is an automated email from the ASF dual-hosted git repository.
ptupitsyn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 748c41b56c IGNITE-18627 .NET: Fix empty result set handling in IgniteDbDataReader (#1573)
748c41b56c is described below
commit 748c41b56c026e172e6218001d980ce20dc3a611
Author: Pavel Tupitsyn <pt...@apache.org>
AuthorDate: Wed Jan 25 10:21:27 2023 +0200
IGNITE-18627 .NET: Fix empty result set handling in IgniteDbDataReader (#1573)
* Fix `IndexOutOfRangeException` when reading empty result set
* Fix `HasRows` to return false for empty result set
* Fix `NextResult` to return false instead of throwing exception
---
.../Sql/IgniteDbDataReaderTests.cs | 28 ++++++++++++++++++++--
.../dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs | 6 +++++
.../dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs | 14 +++++------
3 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/IgniteDbDataReaderTests.cs b/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/IgniteDbDataReaderTests.cs
index a0adbae08a..937918196a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/IgniteDbDataReaderTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/IgniteDbDataReaderTests.cs
@@ -555,12 +555,13 @@ public class IgniteDbDataReaderTests : IgniteTestsBase
}
[Test]
+ [SuppressMessage("Performance", "CA1849:Call async methods when in an async method", Justification = "Testing sync method.")]
public async Task TestNextResult()
{
await using var reader = await ExecuteReader();
- Assert.Throws<NotSupportedException>(() => reader.NextResult());
- Assert.ThrowsAsync<NotSupportedException>(() => reader.NextResultAsync());
+ Assert.IsFalse(reader.NextResult());
+ Assert.IsFalse(await reader.NextResultAsync());
}
[Test]
@@ -631,6 +632,18 @@ public class IgniteDbDataReaderTests : IgniteTestsBase
Assert.AreEqual(9, dt.Rows.Count);
}
+ [Test]
+ public async Task TestDataTableLoadEmptyResultSet()
+ {
+ await using var reader = await Client.Sql.ExecuteReaderAsync(null, "SELECT * FROM TBL_ALL_COLUMNS_SQL WHERE KEY > 100");
+
+ var dt = new DataTable();
+ dt.Load(reader);
+
+ Assert.AreEqual(14, dt.Columns.Count);
+ Assert.AreEqual(0, dt.Rows.Count);
+ }
+
[Test]
public void TestExecuteReaderThrowsOnDmlQuery()
{
@@ -640,6 +653,17 @@ public class IgniteDbDataReaderTests : IgniteTestsBase
Assert.AreEqual("ExecuteReaderAsync does not support queries without row set (DDL, DML).", ex!.Message);
}
+ [Test]
+ public async Task TestEmptyResultSet()
+ {
+ await using var reader = await Client.Sql.ExecuteReaderAsync(null, "SELECT * FROM TBL_ALL_COLUMNS_SQL WHERE KEY > 100");
+ bool readRes = await reader.ReadAsync();
+
+ Assert.IsFalse(readRes);
+ Assert.AreEqual(14, reader.FieldCount);
+ Assert.IsFalse(reader.HasRows);
+ }
+
private async Task<IgniteDbDataReader> ExecuteReader()
{
var reader = await Client.Sql.ExecuteReaderAsync(null, AllColumnsQuery);
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs b/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs
index d4003f3e84..4ac7944c30 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs
@@ -78,6 +78,7 @@ namespace Apache.Ignite.Internal.Sql
if (HasRowSet)
{
_buffer = buf.Slice(reader.Consumed);
+ HasRows = reader.ReadArrayHeader() > 0;
}
else
{
@@ -112,6 +113,11 @@ namespace Apache.Ignite.Internal.Sql
/// </summary>
internal bool IsDisposed => (_resourceId == null || _resourceClosed) && _bufferReleased > 0;
+ /// <summary>
+ /// Gets a value indicating whether this result set has any rows in it.
+ /// </summary>
+ internal bool HasRows { get; }
+
/// <inheritdoc/>
public async ValueTask<List<T>> ToListAsync() =>
await CollectAsync(
diff --git a/modules/platforms/dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs b/modules/platforms/dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs
index f18312ef2a..64726ab664 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs
@@ -77,7 +77,7 @@ public sealed class IgniteDbDataReader : DbDataReader, IDbColumnSchemaGenerator
public override int RecordsAffected => checked((int)_resultSet.AffectedRows);
/// <inheritdoc/>
- public override bool HasRows => _resultSet.HasRowSet;
+ public override bool HasRows => _resultSet.HasRows;
/// <inheritdoc/>
public override bool IsClosed => _resultSet.IsDisposed;
@@ -290,7 +290,7 @@ public sealed class IgniteDbDataReader : DbDataReader, IDbColumnSchemaGenerator
public override bool IsDBNull(int ordinal) => GetReader().IsNull(ordinal);
/// <inheritdoc/>
- public override bool NextResult() => throw new NotSupportedException("Batched result sets are not supported.");
+ public override bool NextResult() => false;
/// <inheritdoc/>
public override bool Read() => ReadNextRowInCurrentPage() || FetchNextPage().GetAwaiter().GetResult();
@@ -520,18 +520,18 @@ public sealed class IgniteDbDataReader : DbDataReader, IDbColumnSchemaGenerator
return false;
}
- ReadFirstRowInCurrentPage();
+ return ReadFirstRowInCurrentPage();
- return true;
-
- void ReadFirstRowInCurrentPage()
+ bool ReadFirstRowInCurrentPage()
{
var reader = _pageEnumerator.Current.GetReader();
_pageRowCount = reader.ReadArrayHeader();
_pageRowOffset = reader.Consumed;
- _pageRowSize = reader.ReadBinaryHeader() + reader.Consumed - _pageRowOffset;
_pageRowIndex = 0;
+ _pageRowSize = (_pageRowCount > 0 ? reader.ReadBinaryHeader() : 0) + reader.Consumed - _pageRowOffset;
+
+ return _pageRowCount > 0;
}
}
}