Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- Fixed `getColumns()` flooding the `DriverManager` log writer with caught-and-recovered `Invalid column index` stack traces.
- Fixed timezone-shifted TIMESTAMP values when retrieving nested complex types (STRUCT/ARRAY/MAP) with `EnableComplexDatatypeSupport=1`.
- Fixed `DatabricksDatabaseMetaData.supportsBatchUpdates()` always returning `false`, which caused batch-aware JDBC clients (e.g. Apache Hop) to skip `executeBatch()` and fall back to one INSERT per row. It now returns `true` when `EnableBatchedInserts=1`, so those clients use the optimized multi-row INSERT path.
- Fixed `Connection.setReadOnly(true)` throwing `DatabricksSQLFeatureNotSupportedException`, which broke clients (e.g. Trino/Starburst GenericJDBC, HikariCP, DBCP) that call it during connection initialization. Per the JDBC spec, `setReadOnly` is a hint the driver may ignore; it is now a no-op and `isReadOnly()` continues to return `false`.

---
*Note: When making changes, please add your change under the appropriate section
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,12 +466,14 @@ public DatabaseMetaData getMetaData() throws SQLException {

@Override
public void setReadOnly(boolean readOnly) throws SQLException {
LOGGER.debug("public void setReadOnly(boolean readOnly)");
LOGGER.debug("public void setReadOnly(boolean readOnly = {})", readOnly);
throwExceptionIfConnectionIsClosed();
if (readOnly) {
throw new DatabricksSQLFeatureNotSupportedException(
"Databricks OSS JDBC does not support readOnly mode.");
}
// Per the JDBC spec, setReadOnly is a hint used to enable database optimizations. The
// Databricks
// backend does not enforce a connection-level read-only mode, so this is treated as a no-op
// rather than throwing. isReadOnly() continues to report false since the hint is not enforced.
// Throwing here breaks common clients (e.g. HikariCP, DBCP, Trino/Starburst) that call
// setReadOnly(true) during connection initialization.
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,9 +625,11 @@ void testTranslationIsolation() throws SQLException {
void testReadOnlyAndAbort() throws SQLException {
connection = new DatabricksConnection(connectionContext, databricksClient);
connection.open();
// setReadOnly is a JDBC hint; the driver does not enforce read-only mode, so both values are
// accepted as no-ops (see JDBC spec). isReadOnly() continues to report false.
assertDoesNotThrow(() -> connection.setReadOnly(false));
assertThrows(
DatabricksSQLFeatureNotSupportedException.class, () -> connection.setReadOnly(true));
assertDoesNotThrow(() -> connection.setReadOnly(true));
assertFalse(connection.isReadOnly());
ExecutorService executorService = Executors.newFixedThreadPool(1);
assertDoesNotThrow(() -> connection.abort(executorService));
connection.close();
Expand Down
Loading