Skip to content

Conversation

@divang
Copy link
Contributor

@divang divang commented Nov 18, 2025

Objective
Introduce a new way to execute prepared statements using a single batch execution method.

Solution
Added a new prepareMethod option value: exec. When selected, this method substitutes parameters directly into the SQL and executes the statement as a single batch, rather than preparing and executing in separate steps.

Testing
Unit and integration tests have been added to validate the correct behavior of the exec prepare method. The tests ensure that statements execute successfully and that parameters are substituted as expected.

divang and others added 10 commits October 24, 2025 16:08
- Add EXEC enum value to PrepareMethod for direct execution without preparation
- Implement Sybase DYNAMIC_PREPARE=false equivalent functionality
- Update reuseCachedHandle to disable caching for exec method
- Modify doPrepExec to bypass statement preparation when using exec method
- Add comprehensive tests for temp table persistence and parameter binding
- Update resource strings for proper documentation

This enables seamless migration from Sybase applications by providing
direct statement execution without preparation, ensuring temp tables
persist across executions as expected by legacy Sybase applications.

Connection usage:
String url = "jdbc:sqlserver://server:1433;databaseName=mydb;prepareMethod=exec";

DataSource usage:
SQLServerDataSource ds = new SQLServerDataSource();
ds.setPrepareMethod("exec");
- Implemented SqlServerPreparedStatementExpander utility class for expanding prepared statement placeholders with actual parameter values
- Added support for prepareMethod=exec to enable direct execution mode similar to Sybase's DYNAMIC_PREPARE=false
- Handles proper SQL syntax parsing to avoid replacing placeholders inside strings, comments, or delimited identifiers
- Implements smart NULL handling with operator rewrites (= ? -> IS NULL, <> ? -> IS NOT NULL, != ? -> IS NOT NULL, IS ? -> IS NULL, IS NOT ? -> IS NOT NULL)
- Formats various data types: strings (with single quote escaping), numbers, booleans (as 1/0), dates/times, byte arrays (as hex), CLOBs, BLOBs
- Added comprehensive JUnit test suite (23 test cases) covering all scenarios
- Added demo class for manual testing and verification
- Updated SQLServerConnection to use the new expander when useDirectValues=true in replaceParameterMarkers
- Fix operator detection to check for two-char operators (!=, <>) before single-char
- Fix spacing issues when replacing operators with IS NULL/IS NOT NULL
- Fix string literal parsing to properly handle escaped quotes ('')
- All 23 tests now pass successfully
…ev/divang/sybase-migration-dynamic-prepare
* Add comprehensive test coverage for EXEC prepare method
* commented testFourPartSyntaxCallEscapeSyntax due to linked server error
@divang
Copy link
Contributor Author

divang commented Nov 21, 2025

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@machavan machavan self-assigned this Nov 25, 2025
@machavan machavan added this to the 13.3.1 milestone Nov 25, 2025
- Moved expandSQLWithParameters() and helper methods from SqlServerPreparedStatementExpander to SQLServerConnection
- Converted from static utility class pattern to instance methods
- Deleted obsolete SqlServerPreparedStatementExpander class and associated test files
- Simplified replaceParameterMarkers() to call expandSQLWithParameters() directly
- Reduced code duplication by ~280 lines
…improve numeric formatting

- Check sendStringParametersAsUnicode config before adding N prefix to string literals
- Improve Float/Double formatting using BigDecimal to avoid precision loss
- Separate integer type handling from floating-point types for better precision control
…g formatting

- Updated Clob value formatting to respect sendStringParametersAsUnicode setting
- Updated fallback case (toString) to respect sendStringParametersAsUnicode setting
@machavan machavan changed the title Enabling Sybase Migration with DynamicPrepare Introduce new prepareMethod exec for PreparedStatement Nov 27, 2025
- Simplified replaceParameterMarkers when useDirectValues=true by directly
  iterating paramPositions array instead of complex SQL parsing
- Removed expandSQLWithParameters() method which is no longer needed
- Uses existing paramPositions array to replace ? markers with formatted values
…rely

after encountering a single statement error, instead of marking the failed
statement with EXECUTE_FAILED (-3) and continuing with remaining statements.
@codecov
Copy link

codecov bot commented Dec 2, 2025

Codecov Report

❌ Patch coverage is 67.14286% with 69 lines in your changes missing coverage. Please review.
✅ Project coverage is 56.59%. Comparing base (ac6130b) to head (b3c2905).

Files with missing lines Patch % Lines
.../microsoft/sqlserver/jdbc/SQLServerConnection.java 56.32% 25 Missing and 13 partials ⚠️
...oft/sqlserver/jdbc/SQLServerPreparedStatement.java 73.72% 19 Missing and 12 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2844      +/-   ##
============================================
+ Coverage     56.42%   56.59%   +0.16%     
- Complexity     4555     4627      +72     
============================================
  Files           151      151              
  Lines         34560    34764     +204     
  Branches       5768     5825      +57     
============================================
+ Hits          19501    19673     +172     
- Misses        12418    12456      +38     
+ Partials       2641     2635       -6     

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

@divang
Copy link
Contributor Author

divang commented Dec 5, 2025

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@microsoft microsoft deleted a comment from machavan Dec 15, 2025
…on logic

- Renamed PrepareMethod from 'exec' to 'scopeTempTablesToConnection' for clarity
- Added containsTemporaryTableOperations() method with optimized regex pattern
- Method detects temp tables (#temp, ##global, [#temp_'chars]) in SQL statements
- Only applies scopeTempTablesToConnection when temp tables are present
- Falls back to normal execution when no temp tables detected

Batch execution improvements:
- Fixed batch combining to separate CREATE TABLE prefix from parameterized INSERT
- Uses lastIndexOf(';', firstParamPos) to find proper SQL statement boundary
- Handles whitespace offset calculation for accurate parameter positions
- Fixed exception hierarchy: BatchUpdateException wrapped in SQLServerException

Regex pattern enhancements:
- Supports both unescaped (#temp) and bracketed ([#temp_'special-chars]) identifiers
- Detects CREATE TABLE, INSERT, UPDATE, DELETE, SELECT INTO operations
- Performance optimized with pre-compiled patterns

Test coverage:
- Added comprehensive test cases for temp table batch execution
- Tests constraint violations with proper update counts validation
- Tests exception cause chain unwrapping
- All 5 tests in SQLServerPreparedStatementTempTableTest passing
…epare method in PrepareMethodExecTest and PreparedStatementTest.
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.

4 participants