Skip to content

Reflect nested ARRAY/MAP types and tolerate unknown column types - #78

Open
aminghadersohi wants to merge 2 commits into
databricks:mainfrom
aminghadersohi:fix-reflect-nested-and-unknown-types
Open

aminghadersohi wants to merge 2 commits into
databricks:mainfrom
aminghadersohi:fix-reflect-nested-and-unknown-types

Conversation

@aminghadersohi

@aminghadersohi aminghadersohi commented Sep 26, 2026 •

Copy link
Copy Markdown

What type of PR is this?

  • Bug Fix

Description

Problem

parse_column_info_from_tgetcolumnsresponse maps only the first word of TYPE_NAME:

  • ARRAY<...> and MAP<...> columns reflect as String, so reflected/autoloaded tables lose their element types (and tools built on reflection report e.g. an ARRAY<STRING> column as STRING).
  • Any type not in GET_COLUMNS_TYPE_MAP raises KeyError, which fails reflection of the whole table or view. Observed on a SQL warehouse (DBSQL 2026.36): a table with a TIME(6) column → KeyError: 'time'; a view selecting an INTERVAL literal → KeyError: 'interval'; a NULL column in a view (VOID) → KeyError: 'void'.

Change

  • New parse_type_name() parses TYPE_NAME recursively: ARRAY<T> → DatabricksArray(T), MAP<K, V> → DatabricksMap(K, V) (nested at any depth, including DECIMAL(p,s) elements).
  • DECIMAL(p,s) is parsed in any case and with any spacing (DECIMAL(10, 2), decimal(10,2)), and a bare DECIMAL becomes Numeric(). Before, those spellings raised AttributeError, which nested parsing would have turned into a whole-table reflection failure.
  • Unrecognised types are reflected as NullType with an SAWarning, the convention SQLAlchemy dialects use, instead of raising.
  • STRUCT keeps its current String mapping (no STRUCT type exists in the dialect yet).

How is this tested?

  • Unit tests
  • E2E Tests
  • Manually
  • N/A

New cases in tests/test_local/test_parsing.py (nested parsing, DECIMAL spellings, and TIME/INTERVAL/VOID/GEOMETRY no longer raising). They fail on main and pass with this change. The local unit suite (tests/test_local, excluding e2e) passes (314), and black --check src and mypy are clean.

Related Tickets & Documents

None.

get_columns mapped only the first word of TYPE_NAME: ARRAY and MAP
columns reflected as String, and any type missing from
GET_COLUMNS_TYPE_MAP (e.g. TIME, INTERVAL, VOID) raised KeyError and
failed reflection of the whole table or view.

Parse TYPE_NAME recursively into DatabricksArray/DatabricksMap and
reflect unrecognised types as NullType with a warning, as other
SQLAlchemy dialects do.
A nested DECIMAL element spelled with a space or in lower case, e.g.
ARRAY<DECIMAL(10, 2)>, raised AttributeError and failed reflection of
the whole table. Match case-insensitively, tolerate whitespace, and fall
back to Numeric() for a bare DECIMAL.

This branch has not been deployed

No deployments
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.

1 participant