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 @@ -20,6 +20,7 @@
- When a Statement is re-executed, the previous server-side operation is now explicitly closed before starting the new execution, preventing orphaned server-side operations when Statements are reused.

### Fixed
- Fixed `DatabaseMetaData.getTables()` in Thrift mode returning rows when called with an empty `types` array. Per JDBC spec, empty types means "no types selected" and now correctly returns zero rows (matching SEA mode).
- Fixed `?` characters inside SQL comments, string literals, and quoted identifiers being incorrectly counted as parameter placeholders when `supportManyParameters=1`. `SQLInterpolator` now uses `SqlCommentParser` to locate only real placeholders. Fixes #1331.
- Fixed `MetadataOperationTimeout` not being applied when metadata operations use SHOW commands. Operations like `getTables`, `getSchemas`, and `getColumns` now respect the `MetadataOperationTimeout` connection property instead of hanging indefinitely with no timeout.
- Reclassify transient server errors to standard SQL states (08S01, 40001) across all Thrift error sites. This ensures UC unavailability and concurrent modification errors surface consistently for better retry handling. Note: Dashboards and branching logic keyed on legacy XXUCC or 42000 must be updated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,11 @@ public DatabricksResultSet listTables(
session.toString(), catalog, schemaNamePattern, tableNamePattern);
LOGGER.debug(context);

// Per JDBC spec: null types = return all types; empty array = return nothing
if (tableTypes != null && tableTypes.length == 0) {
return metadataResultSetBuilder.getTablesResult(catalog, tableTypes, new ArrayList<>());
}

if (!metadataResultSetBuilder.shouldAllowCatalogAccess(catalog, null, session)) {
return metadataResultSetBuilder.getTablesResult(catalog, tableTypes, new ArrayList<>());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -590,6 +591,21 @@ void testListTables() throws SQLException {
assertEquals(resultSet.getStatementStatus().getState(), StatementState.SUCCEEDED);
}

@Test
void testListTablesWithEmptyTypesReturnsEmptyWithoutServerCall() throws SQLException {
// Per JDBC spec: empty types array means "no types selected" → return no rows.
// The driver must short-circuit and NOT send the Thrift request to the server.
DatabricksThriftServiceClient client =
new DatabricksThriftServiceClient(thriftAccessor, connectionContext);

DatabricksResultSet resultSet =
client.listTables(session, TEST_CATALOG, TEST_SCHEMA, TEST_TABLE, new String[0]);

assertEquals(StatementState.SUCCEEDED, resultSet.getStatementStatus().getState());
assertFalse(resultSet.next(), "Empty types array must yield zero rows");
verify(thriftAccessor, never()).getThriftResponse(any());
}

@Test
void testListColumns() throws SQLException {
DatabricksThriftServiceClient client =
Expand Down
Loading