Visitar URL original
[PECOBLR-2086] MST transaction tests — parameterized for SEA/Thrift by vikrantpuppala · Pull Request #1366 · databricks/databricks-jdbc · GitHub
Skip to content

[PECOBLR-2086] MST transaction tests — parameterized for SEA/Thrift - #1366

Merged
vikrantpuppala merged 20 commits into
databricks:mainfrom
vikrantpuppala:add-mst-transaction-tests
Apr 22, 2026
Merged

vikrantpuppala merged 20 commits into
databricks:mainfrom
vikrantpuppala:add-mst-transaction-tests

Conversation

@vikrantpuppala

@vikrantpuppala vikrantpuppala commented Apr 2, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Adds comprehensive MST (Multi-Statement Transaction) E2E test suite for the JDBC driver
  • Tests are parameterized across SEA and Thrift backends — every test runs on both
  • Two transaction modes: JDBC API (setAutoCommit/commit/rollback) and Explicit SQL (BEGIN TRANSACTION/COMMIT/ROLLBACK) share a common abstract base class
  • Covers known server-side bugs: LC-13424, LC-13425, LC-13427, LC-13428
  • See docs/mst-test-design.md for full design, operation categorization, class hierarchy, and E2E results

Test architecture

  • AbstractMstTestBase — 22 shared correctness tests (mode-agnostic, no @Test — invoked via parameterized wrappers)
  • JdbcApiTransactionTests — inherits shared + 10 API-specific tests (autocommit, isolation, PreparedStatement)
  • ExplicitSqlTransactionTests — inherits shared + 7 SQL-specific tests (BEGIN TRANSACTION, SET AUTOCOMMIT)
  • MstMetadataTests — metadata RPCs with backend-aware assertions (SEA: assertThrows, Thrift: non-transactional freshness)
  • MstBlockedSqlTests — MSTCheckRule-blocked SQL introspection + setCatalog/setSchema (assertThrows on both backends)
  • MstExecuteVariantTests — executeUpdate/executeBatch (SEA: silently poisons txn or throws, Thrift: works correctly)

E2E results (174 test executions)

  • 169 pass, 4 skip, 0 errors
  • 4 skips are due to 2 known driver bugs:
    • SEA closes PreparedStatement after execute() — B.8 PreparedStatement reuse, B.9 getMetaData after execute
    • Thrift getFunctions driver logging bug (IllegalFormatConversionException) — D.7

Key E2E findings

  • Thrift metadata RPCs (getColumns, getTables, etc.) are non-transactional — they bypass MST isolation and see concurrent DDL changes
  • SEA executeUpdate/executeLargeUpdate silently poison the transaction (commit fails later); executeBatch throws directly
  • getFunctions via SEA is not blocked by MSTCheckRule (SHOW FUNCTIONS IN CATALOG with StatementType.METADATA bypasses the rule)
  • getPrimaryKeys fails on both backends — server routes it through GET_FUNCTIONS which is blocked in MST
  • SEA closes Statement/PreparedStatement after each execute() — tests use executeSql() helper with fresh Statement per call

Test plan

  • Run full suite on SEA backend
  • Run full suite on Thrift backend
  • Verify blocked SQL tests pass on both backends (24/24)
  • Verify execute variant behavior (SEA: poisons txn, Thrift: correct counts)
  • Verify metadata RPC behavior (SEA: throws, Thrift: non-transactional)
  • Verify freshness tests (Thrift sees concurrent DDL changes)

NO_CHANGELOG=true

This pull request was AI-assisted by Isaac.

Adds 37 new E2E integration tests to TransactionTests.java covering
gaps identified in MST + xDBC metadata audit (LC-13424, LC-13425,
LC-13427, LC-13428):

- executeUpdate/executeLargeUpdate/executeBatch in transactions
- DatabaseMetaData operations (getColumns, getTables, etc.) in active txn
- PreparedStatement metadata before/after execute in transaction
- MSTCheckRule-blocked SQL (SHOW/DESCRIBE/information_schema) in MST
- Allowed operations (setCatalog, setSchema, DESCRIBE TABLE) in MST
- Connection close with pending transaction (implicit rollback)
- DDL behavior in transactions (CREATE/DROP/ALTER TABLE)
- PreparedStatement parameterized DML in transactions
- Concurrent DDL + parameterized DML (stale schema)
- Edge cases: empty txn, read-only txn, holdability, timeout, retry

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
- Add ignoreTransactions=0 to JDBC URL to enable MST
- Fix testCloseConnectionWithPendingTransaction: accept both auto-commit
  and rollback behaviors on close
- Fix testGetFunctionsInsideActiveTransaction: catch known driver logging
  bug (IllegalFormatConversionException in getFunctions)

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
- setCatalog/setSchema/DESCRIBE TABLE are all blocked in MST via Thrift
  (SetCatalogCommand, SetNamespaceCommand, DescribeRelation) — tests now
  expect the exception
- getPrimaryKeys/getCrossReference may poison transaction in MST — wrapped
  in try-catch
- testParameterizedDMLAfterConcurrentAlterTable: catch driver logger bug
- testCommitWithoutActiveTransaction: remove message content assertion
- testTransactionContinuesAfterAllowedMetadataOp: use DML-only operations

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
- Add transactionTests.yml workflow to run TransactionTests and
  ExplicitTransactionStatementTests on push to main (same pattern as
  concurrencyExecutionTests.yml)
- Update both e2e test classes to read credentials from env vars
  (DATABRICKS_HOST, DATABRICKS_TOKEN, DATABRICKS_HTTP_PATH, etc.)
  with fallback to hardcoded defaults for local development
- Fake service replay mode not yet possible for transaction tests
  due to LC-13424 (SEA INLINE disposition bug with MST commands)

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Documents the test architecture for MST transaction tests:
- Operation categorization (broken vs stale vs works) per backend
- Parameterized test class hierarchy (SEA + Thrift)
- Shared correctness tests via abstract base class
- Specialized test classes for metadata, blocked SQL, execute variants
- Migration plan from current unstructured tests

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Adds visual diagrams for:
- Operation categorization (broken/stale/works)
- Driver routing (SEA vs Thrift code paths)
- Class hierarchy
- Test execution flow across backends and transaction modes
- Migration plan from current to new structure
- Test count breakdown

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Comment thread docs/mst-test-design.md Outdated
| # | Test | Description | Expected |
|---|---|---|---|
| A.1 | `testDefaultAutoCommitIsTrue` | New connection defaults to autoCommit=true | Pass |
| A.2 | `testCommitSingleInsert` | Disable autocommit → INSERT → commit → verify from separate conn | Pass |

@vikrantpuppala vikrantpuppala Apr 6, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

why does it say disable autocommit? it should depend on if it's running via api or explicit mode??

Comment thread docs/mst-test-design.md Outdated
| A.4 | `testRollbackSingleInsert` | Disable autocommit → INSERT → rollback → verify not persisted | Pass |
| A.5 | `testMultipleSequentialTransactions` | 3 sequential txns (commit, commit, rollback) → verify only first two persist | Pass |
| A.6 | `testAutoStartAfterCommit` | Commit txn1 → insert+rollback txn2 → only txn1 data persists | Pass |
| A.7 | `testAutoStartAfterRollback` | Rollback txn1 → insert+commit txn2 → only txn2 data persists | Pass |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this should sit in ApiTests?

Comment thread docs/mst-test-design.md Outdated
| A.15 | `testWriteConflictSingleTable` | Two concurrent txns on same table → first commits → second gets ConcurrentAppendException | Pass |
| A.16 | `testWriteSkewProvesSnapshotIsolation` | Two concurrent txns on different tables → both commit → proves Snapshot Isolation | Pass |
| A.17 | `testCommitWithoutActiveTxnThrows` | autocommit=true → commit() → expect exception | Pass |
| A.18 | `testRollbackWithoutActiveTxnBehavior` | autocommit=true → rollback() → document behavior (JDBC throws, explicit SQL is no-op) | Pass |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

are we going to test 17 and 18 with both api and explicit? and do we mean SET AUTOCOMMIT or BEGIN TRANSACTION when running explicit sql tests? also are there scenarios when we'd like to test both?

Comment thread docs/mst-test-design.md Outdated
| A.16 | `testWriteSkewProvesSnapshotIsolation` | Two concurrent txns on different tables → both commit → proves Snapshot Isolation | Pass |
| A.17 | `testCommitWithoutActiveTxnThrows` | autocommit=true → commit() → expect exception | Pass |
| A.18 | `testRollbackWithoutActiveTxnBehavior` | autocommit=true → rollback() → document behavior (JDBC throws, explicit SQL is no-op) | Pass |
| A.19 | `testSetAutoCommitDuringActiveTxnThrows` | In active txn → setAutoCommit(true) → expect exception | Pass |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

again, will we try SET AUTOCOMMIT in case of explicit txn? and if not, shouldn't this be in api tests? imo explicit sql tests shouldn't even know about the SET command and they should just interact with transactions using BEGIN command

Comment thread docs/mst-test-design.md Outdated
| A.18 | `testRollbackWithoutActiveTxnBehavior` | autocommit=true → rollback() → document behavior (JDBC throws, explicit SQL is no-op) | Pass |
| A.19 | `testSetAutoCommitDuringActiveTxnThrows` | In active txn → setAutoCommit(true) → expect exception | Pass |
| A.20 | `testUnsupportedIsolationLevel` | Set isolation to READ_UNCOMMITTED/READ_COMMITTED/SERIALIZABLE → expect exception | Pass |
| A.21 | `testSupportedIsolationLevel` | Set isolation to REPEATABLE_READ → verify | Pass |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

aren't 20 and 21 api tests?

Comment thread docs/mst-test-design.md Outdated
| A.29 | `testPreparedStatementUpdate` | Insert → parameterized UPDATE in txn → commit → verify | Pass |
| A.30 | `testPreparedStatementReuseAcrossTransactions` | Same PreparedStatement used in txn1 (commit) and txn2 (commit) → verify both rows | Pass |
| A.31 | `testPreparedStatementGetMetaDataAfterExecute` | Execute PreparedStatement SELECT → getMetaData() → verify column count | Pass |
| A.32 | `testGetParameterMetaData` | Create parameterized PreparedStatement → getParameterMetaData() → verify non-null | Pass |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

i feel like there are duplications in the tests like maybe we're testing the same thing again and again or in different ways, is there scope to reduce the number of tests here?

Comment thread docs/mst-test-design.md Outdated
| A.31 | `testPreparedStatementGetMetaDataAfterExecute` | Execute PreparedStatement SELECT → getMetaData() → verify column count | Pass |
| A.32 | `testGetParameterMetaData` | Create parameterized PreparedStatement → getParameterMetaData() → verify non-null | Pass |

### B. ExplicitSqlTransactionTests — special tests

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

we should similarly just have api tests as highlighted in previous comments

Comment thread docs/mst-test-design.md Outdated
6. **Add** staleness tests (C.9, C.10) — new, didn't exist before
7. **Parameterize** everything on SEA/Thrift

### Tests being removed (and why)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

why do we need to delete these? can we not add assertions instead?

- Move API-specific tests (setAutoCommit, isolation level) out of
  shared base into JdbcApiTransactionTests
- Clarify ExplicitSqlTransactionTests uses BEGIN TRANSACTION only;
  SET AUTOCOMMIT tests cover implicit SQL mode as special cases
- Remove duplicated tests (SET AUTOCOMMIT FALSE commit/rollback
  already covered by shared base via inherited tests)
- Move setCatalog/setSchema to MstBlockedSqlTests (API calls, not
  shared correctness)
- Make all shared test descriptions mode-agnostic (startTransaction
  instead of disable autocommit)
- Keep DDL/empty-commit/retry tests as needing E2E validation
  instead of deleting them
- Update class diagram, test counts, and execution flow diagrams

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Comment thread docs/mst-test-design.md Outdated
Comment on lines +304 to +305
| A.5 | `testAutoStartAfterCommit` | Commit txn1 → insert+rollback txn2 → only txn1 data persists | Pass |
| A.6 | `testAutoStartAfterRollback` | Rollback txn1 → insert+commit txn2 → only txn2 data persists | Pass |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

aren't these only applicable to setAutocommit and hence should be in api tests?

Auto-start after commit/rollback is specific to implicit transaction
mode (setAutoCommit=false). With BEGIN TRANSACTION there is no
auto-start — you need an explicit BEGIN for each transaction. Moved
testAutoStartAfterCommit and testAutoStartAfterRollback from shared
base (22 tests) to JdbcApiTransactionTests (now 10 API-specific tests).

Updated class diagram, execution flow, and counts accordingly.

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
@vikrantpuppala vikrantpuppala changed the title [PECOBLR-2086] Add comprehensive MST transaction metadata and edge case tests [PECOBLR-2086] MST transaction tests — parameterized for SEA/Thrift Apr 6, 2026
Replace TransactionTests.java and ExplicitTransactionStatementTests.java
with a structured, parameterized test hierarchy in the mst/ package:

- AbstractMstTestBase: 22 shared correctness tests (mode-agnostic),
  parameterized by backend (SEA/Thrift)
- JdbcApiTransactionTests: inherits shared + 10 API-specific tests
  (autocommit, isolation level, auto-start, PreparedStatement metadata)
- ExplicitSqlTransactionTests: inherits shared + 7 SQL-specific tests
  (BEGIN TRANSACTION, SET AUTOCOMMIT command)
- MstMetadataTests: 10 tests for metadata RPCs in MST with
  backend-aware assertions (SEA: xfail, Thrift: staleness)
- MstBlockedSqlTests: 12 tests for MSTCheckRule-blocked SQL and API
  calls, verifying both exception and transaction abort
- MstExecuteVariantTests: 4 tests for executeUpdate/executeBatch row
  counts (Thrift: correct, SEA: TBD after E2E)

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
- Remove @test from AbstractMstTestBase methods (JUnit was running
  them directly on gap test subclasses without initialization)
- Use separate Statement objects for DROP and CREATE in createTestTable
  (Databricks JDBC driver closes statement after execution)
- Default catalog/schema to main/default when env vars not set

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
SEA backend auto-closes statements after execution, so reusing a
Statement for multiple execute() calls fails. Refactored all tests
to use executeSql() helper which creates a fresh Statement per call.
Also use unique table names per test class (based on class name) to
allow parallel test execution without table collisions.

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
MstMetadataTests:
- Each test now starts its own fresh transaction (was sharing one)
- getFunctions: both backends return ResultSet (not blocked by
  MSTCheckRule when issued with StatementType.METADATA). Thrift
  path catches known driver logging bug (IllegalFormatConversionException)
- Staleness tests: flip assertions — Thrift RPCs ARE non-transactional
  and DO see concurrent DDL (proving they bypass transaction isolation)

MstExecuteVariantTests:
- SEA: wrap execute calls in assertThrows (LC-13424 confirmed —
  executeUpdate/executeBatch abort the transaction on SEA)
- Thrift: keep existing correctness assertions

JdbcApiTransactionTests:
- PreparedStatementUpdate: use execute() instead of executeUpdate()
  to avoid LC-13424 on SEA

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
E2E shows executeUpdate and executeLargeUpdate work on SEA (return
row count, don't abort transaction). Only executeBatch aborts on SEA.
Use same assertion for both backends — verify commit and data persist.
Row count may be stale on SEA (LC-13424).

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
E2E confirms executeUpdate and executeLargeUpdate on SEA succeed
(return a row count) but silently poison the transaction — the
subsequent commit() fails with TRANSACTION_ROLLBACK_REQUIRED. Assert
this behavior: SEA expects commit to throw, Thrift expects normal
commit and data persistence.

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
SEA backend closes PreparedStatement after execute(), preventing
reuse across transactions and getMetaData() after execution. Skip
these tests on SEA with Assumptions.assumeTrue(isThrift()).

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Major updates based on actual E2E results:
- Thrift metadata RPCs are non-transactional (see concurrent DDL),
  not stale — flipped terminology and assertions
- executeUpdate/executeLargeUpdate on SEA silently poison txn
  (commit fails), don't throw directly. executeBatch throws.
- getFunctions not blocked on SEA (StatementType.METADATA bypass)
- SEA closes PreparedStatement after execute — documented as
  implementation detail affecting test design
- Added E2E results table, known issues section
- Updated all diagrams to reflect verified behavior
- Removed TBD/open items that are now resolved

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
E2E confirms getPrimaryKeys Thrift RPC also fails inside MST —
the server routes TGetPrimaryKeysReq through GET_FUNCTIONS which
is blocked. Changed from Thrift-pass/SEA-throw to assertThrows
on both backends.

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
…unts

- getPrimaryKeys fails on both backends (server routes through
  GET_FUNCTIONS), not session poisoning — updated categorization
- Fixed E2E results: 169 pass, 5 skip, 0 errors
- Updated known issues: removed session poisoning, added
  getPrimaryKeys server routing issue
- Corrected skip count: 3 in MstMetadataTests (D.7 Thrift,
  D.9 SEA, D.10 SEA) + 2 in JdbcApiTransactionTests (B.8, B.9)

Co-authored-by: Isaac
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>

@gopalldb gopalldb 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.

How will these tests be triggered?

@vikrantpuppala
vikrantpuppala merged commit 77184e7 into databricks:main Apr 22, 2026
15 of 16 checks passed
gopalldb pushed a commit to gopalldb/databricks-jdbc that referenced this pull request Apr 27, 2026
…atabricks#1366)

## Summary
- Adds comprehensive MST (Multi-Statement Transaction) E2E test suite
for the JDBC driver
- Tests are **parameterized across SEA and Thrift backends** — every
test runs on both
- Two transaction modes: **JDBC API**
(`setAutoCommit`/`commit`/`rollback`) and **Explicit SQL** (`BEGIN
TRANSACTION`/`COMMIT`/`ROLLBACK`) share a common abstract base class
- Covers known server-side bugs: LC-13424, LC-13425, LC-13427, LC-13428
- See `docs/mst-test-design.md` for full design, operation
categorization, class hierarchy, and E2E results

## Test architecture
- `AbstractMstTestBase` — 22 shared correctness tests (mode-agnostic, no
`@Test` — invoked via parameterized wrappers)
- `JdbcApiTransactionTests` — inherits shared + 10 API-specific tests
(autocommit, isolation, PreparedStatement)
- `ExplicitSqlTransactionTests` — inherits shared + 7 SQL-specific tests
(BEGIN TRANSACTION, SET AUTOCOMMIT)
- `MstMetadataTests` — metadata RPCs with backend-aware assertions (SEA:
assertThrows, Thrift: non-transactional freshness)
- `MstBlockedSqlTests` — MSTCheckRule-blocked SQL introspection +
setCatalog/setSchema (assertThrows on both backends)
- `MstExecuteVariantTests` — executeUpdate/executeBatch (SEA: silently
poisons txn or throws, Thrift: works correctly)

## E2E results (174 test executions)
- **169 pass, 4 skip, 0 errors**
- 4 skips are due to 2 known driver bugs:
- SEA closes PreparedStatement after `execute()` — B.8 PreparedStatement
reuse, B.9 getMetaData after execute
- Thrift `getFunctions` driver logging bug
(`IllegalFormatConversionException`) — D.7

## Key E2E findings
- Thrift metadata RPCs (getColumns, getTables, etc.) are
**non-transactional** — they bypass MST isolation and see concurrent DDL
changes
- SEA `executeUpdate`/`executeLargeUpdate` **silently poison** the
transaction (commit fails later); `executeBatch` throws directly
- `getFunctions` via SEA is **not blocked** by MSTCheckRule (`SHOW
FUNCTIONS IN CATALOG` with `StatementType.METADATA` bypasses the rule)
- `getPrimaryKeys` fails on **both** backends — server routes it through
GET_FUNCTIONS which is blocked in MST
- SEA closes Statement/PreparedStatement after each `execute()` — tests
use `executeSql()` helper with fresh Statement per call

## Test plan
- [x] Run full suite on SEA backend
- [x] Run full suite on Thrift backend
- [x] Verify blocked SQL tests pass on both backends (24/24)
- [x] Verify execute variant behavior (SEA: poisons txn, Thrift: correct
counts)
- [x] Verify metadata RPC behavior (SEA: throws, Thrift:
non-transactional)
- [x] Verify freshness tests (Thrift sees concurrent DDL changes)

NO_CHANGELOG=true

This pull request was AI-assisted by Isaac.

---------

Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
@cathleeny cathleeny mentioned this pull request Oct 6, 2026
1 of 3 tasks
cathleeny added a commit that referenced this pull request Oct 7, 2026
## Description

Syncs `jdk-8` with `main` at `a64ae0e0` (**3.4.3**) and applies the JDK
8 changes from `.claude/commands/sync-jdk8-branch.md`. I followed the
updated version of that skill from `main` (#1298), which this merge also
brings into `jdk-8`. Replaces #1717.

- **Scope:** 173 commits from `main` since the last sync point,
`3ef86030` (#1270, synced via #1275). That covers releases 3.3.1, 3.3.2,
3.3.3, 3.4.2 and 3.4.3.
- **Merge base:** #1275 was squash-merged, so git's merge base for
`jdk-8`/`main` is still #1150 (`23a0bbdc`). A plain `git merge
origin/main` would re-conflict changes that were already synced. I
merged with `3ef86030` as the base (using a temporary graft), so only
changes since the last sync were merged. This is a real merge commit:
its parents are the `jdk-8` tip and the `main` tip.

### JDK 8 changes

**Root `pom.xml`**
- Source/target stay at `1.8`. The JDK 8 pins stay: Arrow `13.0.0`,
Mockito `4.11.0`, nimbus-jose-jwt `9.47`.
- Spotless stays removed entirely. Main's spotless plugin block was not
merged.
- OWASP `dependency-check-maven` is removed (plugin, `pluginManagement`
entry and version property). Version 12.x needs Java 11, so it breaks
`mvn install` on JDK 8. On `main`, OSV replaced OWASP as the security
gate (#1460).
- Kept from `main`: the dependency bumps, the CycloneDX aggregate-SBOM
plugin (works on JDK 8), and the `dependencyManagement` CVE overrides
for commons-lang3 and gson.

**`jdbc-core/pom.xml`**
- No WireMock dependency and no `--add-opens`.
- The `jdk17-NioNotOpen` and `jdk21-NioNotOpen` profiles, the
Arrow-patch JaCoCo exclusions, and the
`!Jvm17PlusAndArrowToNioReflectionDisabled` group filter are removed.
- Surefire excludes the fakeservice and e2e tests.

**Workflows**
- `coverageReport.yml`: JDK 8, 80% threshold, and `mvn -pl jdbc-core
clean test -Dspotless.skip=true jacoco:report`.
- All other workflows match `main`. That fixes a duplicated "Compile"
step the merge produced in `prCheckJDK8.yml`.

**Java 9+ APIs in code added on `main` since the last sync**
- `List.of`, `Set.of`, `Map.of` and `List.copyOf` became Guava
`ImmutableList`/`ImmutableSet`/`ImmutableMap` in main code, and
`Arrays.asList` or `Collections.empty*` in tests.
- `String.isBlank()`/`strip()` became `trim().isEmpty()`/`trim()`.
- `Objects.requireNonNullElse` became a null-check ternary.
- `Optional.isEmpty()` became `!isPresent()`.
- `Files.writeString` became `Files.write`.
- An anonymous-class diamond became an explicit type.
- JDBC 4.3: removed `supportsSharding()` again and dropped the
`beginRequest`/`endRequest` test asserts.
- Conflicts were resolved keeping the existing `jdk-8` rewrites and
applying main's logic changes on top.

**Removed**
- The fakeservice and e2e tests, plus `IntegrationTestUtil` and
`DatabricksDriverExamples` (which uses it).
- All WireMock resources. That includes `sqlexecapi`, `thriftserverapi`
and `cloudfetchapi`, plus leftover `sqlgatewayapi`,
`cloudfetchsqlgatewayapi`, `cloudfetchthriftserverapi`,
`jwttokenendpoint`, `__files` and the `*fakeservicetest.properties`
files. Only the removed fakeservice tests used them.
- The Arrow patch sources (#1243), their tests, and
`src/test/resources/arrow`.

### Cleanup beyond the skill

I removed 23 Java sources that exist only on `jdk-8`: they were never on
`main`, or were deleted from it long ago. They came back in the 2025-09
"post merge" commit `de3efe43`. Nothing references them:
- `api/IDatabricksConnectionContext` and `api/IDatabricksSession`, stale
duplicates of the `api.internal` interfaces
- `ChunkDownloadCallback`
- `VolumeOperationProcessorDirect`
- `OAuthEndpointResolver`
- `ErrorCodes`, `ErrorTypes`
- `DeviceInfoLogUtil`
- 15 old Thrift-generated classes (`TDBSql*`, `TExpressionInfo`,
`TSQLVariable`, etc.)

Non-code leftovers (`release-notes/v1.0.x`, `.vscode/settings.json`,
`runBenchmarks.yml`) are unchanged.

## Testing

All runs were local on OpenJDK 1.8.0:
- `mvn clean install -DskipTests -Dspotless.skip=true` (the
`prCheckJDK8` "Compile" step): BUILD SUCCESS for all 6 modules.
- `mvn -pl jdbc-core test -Dspotless.skip=true` (the `prCheckJDK8`
unit-test step): 3,569 tests, 0 failures, 0 errors, 0 skipped.
- The built core, thin and uber jars are all Java 8 bytecode (class-file
major version 52; `javap` on `com.databricks.client.jdbc.Driver` reports
52).
- Dependency audit: none of the 85 jars on jdbc-core's test classpath
contains classes newer than Java 8 (multi-release `META-INF/versions`
entries excluded).
- `TestThinPackaging`/`TestUberPackaging`: the offline packaging checks
pass. `executeLargeQuery` needs live workspace credentials, so it wasn't
run.

## Telemetry Errors
- [x] Not applicable — this PR does not add or change a
telemetry-visible error. It only syncs changes already reviewed on
`main`.
- [ ] Applicable — the error uses `DatabricksDriverErrorCode` where
appropriate, and any
      new code is uniquely numbered and tested.
- [ ] Applicable — its driver/server/user classification is linked, or
maintainer help is
      requested because the author cannot access the classification.

## Additional Notes to the Reviewer

- The reviewable part is the JDK 8 delta against `main` (`git diff
origin/main...` on this branch): the poms, `coverageReport.yml`, and the
Java 8 rewrites listed above. Everything else is `main`'s code as
already reviewed.
- Spotless doesn't run on `jdk-8`. I formatted the lines I touched with
google-java-format 1.18.1, the version `main` uses.

<details><summary>Synced commits (173)</summary>

- Honor Auth_Scope for OAuth M2M client credentials (#1707)
- chore(security): remediate OSV findings (#1716)
- Fix SEA UserAgentEntry attribution in Query History (#1709)
- Fix M2M private-key integration test session stub (#1703)
- Bump org.apache.httpcomponents.client5:httpclient5 from 5.6.3 to 5.6.4
(#1656)
- Run Jira automation on protected runner (#1696)
- Automate Jira tickets for new GitHub issues (#1694)
- chore(security): remediate OSV findings (#1690)
- Bump JDBC driver version to 3.4.3 (#1689)
- Add session version exchange to SQL Exec API client (#1678)
- Auto-recover Reyden Thrift rejection to SEA (KP001) (#1683)
- fix(metadata): order getTypeInfo rows by DATA_TYPE (#1680)
- Update Apache Thrift to 0.24.0 (#1682)
- Fix logging when an OFF connection initializes first (#1670)
- Enable native SEA metadata defaults behind server flag (#1672)
- Fix NPE on materialising nested arrays or arrays of maps with `NULL`
elements. (#1659)
- Add Thrift-native metadata support (#1641)
- Fix blocking security scan findings on main (#1663)
- Fix NPE for incomplete JDBC URLs (#1646)
- [2/7] Add native batching configuration and parameter model (#1621)
- Fix duplicate JDBC connection parameters (#1652)
- Add telemetry error classification guardrails (#1629)
- [1/7] Isolate legacy prepared statement batch execution (#1620)
- ci: wire merge_group triggers into required-check workflows (#1582)
- feat(learning): add daily engineer-bot retrospective flow + bump
engine to 654a31d0 (#1635)
- Add Thrift V10 batch parameter wire model (#1602)
- Update 3.4.1 metadata release notes (#1578)
- ci: warm test deps for Engineer Bot's offline agent + bump timeout
(#1588)
- Improve SEA connection-failure error messages (#1587)
- Fix invalid AuthMech crashing with Recursive update /
StackOverflowError (#1586)
- Throw SQLException for out-of-range column in Arrow getObject (#1557)
- Use SHOW COLUMNS IN ALL CATALOGS for getColumns with null catalog
(same-repo, integration-test verification) (#1580)
- Fix PreparedStatement.getMetaData() returning null for CTE (WITH ...)
queries [PECOBLR-3778] (#1581)
- feat(bots): onboard reviewer + engineer bots to databricks-bot-engine
(#1583)
- ci: dispatch coverage-fanout on merged source PRs (#1575)
- Fix NPE reading STRING COLLATE columns via Arrow (#1548)
- Throw SQLException for wrong complex-type getter calls (#1561)
- [test] Make nested timestamp assertions timezone-safe (#1565)
- [connection] Guarantee resource cleanup during close (#1564)
- Harden OSV security-scan gate (fail-closed) + drop SMTP email (#1563)
- Fix IdleConnectionEvictor thread leak when connection.close() fails
due to expired token (#1559)
- Bump to version 3.4.2 (#1551)
- Align Thrift statement-error vendor code with SEA
(EXECUTE_STATEMENT_FAILED) (#1549)
- Fix MAP with complex value type rendering as empty via Arrow (#1505)
(#1546)
- Stream CloudFetch chunk decompression to bound memory and prevent OOM
on large results (#1509)
- Add bounded SEA API support for CloudFetch (UseBoundedSeaApi) (#1468)
- Preserve TIMESTAMP_NTZ type name in ResultSetMetaData (#1495) (#1519)
- Bump anthropics/claude-code-action from 1.0.79 to 1.0.166 (#1538)
- Bump actions/setup-java from 4.8.0 to 5.4.0 (#1542)
- Bump peter-evans/create-pull-request from 7.0.11 to 8.1.1 (#1541)
- Bump actions/cache/save from 4.3.0 to 6.1.0 (#1540)
- Bump dawidd6/action-send-mail from 3.12.0 to 18 (#1539)
- Fix JulLogger CPU burn from unconditional stack-trace walk (#1511)
(#1515)
- Fix telemetry misattribution across connections on the same thread
(#1531)
- Accept OAuth M2M client id/secret via JDBC user/password (#1132)
(#1533)
- Bump actions/checkout from 4.3.1 to 7.0.0 (#1484)
- Bump dawidd6/action-send-mail from 3.11.0 to 3.12.0 (#1486)
- Bump actions/github-script from 7.0.1 to 9.0.0 (#1488)
- Bump softprops/action-gh-release from 1 to 3 (#1487)
- Bump actions/stale from 8.0.0 to 10.3.0 (#1479)
- Add release notes for v3.4.1 (#1522)
- Harden OAuth U2M token cache encryption and file permissions (#1520)
- Make Connection.setReadOnly a no-op instead of throwing (#1523)
- Bump shaded jackson 2.18.7 to 2.18.8 to fix CVE-2026-54512 and
CVE-2026-54513 in uber jar (#1507)
- Use offline cache for Security Scan on fork PRs (#1514)
- Fix Maven cache warmer to cache surefire-junit-platform provider
(#1513)
- Redact credentials in DatabaseMetaData.getURL() and parse errors
(#1502)
- Redact Azure and GCS presigned URL credentials in logs (#1501)
- Redact access token before logging in setClientInfoProperty (#1498)
- Bump Databricks SDK for Java from 0.106.0 to 0.118.0 (#1500)
- Fix getColumns() flooding DriverManager log writer with stack traces
(#1494)
- Fix timezone-shifted TIMESTAMP in nested complex types (ES-1978662)
(#1492)
- Fix closeOnCompletion() infinite recursion on ResultSet/Statement
close (ES-1978361) (#1493)
- Harden binary parameter interpolation against SQL injection (#1497)
- Fix supportsBatchUpdates() to honor EnableBatchedInserts (#1496)
- Surface truncated flag from SEA result manifest (#1503)
- Use async wait timeout for SEA when direct results disabled (fix
hybrid-path truncation) (#1476)
- Fix metadata identifiers containing backticks (#1474)
- Fix chunk download failures mis-bucketed as CONNECTION_ERROR in
telemetry (#1469)
- Fix double backtick wrapping in setCatalog and setSchema (#1454)
- v3.4.1 Bump (#1467)
- Bump databricks-sdk-java from 0.69.0 to 0.106.0 (#1465)
- Add debug logging for connector-service feature flags request and
response (#1462)
- [PECOBLR-2321] Result Set Heartbeat / Keep-Alive for Ongoing Query
Executions (#1415)
- Unify weekly + per-PR security scanning into a single workflow (#1460)
- Fix PreparedStatement.getMetaData() crash for SQL type aliases (#1289)
- Bump shaded bouncycastle and libthrift to clear remaining CVE findings
(#1461)
- Fix telemetry HTTP client socket leak preventing CRaC checkpoint
(#1333)
- Deprecate EnableArrow — Arrow always enabled except on AIX/IBM Power
(#1450)
- Fix DML misclassification for statements containing
UNION/INTERSECT/EXCEPT (#1420)
- Fix client-side maxRows enforcement in ResultSet.next() (#1448)
- Bump shaded jackson, httpcore5-h2, netty, commons-configuration2, lz4
to address CVEs (#1456)
- Proactive server-side statement close when results consumed (#1444)
- Update NEXT_CHANGELOG with detailed breaking changes for 3.4.1 (#1449)
- Fix getTables(types=[]) returning rows in Thrift mode (#1451)
- Close server-side operation on Statement re-execution (#1422)
- Fix SQLInterpolator treating ? in comments and literals as
placeholders + shorten next_changelog (#1424)
- Enable native geospatial type support by default (#1446)
- Add MetadataOperationTimeout support for SHOW commands metadata path
(#1417)
- [ES-1884446] Classify transient/mis-categorized server errors with
retryable SQL states (#1430)
- Distinguish Arrow schema parsing failures from generic ResultSet
errors (#1443)
- Add server-side SAFE flag for UseQueryForMetadata rollout on DBSQL
(#1437)
- Decouple geospatial support from complex datatype flag (#1438)
- Update release-notes.txt for 3.3.3 and mark 3.3.2 as DEPRECATED
(#1441)
- Cut new release 3.3.3 (#1434)
- Fix unresolvable 3.3.2 Maven Central POM for uber jar (#1432)
- Fix main CI: JFrog mirror bypass and Windows pwsh parse error (#1428)
- Cut new release 3.3.2 (#1419)
- Enable release freeze for 3.3.2 (#1427)
- Fix cancel error handling: vendor code, telemetry level, SEA async
path (#1425)
- Improve error messages for transient HTTP failures during Thrift
polling (#1426)
- Fix SEA result expiry error handling — preserve server error message
(#1302)
- Fix ambiguous errors when statements are cancelled or connection
closed (#1291)
- Fix race condition between chunk release and download error handling
(#1407)
- Revert UseQueryForMetadata default to 0, make SHOW commands opt-in
(#1421)
- Force Thrift mode when metadata params require native RPCs (#1416)
- [PECOBLR-2086] MST transaction tests — parameterized for SEA/Thrift
(#1366)
- Change UseQueryForMetadata default to 1 (SHOW commands) (#1413)
- Fix statement close behavior for direct results in SEA (#1400)
- Add SPOG support for ?o= routing in httpPath (#1316)
- Fix batched insert regex to support backtick-quoted identifiers with
special characters (#1403)
- Fix getCrossReference case-insensitive parent matching (#1411)
- [PECOBLR-2318] Unify EnableDirectResults and
EnableSQLExecDirectResults params (#1409)
- Fix IntervalConverter crash on CloudFetch interval columns (#1397)
- [PECOBLR-1928] Add AI coding agent detection to User-Agent header
(#1230)
- [PECOBLR-2409] Add CallableStatement support with IN parameters
(#1371)
- Add VARIANT type to ColumnInfoTypeName for correct SEA metadata
(#1388)
- Fix GEOMETRY/GEOGRAPHY DATA_TYPE mapping in Thrift getColumns()
(#1387)
- SEA metadata: throw for invalid null/empty params (Thrift parity)
(#1390)
- Add vulnerability scan gate to release workflows (#1396)
- Fix cache warmer: add Windows runner, timestamp-based cache keys
(#1395)
- Fix cache warmer: add clean to resolve maven-clean-plugin and
exec-maven-plugin (#1394)
- Fix: normalize _remote.repositories repo ID for offline mode (#1393)
- Fix: non-fork cache path must be restore-only (#1392)
- Remove _remote.repositories from cache + use offline mode for forked
PRs (#1391)
- Fix fork Maven config: set updatePolicy=never to prevent 401 on cached
artifacts (#1389)
- Fix cache warmer: run real test to resolve surefire provider (#1385)
- Revert Windows git install, restore original Enable long paths step
(#1383)
- Fix cache warmer: use install only, drop dependency:resolve (#1382)
- Fix cache warmer: use install for inter-module SNAPSHOT resolution
(#1381)
- Fix cache warmer: Linux-only, OS-agnostic cache key (#1380)
- Bump version to 3.3.2-SNAPSHOT (#1292)
- Bump netty.version from 4.2.6.Final to 4.2.12.Final (#1347)
- Use Databricks protected runner group for CI actions (#1369)
- Resolve null catalog/schema in SEA key-based metadata operations
(#1370)
- Fix getSchemas returning JDBC-escaped catalog name in SEA mode (#1365)
- Fix IllegalFormatConversionException in JulLogger error logging with
Throwable (#1372)
- Simplify SEA disposition: use connection parameters instead of
statement type (#1322)
- Fix CI failures: replace gh API calls blocked by IP allow list (#1363)
- Fix SEA metadata JDBC spec compliance: catalog handling, empty types,
non-existent objects (#1308)
- Fix SEA volume operations failing with Statement is closed (#1323)
- Address open supply chain security action items (#1359)
- Disable publishing workflows per third-party package freeze (#1354)
- Migrate all CI workflows from Databricks runners to GitHub-hosted
runners (#1350)
- Pin all GitHub Actions to commit SHAs (#1324)
- Harden CI/CD supply chain security across all workflows (#1328)
- Migrate dco-check and vulnerabilityCatcher to Databricks runners
(#1327)
- Prevent script injection in coverageReport workflow (#1295)
- Improve instructions for jdk8 branch update (#1298)
- Use version property for jts-core dependency (#1297)
- Add OWASP suppression for CVE-2026-25087 and re-enable dependency
check in release (#1296)
- Add Claude GitHub Actions workflows (#1288)
- Move dependencyManagement to parent pom to fix CVE-2025-48924 in uber
jar (#1294)
- Fix backtick quoting for column names in batched INSERT reconstruction
(#1285)
- Fix primitive type parsing in complex types for Arrow-serialized
formats (#1250)
- Skip OWASP dependency check in release build step (#1286)
- Cut new release 3.3.1 (#1281)
- [PECOBLR-1746] Implementing support for listing procedures (#1238)
- Fix IdleConnectionEvictor thread leak in long-running services (#1271)
- [ES-1717770] Fix TIMEDOUT_STATE not recognized as error on interactive
clusters (#1244)
- [ES-1765150] Coalesce concurrent expired-link refreshes into single
batch RPC (#1277)
- [ES-1774740] Fix Thrift polling infinite loop on invalid operation
handle (#1273)
- Add /sync-jdk8-branch slash command + update the jdk8 action workflow
(#1274)

</details>

NO_CHANGELOG=true

This pull request and its description were written by Isaac.


[PECOBLR-3778]:
https://databricks.atlassian.net/browse/PECOBLR-3778?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

---------

Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: samikshya-chand_data <samikshya.chand@databricks.com>
Signed-off-by: Sreekanth Vadigi <sreekanth.vadigi@databricks.com>
Signed-off-by: Nikhil Suri <nikhil.suri@databricks.com>
Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
Signed-off-by: rileythomp <rileythompson99@gmail.com>
Signed-off-by: Samikshya Chand <samikshya.chand@databricks.com>
Signed-off-by: Madhavendra Rathore <madhavendra.rathore@databricks.com>
Signed-off-by: Oleksandr Shevchenko <oleksandr.shevchenko@datarobot.com>
Signed-off-by: Shivam Raj <shivam.raj@databricks.com>
Signed-off-by: Madhavendra Rathore
Signed-off-by: Dan Homola <dan.homola@hotmail.cz>
Signed-off-by: Matthieu Sprunck <msprunck@cisco.com>
Signed-off-by: Matthieu Sprunck <matthieu@sprunck.com>
Signed-off-by: Eric Wang <e.wang@databricks.com>
Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
Signed-off-by: Prathamesh Baviskar <prathamesh.baviskar@databricks.com>
Signed-off-by: Cathleen Yan <cathleen.yan@databricks.com>
Signed-off-by: Vu Anh Phung <vu.phung@databricks.com>
Signed-off-by: Michael Simons <michael@simons.ac>
Signed-off-by: Cathleen Yan <58714163+cathleeny@users.noreply.github.com>
Signed-off-by: Rahul Singhal <rahul.singhal@databricks.com>
Signed-off-by: Aakash Saravanan <aakash.saravanan@databricks.com>
Signed-off-by: peco-engineer-bot[bot] <287056288+peco-engineer-bot[bot]@users.noreply.github.com>
Co-authored-by: Gopal Lal <135012033+gopalldb@users.noreply.github.com>
Co-authored-by: Samikshya Chand <148681192+samikshya-db@users.noreply.github.com>
Co-authored-by: Madhavendra Rathore <madhavendra.rathore@databricks.com>
Co-authored-by: Vikrant Puppala <vikrant.puppala@databricks.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: tejassp-db <241722411+tejassp-db@users.noreply.github.com>
Co-authored-by: jayant <167047871+jayantsing-db@users.noreply.github.com>
Co-authored-by: Sreekanth <sreekanth.vadigi@databricks.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Jothi Prakash <jothi.prakash@databricks.com>
Co-authored-by: Shivam Raj <171748731+shivam2680@users.noreply.github.com>
Co-authored-by: nikhilsuri-db <nikhil.suri@databricks.com>
Co-authored-by: Riley Thompson <rileythompson99@gmail.com>
Co-authored-by: Oleksandr Shevchenko <shevchenko.olexandr96@gmail.com>
Co-authored-by: Oleksandr Shevchenko <oleksandr.shevchenko@datarobot.com>
Co-authored-by: Madhav Sainanee <madhav.sainanee@databricks.com>
Co-authored-by: Dan Homola <dan.homola@hotmail.cz>
Co-authored-by: Thomas Powell <tom-s-powell@users.noreply.github.com>
Co-authored-by: Matthieu Sprunck <matthieu@sprunck.com>
Co-authored-by: eric-wang-1990 <115501094+eric-wang-1990@users.noreply.github.com>
Co-authored-by: Prathamesh Baviskar <prathamesh.baviskar@databricks.com>
Co-authored-by: vuanhphung <vuanhphung1997@gmail.com>
Co-authored-by: Michael Simons <michael@simons.ac>
Co-authored-by: vuanhphung <vu.phung@databricks.com>
Co-authored-by: Rahul Singhal <126218237+rahuls-db@users.noreply.github.com>
Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: aakash-saravanan-db <aakash.saravanan@databricks.com>
Co-authored-by: peco-engineer-bot[bot] <287056288+peco-engineer-bot[bot]@users.noreply.github.com>
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.

2 participants