Skip to content

Introduce prepareMethod=scopeTempTablesToConnection for connection-scoped temporary tables#2844

Merged
divang merged 54 commits intomainfrom
dev/divang/sybase-migration-dynamic-prepare
Jan 21, 2026
Merged

Introduce prepareMethod=scopeTempTablesToConnection for connection-scoped temporary tables#2844
divang merged 54 commits intomainfrom
dev/divang/sybase-migration-dynamic-prepare

Conversation

@divang
Copy link
Copy Markdown
Contributor

@divang divang commented Nov 18, 2025

Objective:
Enable prepared statements to work correctly with temporary tables by providing an alternative execution method that uses literal parameter substitution instead of server-side prepared statement handles. This addresses scenarios where temporary tables created within prepared statements are not visible in subsequent executions due to session scoping issues with sp_prepexec.

Solution:
New value: Added scopeTempTablesToConnection as a new option to the existing connection property (alongside prepexec and prepare)
Temporary table detection: Implemented logic to automatically detect temporary table operations (#temp, not global temp table) in SQL statements
Literal parameter substitution: When [prepareMethod=scopeTempTablesToConnection] is set and temp tables are detected, the driver replaces parameter markers (?) with properly formatted literal values directly in the SQL string
Parameter formatting: Implemented comprehensive formatLiteralValue() method in SQLServerConnection to handle:

  • Numeric types (int, long, float, double, BigDecimal, etc.)
  • Date/Time types (Date, Time, Timestamp, LocalDate, LocalDateTime, etc.)
  • String types with Unicode support via sendStringParametersAsUnicode
  • Binary data and other data types

Smart fallback: Automatically falls back to standard prepared statement execution when no temp tables are detected
Batch execution fixes: Improved batch update count handling for comma-separated SQL statements and proper error handling (EXECUTE_FAILED=-3) for individual statement failures

Testing:
PrepareMethodExecTest: Comprehensive tests covering various data types and scenarios
SQLServerPreparedStatementTempTableTest: Tests for temporary table scoping and detection logic
BatchExecutionTest: Enhanced batch execution tests with temp table scenarios
FormatLiteralValueNumericTest: Tests for numeric value formatting
FormatLiteralValueDateTimeTest: Tests for date/time value formatting
CallableStatementTest enhancements: Added tests for callable statement parameter handling

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
* Add comprehensive test coverage for EXEC prepare method
* commented testFourPartSyntaxCallEscapeSyntax due to linked server error
@divang
Copy link
Copy Markdown
Contributor Author

divang commented Nov 21, 2025

/azp run

@azure-pipelines
Copy link
Copy Markdown

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
Comment thread src/test/SybaseConnection.java Outdated
Comment thread src/test/PreparedStatementExecMethodE2ETest.java Outdated
- 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
Copy Markdown

codecov Bot commented Dec 2, 2025

Codecov Report

❌ Patch coverage is 47.97980% with 103 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.05%. Comparing base (56812d5) to head (af1147c).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...oft/sqlserver/jdbc/SQLServerPreparedStatement.java 46.63% 87 Missing and 16 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2844      +/-   ##
============================================
+ Coverage     58.98%   59.05%   +0.06%     
- Complexity     4739     4807      +68     
============================================
  Files           151      151              
  Lines         34575    34748     +173     
  Branches       5776     5827      +51     
============================================
+ Hits          20395    20519     +124     
- Misses        11404    11488      +84     
+ Partials       2776     2741      -35     

☔ 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
Copy Markdown
Contributor Author

divang commented Dec 5, 2025

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

- Updated exception message checking to traverse the entire exception cause chain
- Changed from simple message check to comprehensive search through all causes
- Now checks for 'CHECK constraint' or 'constraint' in any exception in the chain
- Fixes test failure in testConstraintViolationBasicPrepareStatementScopeTemp
- Applied fix to both Use Case 1 and Use Case 3 for consistency
- Added hasConstraintViolationMessage() helper to check multiple keywords
- Added getExceptionMessageChain() helper for better error diagnostics
- Now checks for: 'check constraint', 'constraint', 'violated', 'check', and SQL error code 547
- Uses case-insensitive matching for more robust detection
- Provides full exception chain in assertion message for debugging
- Applied to both Use Case 1 and Use Case 3 consistently
Copy link
Copy Markdown
Contributor

@muskan124947 muskan124947 left a comment

Choose a reason for hiding this comment

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

Posted some cleanup related comments

Comment thread src/test/java/com/microsoft/sqlserver/jdbc/BatchCombinedExecutionTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/BatchCombinedExecutionTest.java Outdated
…odScopeTempTablesToConnectionTest, PreparedStatementTest
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java Outdated
…QLServerPreparedStatement and fix the test cases acordingly
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.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
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/BatchCombinedExecutionTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/BatchCombinedExecutionTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/BatchCombinedExecutionTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/BatchCombinedExecutionTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/FormatLiteralValueDateTimeTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java Outdated
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java Outdated
@divang divang force-pushed the dev/divang/sybase-migration-dynamic-prepare branch from 028219d to 599457b Compare January 19, 2026 06:18
Comment thread src/test/java/com/microsoft/sqlserver/jdbc/BatchCombinedExecutionTest.java Outdated
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java Outdated
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerParameterMetaData.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
@divang divang merged commit ee978e8 into main Jan 21, 2026
16 of 19 checks passed
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