Fix PreparedStatement.getMetaData() crash for SQL type aliases#1289
Conversation
…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>
msrathore-db
left a comment
There was a problem hiding this comment.
Please test it on a real workspace with a table containing all these data types
sreekanth-db
left a comment
There was a problem hiding this comment.
+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 ?
Local Verification ResultsTested against dogfood warehouse ( Before fix (main branch)
After fix (PR branch)
Note on crash reproductionThe However, the fix is correct — replacing the fragile This comment was generated with GitHub MCP. |
|
Correction on DATE mapping verification: The live test showed The DATE bug is in the text-based path at line 440-465 ( 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 This comment was generated with GitHub MCP. |
Resolve conflicts: - NEXT_CHANGELOG.md: keep both entries - DatabricksTypeUtil.java: use VARIANT → VARIANT from main (new enum), keep GEOMETRY/GEOGRAPHY/INTERVAL sub-type handling from PR - DatabricksTypeUtilTest.java: update VARIANT test expectations to VARIANT (was STRING before main's change) - DatabricksResultSetMetaDataTest.java: update VARIANT JDBC type from Types.VARCHAR to Types.OTHER (matches new VARIANT enum mapping) Co-authored-by: Isaac Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
5d4eda5 to
a4565a8
Compare
…ral change
getColumnInfoType("DATE") returns TIMESTAMP (matching main) to preserve
backward compatibility for setDate() parameter serialization. The DESCRIBE
QUERY constructor handles DATE separately to return ColumnInfoTypeName.DATE
(correct metadata), matching main's valueOf("DATE") behavior.
This avoids changing how DATE parameters are serialized in Thrift requests,
which would break WireMock stubs and could affect server interpretation.
Co-authored-by: Isaac
Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
…stubs
Previously getColumnInfoType("DATE") incorrectly returned TIMESTAMP,
causing setDate() to serialize parameters as TIMESTAMP type. Now returns
DATE correctly. This is a behavioral change documented in BREAKING CHANGES.
Re-recorded WireMock stubs for testSetDate in both Thrift and SEA modes
against dogfood warehouse with the corrected DATE parameter type.
Co-authored-by: Isaac
Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
Co-authored-by: Isaac Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
Summary
Completes the fix for #1064 —
PreparedStatement.getMetaData()throwsIllegalArgumentExceptionfor SQL type aliases.PreparedStatement.getMetaData()triggers a DESCRIBE QUERY internally, and the response type names are mapped viaColumnInfoTypeName.valueOf(). SQL type aliases like VARCHAR, INTEGER, NUMERIC, DEC, REAL, NVARCHAR, NCHAR have no enum entry, causingIllegalArgumentExceptionvalueOf()withDatabricksTypeUtil.getColumnInfoType()which handles all alias mappings and falls back toUSER_DEFINED_TYPEinstead of crashinggetColumnInfoType()to cover all missing SQL standard aliases, plus VARIANT, GEOMETRY, GEOGRAPHY, and multi-word INTERVAL sub-typesBackground: 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.Scope
Changes affect only
PreparedStatement.getMetaData()— the DESCRIBE QUERY code path. Verified by tracing all call sites:DatabricksTypeUtil.getColumnInfoType()is called from 2 places:DatabricksResultSetMetaDataDESCRIBE QUERY constructor (line 453) — only used by PreparedStatement.getMetaData()DatabricksPreparedStatementparameter metadata (line 859) — also PreparedStatement-onlyResultSet.getMetaData()uses different constructors that takeDatabricksColumnobjects from server responses — unaffectedDatabaseMetaDataoperations (getColumns,getTables, etc.) useMetadataResultSetBuilder— unaffectedTest plan
Testing
Live E2E verification (May 21, 2026)
Tested against dogfood warehouse (
e2-dogfood.staging.cloud.databricks.com, warehousedd43ee29fedd958d).Setup: Created a table with type alias columns to exercise DESCRIBE QUERY:
Test 1: Table with DDL type aliases — PASSED
Test 2: CAST expressions with type aliases — PASSED
All 5 columns returned correct metadata without
IllegalArgumentException.Test 3: Standard types (regression) — PASSED
Test 4: INTERVAL type — PASSED
Returned
type=INTERVAL YEAR (12).Test 5: VARIANT type — PASSED
Returned
type=VARIANT (12).Before-fix behavior (reproduced via unit test)
Without the fix,
PreparedStatement.getMetaData()on any query returning VARCHAR, INTEGER, NUMERIC, DEC, or REAL columns throws:Closes #1064
This pull request was AI-assisted by Isaac.