Skip to content

Fix update count handling for multi-statement queries executed via PreparedStatement. (#2722) - #2737

Merged
Ananya Garg (Ananya2) merged 3 commits into
mainfrom
user/anagarg/issue#2722
Aug 13, 2025
Merged

Fix update count handling for multi-statement queries executed via PreparedStatement. (#2722)#2737
Ananya Garg (Ananya2) merged 3 commits into
mainfrom
user/anagarg/issue#2722

Conversation

@Ananya2

@Ananya2 Ananya Garg (Ananya2) commented Aug 12, 2025

Copy link
Copy Markdown
Contributor

Description
This PR addresses an inconsistency in how PreparedStatement handles update counts for multi-statement queries, particularly when INSERT operations are involved.

Issue
When executing multi-statement queries containing INSERT operations, PreparedStatement returned different update counts compared to Statement due to differences in Tabular Data Stream (TDS) token processing:

  • Statement: Requires reading an additional TDS_DONE token for INSERT operations to obtain the correct update count.
  • PreparedStatement: Does not require this additional token processing, but was incorrectly using the same logic as Statement, leading to inaccurate update counts.

Example of inconsistent behavior:
PreparedStatement ps = conn.prepareStatement( "DELETE FROM TestTable; " + "INSERT INTO TestTable (c1,c2) VALUES (?, ?); " + "INSERT INTO TestTable (c1,c2) VALUES (?, ?); " + "UPDATE TestTable SET C1 = 1; " + "INSERT INTO TestTable (c1,c2) VALUES (?, ?); " + "SELECT * FROM TestTable" ); do { boolean hasResults = ps.getMoreResults(); System.out.println("update count: " + ps.getUpdateCount() + ", has result: " + hasResults); } while (true);

  • Driver 12.10 output:
    update count: 3, has result :false update count: 1, has result :false update count: 1, has result :false update count: 2, has result :false update count: 1, has result :false update count: -1, has result :true
  • Driver 13.1 output:
    update count: 3, has result :false update count: 2, has result :false update count: 1, has result :false update count: -1, has result :true

Root Cause
In PR #2554, the following logic was added to handle INSERT operations:
if ((StreamDone.CMD_INSERT == doneToken.getCurCmd()) && (-1 != doneToken.getUpdateCount()) && EXECUTE == executeMethod) { return true; }
This logic is correct for Statement but not for PreparedStatement.
For PreparedStatement, the execute API for INSERT does not require reading an additional explicit TDS_DONE token — applying the same logic caused incorrect update counts.

Fix
Added overridden methods to correctly handle update count retrieval in both PreparedStatement and SQLServerStatement, ensuring that each uses the appropriate TDS token processing logic.

Testing

  • Verified all existing tests pass.
  • Added new test cases covering various combinations of execute API calls via PreparedStatement to validate update counts for INSERT, UPDATE, DELETE, and MERGE operations, followed by explicit SELECT statements.

Closes #2722

@codecov

codecov Bot commented Aug 12, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 1 line in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@1ed161f). Learn more about missing BASE report.
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...m/microsoft/sqlserver/jdbc/SQLServerStatement.java 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2737   +/-   ##
=======================================
  Coverage        ?   51.54%           
  Complexity      ?     4071           
=======================================
  Files           ?      149           
  Lines           ?    34244           
  Branches        ?     5719           
=======================================
  Hits            ?    17650           
  Misses          ?    14104           
  Partials        ?     2490           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java Outdated
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java Outdated

@David-Engel David Engel (David-Engel) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just the changes around unnecessary catching of exceptions in new tests. Otherwise approved.

Comment thread src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/StatementTest.java Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Concatenated select SQL Statement returns null in JDBC Driver 12.10

5 participants