mirror of
https://github.com/apache/doris.git
synced 2026-11-04 16:03:23 +00:00
### 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`.