From 4576eb65ad72d67f3f4ed1ece516e84dd92bcd68 Mon Sep 17 00:00:00 2001
From: Francois Jehl <16541584+francoisjehl@users.noreply.github.com>
Date: Wed, 14 Oct 2026 14:30:28 +0200
Subject: [PATCH] fix: clamp RecordsAffected to int.MaxValue instead of
throwing OverflowException
---
src/SingleStoreConnector/SingleStoreDataReader.cs | 5 +++--
tests/SingleStoreConnector.Tests/ConnectionTests.cs | 9 +++++++++
.../FakeSingleStoreServerConnection.cs | 12 ++++++++++++
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/src/SingleStoreConnector/SingleStoreDataReader.cs b/src/SingleStoreConnector/SingleStoreDataReader.cs
index 92ed68a5a..69bdae93e 100644
--- a/src/SingleStoreConnector/SingleStoreDataReader.cs
+++ b/src/SingleStoreConnector/SingleStoreDataReader.cs
@@ -208,8 +208,9 @@ public override bool HasRows
///
/// For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command.
/// For stored procedures, the return value is the number of rows affected by the last statement in the stored procedure,
- /// or zero if the last statement is a SELECT. For all other types of statements, the return value is -1.
- public override int RecordsAffected => RealRecordsAffected is ulong recordsAffected ? checked((int) recordsAffected) : -1;
+ /// or zero if the last statement is a SELECT. For all other types of statements, the return value is -1.
+ /// If the number of affected rows exceeds , the return value is .
+ public override int RecordsAffected => RealRecordsAffected is ulong recordsAffected ? (int) Math.Min(recordsAffected, int.MaxValue) : -1;
public override int GetOrdinal(string name) => GetResultSet().GetOrdinal(name);
public override bool GetBoolean(int ordinal) => GetResultSet().GetCurrentRow().GetBoolean(ordinal);
diff --git a/tests/SingleStoreConnector.Tests/ConnectionTests.cs b/tests/SingleStoreConnector.Tests/ConnectionTests.cs
index 6f453f1a8..087b54368 100644
--- a/tests/SingleStoreConnector.Tests/ConnectionTests.cs
+++ b/tests/SingleStoreConnector.Tests/ConnectionTests.cs
@@ -19,6 +19,15 @@ public void Dispose()
m_server.Stop();
}
+ [Fact]
+ public void RecordsAffectedAboveInt32MaxValueIsClamped()
+ {
+ using var connection = new SingleStoreConnection(m_csb.ConnectionString);
+ connection.Open();
+ using var command = new SingleStoreCommand("ALTER TABLE big_table ADD COLUMN c INT", connection);
+ Assert.Equal(int.MaxValue, command.ExecuteNonQuery());
+ }
+
[Fact]
public void PooledConnectionIsReturnedToPool()
{
diff --git a/tests/SingleStoreConnector.Tests/FakeSingleStoreServerConnection.cs b/tests/SingleStoreConnector.Tests/FakeSingleStoreServerConnection.cs
index 3b3eabedd..22453f687 100644
--- a/tests/SingleStoreConnector.Tests/FakeSingleStoreServerConnection.cs
+++ b/tests/SingleStoreConnector.Tests/FakeSingleStoreServerConnection.cs
@@ -167,6 +167,18 @@ public async Task RunAsync(TcpClient client, CancellationToken token)
var wasSet = CancelQueryEvent.Wait(0, token);
await SendAsync(stream, 1, WriteOk);
}
+ else if (query == "ALTER TABLE big_table ADD COLUMN c INT")
+ {
+ await SendAsync(stream, 1, x =>
+ {
+ x.Write((byte) 0); // signature
+ x.Write((byte) 0xFE); // 8-byte length-encoded integer
+ x.Write(4_000_000_000UL); // rows affected
+ x.Write((byte) 0); // last insert ID
+ x.Write((ushort) 0); // server status
+ x.Write((ushort) 0); // warning count
+ });
+ }
else if (query == "select infinity")
{
var packets = new[]