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[]