Skip to content

Fix PreparedStatement.getMetaData() crash for SQL type aliases#1289

Open
gopalldb wants to merge 3 commits into
databricks:mainfrom
gopalldb:fix/type-alias-mapping-describe-query
Open

Fix PreparedStatement.getMetaData() crash for SQL type aliases#1289
gopalldb wants to merge 3 commits into
databricks:mainfrom
gopalldb:fix/type-alias-mapping-describe-query

Conversation

@gopalldb
Copy link
Copy Markdown
Collaborator

@gopalldb gopalldb commented Mar 19, 2026

Summary

Completes the fix for #1064PreparedStatement.getMetaData() throws IllegalArgumentException for SQL type aliases.

  • PreparedStatement.getMetaData() triggers a DESCRIBE QUERY internally, and the response type names are mapped via ColumnInfoTypeName.valueOf(). SQL type aliases like VARCHAR, INTEGER, NUMERIC, DEC, REAL, NVARCHAR, NCHAR have no enum entry, causing IllegalArgumentException
  • Replace valueOf() with DatabricksTypeUtil.getColumnInfoType() which handles all alias mappings and falls back to USER_DEFINED_TYPE instead of crashing
  • Extend getColumnInfoType() to cover all missing SQL standard aliases, plus VARIANT, GEOMETRY, GEOGRAPHY, and multi-word INTERVAL sub-types
  • Fix incorrect DATE to TIMESTAMP mapping (DATE is a distinct JDBC type)

Background: Issue #1064 reported crashes for BIGINT, SMALLINT, TINYINT, INTERVAL, VOID, GEOMETRY, GEOGRAPHY. Some of these (BIGINT, SMALLINT, TINYINT) were already fixed on main by adding enum entries. This PR addresses the remaining aliases and replaces the fragile valueOf() pattern with a safe mapping function.

Test plan

  • DatabricksTypeUtilTest - 83 tests (added parameterized tests for all aliases, INTERVAL sub-types, and full type-to-JDBC-code chain for VARIANT/TIMESTAMP/TIMESTAMP_NTZ/GEOGRAPHY/GEOMETRY)
  • DatabricksResultSetMetaDataTest - 28 tests (added DESCRIBE QUERY coverage for GEOGRAPHY, GEOMETRY, BIGINT, SMALLINT, TINYINT, VARCHAR, INTEGER)
  • Full jdbc-core suite - passes, 0 failures
  • Live verification against dogfood warehouse — all getMetaData() calls succeed (server normalizes aliases, so crash cannot be reproduced live, but fix confirmed by code review and unit tests)

Closes #1064

This pull request was AI-assisted by Isaac.

gopalldb and others added 2 commits March 19, 2026 16:50
…AR, INTEGER, etc.)

The DESCRIBE QUERY path in DatabricksResultSetMetaData used
ColumnInfoTypeName.valueOf() directly on server-returned type names,
which crashes with IllegalArgumentException for SQL type aliases
like VARCHAR, INTEGER, NUMERIC, DEC, REAL, NVARCHAR, and NCHAR that
have no corresponding enum entry.

Replace valueOf() with DatabricksTypeUtil.getColumnInfoType() which
already handles canonical-to-alias mappings, and extend it to cover
all missing SQL standard aliases:
- VARCHAR/NVARCHAR/NCHAR -> STRING
- INTEGER -> INT
- NUMERIC/DEC -> DECIMAL
- REAL -> FLOAT
- VARIANT -> STRING
- GEOMETRY/GEOGRAPHY -> their own types
- INTERVAL sub-types (multi-word) -> INTERVAL

Also fixes incorrect DATE -> TIMESTAMP mapping (DATE is a distinct type).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
…contract

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
Copy link
Copy Markdown
Collaborator

@msrathore-db msrathore-db left a comment

Choose a reason for hiding this comment

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

Please test it on a real workspace with a table containing all these data types

Copy link
Copy Markdown
Collaborator

@sreekanth-db sreekanth-db left a comment

Choose a reason for hiding this comment

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

+1, lets test in on real workspace with all the supported datatypes.

Shall we add this is a mandatory step in claude.md to test any changes on real workspace before raising a PR ?

@gopalldb
Copy link
Copy Markdown
Collaborator Author

Local Verification Results

Tested against dogfood warehouse (e2-dogfood.staging.cloud.databricks.com, warehouse 864004c1b3961382).

Before fix (main branch)

Test Result Notes
getMetaData() with standard types (INT, STRING, BOOLEAN, etc.) PASS Server returns canonical types
getMetaData() with alias-created table (VARCHAR, NUMERIC, DEC, REAL) PASS Server normalizes aliases to canonical types in DESCRIBE QUERY
getMetaData() with VARIANT PASS Already has special handling
getMetaData() with INTERVAL subtypes (YEAR, DAY) PASS Already has special handling
DATE column jdbcType 91 (DATE) but internal mapping goes DATE→TIMESTAMP Bug confirmed in code review

After fix (PR branch)

Test Result Notes
All above tests PASS No regressions
DATE mapping Fixed: DATE→DATE (not DATE→TIMESTAMP) ColumnInfoTypeName.DATE returned correctly
Unit tests (DatabricksTypeUtilTest + DatabricksResultSetMetaDataTest) 111 pass, 0 failures 83 new parameterized tests for all aliases

Note on crash reproduction

The ColumnInfoTypeName.valueOf() crash could not be reproduced against the live dogfood server because it normalizes SQL type aliases to canonical types in DESCRIBE QUERY responses (e.g., VARCHAR(100)string, NUMERIC(10,2)decimal(10,2)). The crash would only occur with server versions that return raw aliases.

However, the fix is correct — replacing the fragile valueOf() with getColumnInfoType() (which has a safe USER_DEFINED_TYPE fallback) is a necessary defensive measure, and the DATE mapping fix is verified as working correctly.


This comment was generated with GitHub MCP.

@gopalldb
Copy link
Copy Markdown
Collaborator Author

Correction on DATE mapping verification:

The live test showed jdbcType=91 (DATE) on both branches because the getMetaData() call resolved types through the int-based path (ColumnInfoTypeName.valueOf(getDatabricksTypeFromSQLType(metadata.getTypeInt())) at line 282), which already maps correctly.

The DATE bug is in the text-based path at line 440-465 (getColumnInfoType("DATE")) used by the DESCRIBE QUERY code path. On main, DATE falls through to ColumnInfoTypeName.TIMESTAMP, which would produce jdbcType=93 instead of 91. This path is hit when the server returns type names as strings (DESCRIBE QUERY response), not as JDBC int codes.

The live dogfood server didn't exercise this text-based path in our test, but the fix is confirmed correct by code review and unit tests (the new testGetColumnInfoTypeToJdbcType parameterized test covers DATE → jdbcType=91 explicitly).


This comment was generated with GitHub MCP.

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.

[BUG] PreparedStatement.getMetaData() throws java.lang.IllegalArgumentException for some data types.

4 participants