Files
Mingyu Chen (Rayner) a290247000 [fix](jdbc) Set the Oracle driver's session time zone only for Oracle catalogs (#69121)
### What problem does this PR solve?

Issue Number: None

Related PR: #68786

Problem Summary:

**In short.** Since #68786, every scan of a JDBC catalog that connects
to OceanBase in Oracle mode fails with `Failed to initialize Oracle
session time zone`, whatever columns it reads. The Oracle type handler,
which such a catalog shares with Oracle catalogs, sets the session time
zone through Oracle's JDBC driver, and an OceanBase catalog has
OceanBase's driver instead. This PR makes only Oracle catalogs do that.

**Background.** BE's JDBC scanner picks a type handler by the catalog's
table type (`JdbcTypeHandlerFactory`): `ORACLE` and `OCEANBASE_ORACLE`,
which FE reports for an OceanBase database whose
`ob_compatibility_mode()` is ORACLE, both get `OracleTypeHandler`.
#68786 made its `initializeStatement` set the session time zone of every
borrowed connection to UTC through
`oracle.jdbc.OracleConnection#setSessionTimeZone`, loaded reflectively
from the class loader of the driver's connection, so that Oracle's
driver reads TIMESTAMP WITH LOCAL TIME ZONE as an instant: `ALTER
SESSION` alone leaves the driver's own zone unset. The review bot raised
this for OceanBase on #68786 (thread 4237173029); the thread was still
open when it merged.

**The problem, and what it cost.** An Oracle-mode OceanBase catalog
connects through OceanBase's driver, and the class loader of a catalog's
driver only sees that driver.
`Class.forName("oracle.jdbc.OracleConnection", ...)` therefore throws
ClassNotFoundException, and `initializeStatement` turns it into
`SQLException: Failed to initialize Oracle session time zone` before the
query is prepared. Every SELECT on such a catalog failed, including ones
that read no timestamp column. Writes were not affected, since they do
not go through `initializeStatement`.

**How this PR fixes it.** `OracleTypeHandler` takes the table type, as
`MySQLTypeHandler` does for `MYSQL` and `OCEANBASE`, and sets the Oracle
session time zone only for `ORACLE`. An Oracle-mode OceanBase catalog
prepares its statements as it did before #68786, and reads TIMESTAMP
WITH LOCAL TIME ZONE as OceanBase's driver returns it. The no-argument
constructor keeps the Oracle behavior.

**Results.**

- **FE UT** (`be-java-extensions/jdbc-scanner`).
`OracleSessionTimeZoneTest.oceanBaseOracleModeScansWithoutTheOracleDriver`
prepares a statement through the factory's `OCEANBASE_ORACLE` handler on
a connection defined by the platform class loader, which cannot see
`oracle.jdbc` either; before this change it failed with `Failed to
initialize Oracle session time zone`, and setting the Oracle session
time zone for `OCEANBASE_ORACLE` too turns it red again.
`oracleCatalogSetsTheSessionTimeZone` checks that the factory's `ORACLE`
handler still sets it. All 57 tests of jdbc-scanner pass (18 skipped:
the two integration test classes need their databases).
- **End to end.** Not tested: OceanBase's Oracle mode is only in its
enterprise edition, and the regression environment runs OceanBase CE in
MySQL mode.

branch-4.1 and branch-4.2 carry the same session time zone setup in
`OracleJdbcExecutor` since #68873, and also give it to
`OCEANBASE_ORACLE`.
2026-10-19 14:36:04 +08:00
..
…