Skip to content

[6.1] Port #3912 to release/6.1#4133

Merged
paulmedynski merged 2 commits intodev/samsharma2700/backport_3912_61from
copilot/sub-pr-3947
Apr 2, 2026
Merged

[6.1] Port #3912 to release/6.1#4133
paulmedynski merged 2 commits intodev/samsharma2700/backport_3912_61from
copilot/sub-pr-3947

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 2, 2026

Description

Ports the fix for #3736 (ExecuteScalar/ExecuteScalarAsync silently discarding server errors after the first result) into release/6.1, and addresses review feedback on the initial port.

ExecuteScalarAsync cancellation semantics (netcore + netfx):

  • The async drain loop's catch block now distinguishes OperationCanceledException from other exceptions, calling source.SetCanceled() instead of source.SetException(e) so a canceled ExecuteScalarAsync produces a properly canceled task rather than a faulted one.

Regression test reliability (SqlCommandExecuteScalarTest.cs):

  • All test tables now declare Id as PRIMARY KEY CLUSTERED, ensuring SQL Server scans rows in insertion order (Id=1 before Id=2). Without this, a heap scan could encounter the conversion error before returning any row, bypassing the specific code path under test.
  • Fixed comment wording: "not an invalid number""but not a valid number".

Dead code removal (MultipleResultsTest.cs):

  • Removed the unused ConcurrentQueue<string> messages and InfoMessage handler from ExecuteScalar() after the test was updated to use Assert.Throws<SqlException>.

Issues

Testing

  • Existing manual regression tests (ExecuteScalar_ShouldThrowOnConversionError, ExecuteScalarAsync_ShouldThrowOnConversionError, and their transaction variants) now run against tables with a clustered primary key, making scan order deterministic and the tests reliable.
  • No new test logic added; changes are structural improvements to existing tests.

Guidelines

Please review the contribution guidelines before submitting a pull request:

Copilot AI changed the title [WIP] Port #3912 to release/6.1 to fix Execute Scalar issue [6.1] Port #3912 to release/6.1 Apr 2, 2026
Copilot AI requested a review from paulmedynski April 2, 2026 19:11
@paulmedynski paulmedynski marked this pull request as ready for review April 2, 2026 19:17
@paulmedynski paulmedynski requested a review from a team as a code owner April 2, 2026 19:17
Copilot AI review requested due to automatic review settings April 2, 2026 19:17
@paulmedynski paulmedynski moved this from To triage to In review in SqlClient Board Apr 2, 2026
@paulmedynski paulmedynski merged commit 113aab3 into dev/samsharma2700/backport_3912_61 Apr 2, 2026
4 checks passed
@paulmedynski paulmedynski deleted the copilot/sub-pr-3947 branch April 2, 2026 19:18
@github-project-automation github-project-automation bot moved this from In review to Done in SqlClient Board Apr 2, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports the GH #3736 fix to release/6.1, ensuring ExecuteScalar/ExecuteScalarAsync properly surface server errors that occur after the first result, and incorporates review-driven improvements for cancellation behavior and test reliability.

Changes:

  • Updated InternalExecuteScalarAsync (netcore + netfx) to treat OperationCanceledException as task cancellation (rather than faulting) when the provided cancellation token is canceled.
  • Made ExecuteScalar regression ManualTests deterministic by adding PRIMARY KEY CLUSTERED to identity columns used by the test tables and adjusted related comments.
  • Removed unused InfoMessage/ConcurrentQueue plumbing from MultipleResultsTest.ExecuteScalar().

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandExecuteScalarTest.cs Makes regression test table scans more deterministic via clustered PK and updates comments.
src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs Removes unused message-collection code from the ExecuteScalar test.
src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs Ensures canceled ExecuteScalarAsync completes as canceled (not faulted) in the drain-loop cleanup path.
src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs Same cancellation semantics adjustment as netfx for ExecuteScalarAsync.

// sourceTable.Val is VARCHAR - both '12345' and '42-43' are valid strings
DataTestUtility.CreateTable(connection, sourceTable, "(Id INT IDENTITY(1,1) NOT NULL, Val VARCHAR(10) NOT NULL)");
DataTestUtility.CreateTable(connection, targetTable, "(Id INT IDENTITY(1,1) NOT NULL, Val1 INT NOT NULL, Val2 INT NOT NULL)");
// sourceTable.Val is VARCHAR - both '12345' and '42-43' are valid strings but not valid numbers
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is inaccurate: '12345' is a valid number when converting VARCHAR to INT; only '42-43' fails conversion. Consider rewording to avoid implying both values are not valid numbers (e.g., clarify that one value converts and the other does not).

Suggested change
// sourceTable.Val is VARCHAR - both '12345' and '42-43' are valid strings but not valid numbers
// sourceTable.Val is VARCHAR - both '12345' and '42-43' are valid strings, but only '12345' converts to INT

Copilot uses AI. Check for mistakes.
// sourceTable.Val is VARCHAR - both '12345' and '42-43' are valid strings
DataTestUtility.CreateTable(connection, sourceTable, "(Id INT IDENTITY(1,1) NOT NULL, Val VARCHAR(10) NOT NULL)");
DataTestUtility.CreateTable(connection, targetTable, "(Id INT IDENTITY(1,1) NOT NULL, Val1 INT NOT NULL, Val2 INT NOT NULL)");
// sourceTable.Val is VARCHAR - both '12345' and '42-43' are valid strings but not valid numbers
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is inaccurate: '12345' converts to INT successfully; the conversion error is caused by the '42-43' row. Rewording this will prevent confusion when interpreting why the WHERE clause throws.

Suggested change
// sourceTable.Val is VARCHAR - both '12345' and '42-43' are valid strings but not valid numbers
// sourceTable.Val is VARCHAR - both '12345' and '42-43' are valid strings, but only '42-43' cannot be converted to INT

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants