Skip to content

Add prepareMethod=none execution path and tests#2890

Merged
divang merged 12 commits intomainfrom
dev/divang/preparemethod-none
Feb 11, 2026
Merged

Add prepareMethod=none execution path and tests#2890
divang merged 12 commits intomainfrom
dev/divang/preparemethod-none

Conversation

@divang
Copy link
Copy Markdown
Contributor

@divang divang commented Feb 2, 2026

Summary
This PR introduces a new prepareMethod=none connection property option that uses literal parameter substitution + SQL Batch execution for all prepared statements.

When prepareMethod=none is set, the driver always uses literal parameter substitution + SQL Batch for ALL prepared statements, bypassing server-side prepared statement handles (sp_prepexec/sp_prepare). This provides server-side visibility for performance tuning and query analysis.

Changes
Added NONE("none") to PrepareMethod enum in SQLServerDriver.java
Added isPrepareMethodNone execution path in SQLServerPreparedStatement.java

Tests
Basic Functionality Tests:
testBasicOperationsWithPrepareMethodNone - Tests basic CRUD operations with direct SQL execution
testBatchExecutionWithPrepareMethodNone - Validates batch insert operations work correctly
testMultipleDataTypesWithPrepareMethodNone - Tests literal parameter substitution for INT, BIGINT, DECIMAL, FLOAT, VARCHAR, NVARCHAR, BIT, DATE, DATETIME2
testNullValuesWithPrepareMethodNone - Ensures NULL values are correctly substituted in SQL
testSelectQueryWithPrepareMethodNone - Tests parameterized SELECT queries with LIKE and comparison operators

SQL Batch Execution Tests:
testBatchMultipleParameterizedStatementsWithNone - Multiple INSERT statements with parameters in single batch
testBatchNonParameterizedBetweenParameterizedWithNone - Non-parameterized statement (DELETE) between parameterized INSERTs
testBatchMultipleParametersPerStatementWithNone - Verifies correct parameter-to-position mapping across multiple statements
testBatchOnlyNonParameterizedStatementsWithNone - Batch execution with no parameters
testBatchWithStringLiteralsAndCommentsWithNone - SQL parsing edge cases - semicolons in string literals, comments
testBatchParameterMappingCorrectnessWithNone - Validates exact parameter values are inserted in correct tables/columns
testBatchCombinedWithErrorsWithNone - Error handling - duplicate key violation throws SQLException
testLargeBatchWithNone - Scalability test with 100 batch statements

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 2, 2026

Codecov Report

❌ Patch coverage is 96.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 60.57%. Comparing base (dfdadee) to head (3ee1bbe).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
...oft/sqlserver/jdbc/SQLServerPreparedStatement.java 95.45% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2890      +/-   ##
============================================
+ Coverage     58.87%   60.57%   +1.70%     
- Complexity     4778     4907     +129     
============================================
  Files           151      151              
  Lines         34748    34788      +40     
  Branches       5827     5829       +2     
============================================
+ Hits          20457    21074     +617     
+ Misses        11502    10906     -596     
- Partials       2789     2808      +19     

☔ 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.

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

This PR introduces a new prepareMethod=none connection property option that always uses literal parameter substitution and SQL Batch execution for all prepared statements, regardless of whether temporary tables are present. This differs from the existing scopeTempTablesToConnection option (introduced in PR #2844), which only uses direct SQL execution when temporary table operations are detected.

Changes:

  • Added NONE("none") enum value to the PrepareMethod enum in SQLServerDriver.java
  • Updated execution logic in SQLServerPreparedStatement.java to handle the new prepare method in three key areas: request type selection, statement handle caching, and batch execution
  • Added comprehensive test coverage for basic functionality and SQL batch execution scenarios

Reviewed changes

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

File Description
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java Added NONE enum value to PrepareMethod and included it in the available choices array for the prepareMethod connection property
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Added isPrepareMethodNone flag checks in doExecutePreparedStatement, reuseCachedHandle, doPrepExec, and doExecutePreparedStatementBatch to enable direct SQL execution path for the new prepare method
src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PreparedStatementTest.java Added tests to verify the none prepare method can be set via connection property and works for basic insert operations
src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/PrepareMethodScopeTempTablesToConnectionTest.java Added 14 comprehensive tests covering basic functionality (temp table persistence, CRUD operations, batch execution, multiple data types, NULL values, SELECT queries) and SQL batch execution patterns (multiple parameterized statements, non-parameterized statements, parameter mapping, error handling, large batches)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
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

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


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
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

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


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java Outdated
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
…eCachedHandle() and doPrepExec() methods. Added 4 more tests using prepareMethod=none via connection string property
@divang divang added this to the 13.3.2 milestone Feb 4, 2026
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
Move isDirectSqlExecution and usePrepExec flag calculations from
doExecutePreparedStatement() and doPrepExec() to the constructor.

Changes:
- Add final field usePrepExec to determine sp_prepexec vs sp_prepare
- Make isDirectSqlExecution final, calculated once in constructor
- Remove redundant connection.getPrepareMethod() calls on each execution
- Simplify doPrepExec() by using pre-calculated flags
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
…cture

Replace compound boolean expressions with clear if-else branches
for better readability and maintainability.

Changes:
- Restructure flag initialization using explicit if-else for each prepareMethod:
  - NONE: isDirectSqlExecution=true, usePrepExec=false
  - SCOPE_TEMP_TABLES_TO_CONNECTION: depends on temp table detection
  - PREPEXEC: isDirectSqlExecution=false, usePrepExec=true
  - Default (prepare): isDirectSqlExecution=false, usePrepExec=false
- Remove intermediate boolean variable (isScopeTempTables)
- Each case now explicitly sets both flags for clarity
@divang
Copy link
Copy Markdown
Contributor Author

divang commented Feb 9, 2026

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
- Refactored all prepareMethod=none test methods to use finally blocks for resource cleanup instead of cleanup inside try blocks

- Ensures temp tables are dropped even if test assertions fail

- Added assert statements for missing columns in testMultipleDataTypesWithPrepareMethodNone
@divang divang merged commit a0cc3f5 into main Feb 11, 2026
19 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Closed/Merged PRs in MSSQL JDBC Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Closed/Merged PRs

Development

Successfully merging this pull request may close these issues.

5 participants