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 @@ -8,6 +8,7 @@
- `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
- Fixed connections failing when the same parameter is provided in both the JDBC URL and the connection properties, with the JDBC URL taking precedence.
- 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ private DatabricksConnectionContext(

/**
* Builds a map of properties from the given connection parameter string and properties object.
* Connection URL parameters take precedence over entries in the properties object.
*
* @param connectionParamString the connection parameter string
* @param properties the properties object
Expand All @@ -113,6 +114,9 @@ private DatabricksConnectionContext(
public static ImmutableMap<String, String> buildPropertiesMap(
String connectionParamString, Properties properties) {
ImmutableMap.Builder<String, String> parametersBuilder = ImmutableMap.builder();
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
parametersBuilder.put(entry.getKey().toString().toLowerCase(), entry.getValue().toString());
}
// check if connectionParamString is empty or null
if (!isNullOrEmpty(connectionParamString)) {
String[] urlParts = connectionParamString.split(DatabricksJdbcConstants.URL_DELIMITER);
Expand All @@ -128,10 +132,7 @@ public static ImmutableMap<String, String> buildPropertiesMap(
}
}
}
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
parametersBuilder.put(entry.getKey().toString().toLowerCase(), entry.getValue().toString());
}
return parametersBuilder.build();
return parametersBuilder.buildKeepingLast();
}

static IDatabricksConnectionContext parseWithoutError(String url, Properties properties) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ public void testBuildPropertiesMap() {
assertEquals("value3", propertiesMap.get("param3"));
}

@ParameterizedTest
@CsvSource({"url-value, url-value", "url-value, properties-value"})
public void testBuildPropertiesMapUrlOverridesProperties(
String urlValue, String propertiesValue) {
Properties properties = new Properties();
properties.setProperty("HTTPPATH", propertiesValue);

ImmutableMap<String, String> propertiesMap =
buildPropertiesMap("httpPath=" + urlValue, properties);

assertEquals(1, propertiesMap.size());
assertEquals(urlValue, propertiesMap.get("httppath"));
}

@Test
public void testTelemetrySocketTimeoutDefault() throws DatabricksSQLException {
DatabricksConnectionContext context =
Expand Down
Loading