Skip to content

SEA metadata: throw for invalid null/empty params (Thrift parity)#1390

Merged
gopalldb merged 9 commits intodatabricks:mainfrom
msrathore-db:sea-metadata-throw-parity
Apr 9, 2026
Merged

SEA metadata: throw for invalid null/empty params (Thrift parity)#1390
gopalldb merged 9 commits intodatabricks:mainfrom
msrathore-db:sea-metadata-throw-parity

Conversation

@msrathore-db
Copy link
Copy Markdown
Collaborator

Summary

  • Change key-based SEA metadata operations (getPrimaryKeys, getImportedKeys, getExportedKeys, getCrossReference) to throw SQLException instead of returning empty ResultSets for invalid parameter combinations
  • Matches Thrift server behavior: null/empty table → throw, null schema with explicit catalog → throw, all-empty strings in cross-reference → throw
  • Builds on Resolve null catalog/schema in SEA key-based metadata operations #1370 which added null catalog/schema resolution for valid cases

What changed

  • DatabricksMetadataQueryClient.resolveKeyBasedParams(): Now throws DatabricksSQLException for invalid combos instead of returning null
  • DatabricksMetadataQueryClient.listExportedKeys(): Added null/empty table validation
  • DatabricksDatabaseMetaData.getCrossReference(): Added empty string validation for both parent and foreign sides
  • DatabricksMetadataQueryClientTest: Updated tests to expect exceptions instead of empty results
  • MetadataNullResolutionTests: Updated integration tests to verify exception-throwing behavior

Thrift behavior reference

Scenario Thrift behavior SEA behavior (after this PR)
getPrimaryKeys(null, null, table) Resolves to current catalog/schema Same (from #1370)
getPrimaryKeys(catalog, null, table) Throws Throws
getPrimaryKeys(catalog, schema, null) Throws Throws
getCrossReference(all empty strings) Throws Throws

Test plan

  • Unit tests: DatabricksMetadataQueryClientTest — 57 tests pass
  • Integration tests: MetadataNullResolutionTests (requires WireMock stub re-recording)
  • CI pipeline

NO_CHANGELOG=true

This pull request was AI-assisted by Isaac.

… Thrift parity

Change key-based SEA metadata operations (getPrimaryKeys, getImportedKeys,
getExportedKeys, getCrossReference) to throw SQLException instead of returning
empty ResultSets for invalid parameter combinations like null/empty table or
null schema with explicit catalog. This matches Thrift server behavior.

Co-authored-by: Isaac
Signed-off-by: Madhavendra Rathore <[email protected]>
if (parentTable == null && foreignTable == null) {
boolean parentTableMissing = parentTable == null || parentTable.isEmpty();
boolean foreignTableMissing = foreignTable == null || foreignTable.isEmpty();
if (parentTableMissing && foreignTableMissing) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add logging

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added LOGGER.debug() before all throw sites in the latest commits.

IDatabricksSession session, String catalog, String schema, String table) throws SQLException {
LOGGER.debug("public ResultSet listExportedKeys() using SDK");

if (table == null || table.isEmpty()) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add logging

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added LOGGER.debug() before the throw.

String catalog, String schema, String table, IDatabricksSession session) throws SQLException {
if (table == null) {
return null;
if (table == null || table.isEmpty()) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logging

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added LOGGER.debug() with the table value before throwing.

}
} else if (schema == null) {
return null;
} else if (schema == null || schema.isEmpty()) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logging

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added LOGGER.debug() that includes the explicit catalog value for context.


if (catalog == null || schema == null) {
return null;
throw new DatabricksSQLException(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this exception? this will throw when catalog= null, but schema is valid

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a safety net for when getCurrentCatalogAndSchema() returns null values (server error edge case). In normal flow: if catalog was null it gets resolved at line 533, and if schema was also null it gets resolved at line 536 — so both are non-null by this point. This check only triggers if the server returns null for current_catalog or current_schema. Added a comment and debug log with the actual values for clarity.

Address PR review comments: add LOGGER.debug() calls before each
throw site in getCrossReference empty-string check, listExportedKeys
null table check, and resolveKeyBasedParams validation. Also add
comment clarifying the safety-net check for getCurrentCatalogAndSchema
returning null values.

Co-authored-by: Isaac
Signed-off-by: Madhavendra Rathore <[email protected]>
Empty strings are passed through to the server like Thrift does,
instead of being treated as invalid. Only null values trigger
exceptions for table and schema parameters.

Co-authored-by: Isaac
Signed-off-by: Madhavendra Rathore <[email protected]>
Match Thrift behavior for getCrossReference:
- null table on either side = "unspecified", return empty ResultSet
- empty string table = invalid, throw SQLException (Thrift server rejects these)

Co-authored-by: Isaac
Signed-off-by: Madhavendra Rathore <[email protected]>
…rns empty

Based on comparator results, align all key-based metadata ops with Thrift:
- getPrimaryKeys/getImportedKeys/getExportedKeys: throw for null OR empty table
- getCrossReference: throw for null/empty parentTable, throw for empty foreignTable,
  return empty ResultSet for null foreignTable (Thrift treats as "unspecified")

Co-authored-by: Isaac
Signed-off-by: Madhavendra Rathore <[email protected]>
Thrift's getExportedKeys returns empty ResultSet for empty table name
(it always returns empty in DBSQL). Match this behavior by only
throwing for null, not empty string.

Co-authored-by: Isaac
Signed-off-by: Madhavendra Rathore <[email protected]>
Delete stub directories for tests that were renamed from
*ReturnsEmpty to *Throws — these tests now throw before
making any server call, so stubs are not needed.

Co-authored-by: Isaac
Signed-off-by: Madhavendra Rathore <[email protected]>
@gopalldb gopalldb merged commit c9a7beb into databricks:main Apr 9, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants