From 260e8c96ab62a2bb38e37a9ffafb4e2a5dd22016 Mon Sep 17 00:00:00 2001 From: Prathamesh Baviskar Date: Thu, 20 Aug 2026 17:05:19 +0000 Subject: [PATCH] [PECOBLR-3982] Use JDBC-standard exception for unimplemented features Signed-off-by: Prathamesh Baviskar --- NEXT_CHANGELOG.md | 4 ++ ...icksSQLFeatureNotImplementedException.java | 13 ++++++- ...SQLFeatureNotImplementedExceptionTest.java | 38 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/databricks/jdbc/exception/DatabricksSQLFeatureNotImplementedExceptionTest.java diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index e12c8875f4..a255d37b8d 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -8,6 +8,10 @@ - `DatabaseMetaData.getColumns(...)` with a `null` catalog now issues a single `SHOW COLUMNS IN ALL CATALOGS` statement (consistent with `getSchemas`/`getTables`) instead of enumerating every catalog and issuing a per-catalog `SHOW COLUMNS`. Older DBR versions that do not support the syntax transparently fall back to the previous enumerate-and-fan-out behavior. ### Fixed +- `DatabricksSQLFeatureNotImplementedException` now follows the JDBC contract by extending + `SQLFeatureNotSupportedException`, while continuing to emit the existing + `NOT_IMPLEMENTED_OPERATION` telemetry error. + - Fixed `IdleConnectionEvictor` thread leak in long-running applications. Driver-side resources (HTTP client, background threads) are now always released when `Connection.close()` is called, even if statement cleanup or server-side session termination fails. - Throw `DatabricksSQLException` instead of an unchecked `ClassCastException` when a complex-type getter (`getArray`, `getStruct`, `getMap`) is called on a column of a different complex type. diff --git a/src/main/java/com/databricks/jdbc/exception/DatabricksSQLFeatureNotImplementedException.java b/src/main/java/com/databricks/jdbc/exception/DatabricksSQLFeatureNotImplementedException.java index 9bd26abb01..e00810d634 100644 --- a/src/main/java/com/databricks/jdbc/exception/DatabricksSQLFeatureNotImplementedException.java +++ b/src/main/java/com/databricks/jdbc/exception/DatabricksSQLFeatureNotImplementedException.java @@ -1,10 +1,19 @@ package com.databricks.jdbc.exception; +import com.databricks.jdbc.common.TelemetryLogLevel; +import com.databricks.jdbc.common.util.DatabricksThreadContextHolder; import com.databricks.jdbc.model.telemetry.enums.DatabricksDriverErrorCode; +import com.databricks.jdbc.telemetry.TelemetryHelper; +import java.sql.SQLFeatureNotSupportedException; -public class DatabricksSQLFeatureNotImplementedException extends DatabricksSQLException { +public class DatabricksSQLFeatureNotImplementedException extends SQLFeatureNotSupportedException { public DatabricksSQLFeatureNotImplementedException(String reason) { - super(reason, DatabricksDriverErrorCode.NOT_IMPLEMENTED_OPERATION); + super(reason, DatabricksDriverErrorCode.NOT_IMPLEMENTED_OPERATION.name()); + TelemetryHelper.exportFailureLog( + DatabricksThreadContextHolder.getConnectionContext(), + DatabricksDriverErrorCode.NOT_IMPLEMENTED_OPERATION.name(), + reason, + TelemetryLogLevel.ERROR); } } diff --git a/src/test/java/com/databricks/jdbc/exception/DatabricksSQLFeatureNotImplementedExceptionTest.java b/src/test/java/com/databricks/jdbc/exception/DatabricksSQLFeatureNotImplementedExceptionTest.java new file mode 100644 index 0000000000..72518a6812 --- /dev/null +++ b/src/test/java/com/databricks/jdbc/exception/DatabricksSQLFeatureNotImplementedExceptionTest.java @@ -0,0 +1,38 @@ +package com.databricks.jdbc.exception; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.Mockito.mockStatic; + +import com.databricks.jdbc.common.TelemetryLogLevel; +import com.databricks.jdbc.common.util.DatabricksThreadContextHolder; +import com.databricks.jdbc.model.telemetry.enums.DatabricksDriverErrorCode; +import com.databricks.jdbc.telemetry.TelemetryHelper; +import java.sql.SQLFeatureNotSupportedException; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; + +class DatabricksSQLFeatureNotImplementedExceptionTest { + + @Test + void followsJdbcContractAndPreservesTelemetry() { + String reason = "Not implemented"; + DatabricksSQLFeatureNotImplementedException exception; + try (MockedStatic telemetryHelper = mockStatic(TelemetryHelper.class)) { + exception = new DatabricksSQLFeatureNotImplementedException(reason); + + telemetryHelper.verify( + () -> + TelemetryHelper.exportFailureLog( + DatabricksThreadContextHolder.getConnectionContext(), + DatabricksDriverErrorCode.NOT_IMPLEMENTED_OPERATION.name(), + reason, + TelemetryLogLevel.ERROR)); + } + + assertInstanceOf(SQLFeatureNotSupportedException.class, exception); + assertEquals( + DatabricksDriverErrorCode.NOT_IMPLEMENTED_OPERATION.name(), exception.getSQLState()); + assertEquals(0, exception.getErrorCode()); + } +}