Skip to content

Read a Databricks catalog, and pin catalog rows as a shared fixture - #278

Open
jat255 wants to merge 2 commits into
jat255/xp65-snowflake-readerfrom
jat255/xp65-databricks-reader
Open

Read a Databricks catalog, and pin catalog rows as a shared fixture#278
jat255 wants to merge 2 commits into
jat255/xp65-snowflake-readerfrom
jat255/xp65-databricks-reader

Conversation

@jat255

@jat255 jat255 commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Fourth PR of the catalog import stack (kata xp65). Stacked on #277. Ports the catalog-import half of catalog-databricks.R, and moves both readers' row interpretation into a shared fixture.

Metric views are out of scope with the rest of the semantic-model work (kata gcgj).

Row interpretation is now a shared fixture

Which rows are relations, what kind each is, which comments count as prose, and where a DESCRIBE reply stops being columns are all user-observable, so they belong in tests/shared/ rather than being asserted in each language. catalog-rows.json carries the rows both warehouses actually return and what both implementations must make of them. Running the queries stays each language's own business; only their replies are a contract.

Booleans travel as strings, because a bare JSON true reads back as a logical in R and an absent one as NULL, which would let the two runners disagree about a fixture neither had changed.

R changes

@simonpcouch

R/ has no new behavior, but does have one refactor. Snowflake's column shaping was inline in snowflake_describe_relation(), which also runs the query, so the contract it implements could not be reached or tested without a live connection. It is now snowflake_describe_rows(), called by that same function with the same rows and returning the same data frame. Databricks already had databricks_columns_from_describe() split out, so it needed nothing and this makes Snowflake's implementation more consistent.

In the test suite, two hand-written tests are replaced by fixture runners with their expectations now pinned in catalog-rows.json. The Python suite asserts the same cases.

Why it is safe: test-catalog-snowflake.R and test-catalog-databricks.R both pass.

Verification

677 Python tests, ruff and pyrefly clean. The reader was confirmed to bite by removing the # metadata cutoff and by removing the hive_metastore fork.

@jat255
jat255 marked this pull request as draft September 4, 2026 06:10
@jat255 jat255 added this to the py-M2: data layer milestone Sep 4, 2026
@jat255 jat255 added needs-manual-review Agent-created work that needs a human review py Affects the Python implementation labels Sep 4, 2026
@jat255
jat255 force-pushed the jat255/xp65-databricks-reader branch from 3babd70 to dfed967 Compare September 5, 2026 04:58
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Preview deployed to Connect (dogfood.team.pct.posit.it): https://dogfood.team.pct.posit.it/connect/#/apps/d7a36cae-8f27-448b-a478-61b81fbe3942/draft/368186

Deployed from commit 7aa91a8.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Preview deployed to Connect (dogfood.team.pct.posit.it): https://dogfood.team.pct.posit.it/connect/#/apps/d7a36cae-8f27-448b-a478-61b81fbe3942/draft/367964

Deployed from commit dfed967.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Preview deployed to Connect (connect.staging.pct.posit.it): https://connect.staging.pct.posit.it/connect/#/apps/ad662e1b-5048-4acc-9ad7-f9478c92274e/draft/2644

Deployed from commit 7aa91a8.

@jat255
jat255 force-pushed the jat255/xp65-databricks-reader branch from dfed967 to 865cb4e Compare September 6, 2026 02:07
@jat255

jat255 commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator Author

Manual review completed 2026-09-05 23:35 MDT by @jat255. Findings: 1 MEDIUM (untested hive_metastore fork in exact_relation) and 1 LOW (unpinned backtick doubling in identifier quoting) — both closed with tests in 9f15c41. 4 INFO, all documented or fail-safe divergences from catalog-databricks.R, no action needed. Note: the two replaced R tests each dropped a dbQuoteIdentifier rendering expectation, so "none was dropped" is slightly off — the substance is pinned by the fixture's expect_identical on the Id, and the rendering is DBI's contract. Local checks green: ruff, pyrefly, 796 tests. R tests not run locally (ellmer 0.4.2 < 0.5.0 here); CI's R CMD check passed on this head. Removing needs-manual-review.

@jat255 jat255 added r Affects the R implementation and removed needs-manual-review Agent-created work that needs a human review labels Sep 6, 2026
@jat255
jat255 requested a review from simonpcouch September 6, 2026 05:42
@jat255
jat255 marked this pull request as ready for review September 6, 2026 05:43
Fourth of the catalog import stack (kata xp65). Ports the catalog-import
half of catalog-databricks.R.

Unity Catalog is read through system.information_schema, which is a plain
query rather than a SHOW, and the information schema itself is excluded so a
listing describes the data rather than the catalog. The legacy
hive_metastore is not in there at all and needs SHOW TABLES, which is why
the listing forks on the catalog name and why selecting hive_metastore
requires a schema: there is nothing to enumerate a whole legacy catalog
from.

DESCRIBE TABLE does not report nullability, so it is read separately from
system.information_schema.columns and joined by column name. hive_metastore
has no information schema to ask, so its columns keep an unknown
nullability rather than a guessed one.

DESCRIBE TABLE also appends partition and detail sections after a row whose
name starts with `#`; reading past that turns section headings into columns.

Metric views are out of scope with the rest of the semantic-model work
(kata gcgj). They report as views here, and telling them apart needs the
ODBC object type R queries, which only matters once metric views are
supported. The comment in the reader says so.
Which rows are relations, what kind each is, which comments count as prose,
and where a DESCRIBE reply stops being columns are all user-observable, so
they belong in tests/shared/ rather than being asserted in each language.
catalog-rows.json carries the rows Snowflake and Databricks actually return
and what both implementations must make of them; R's hand-written row
assertions are replaced by runners over it.

Running the queries stays each language's own business. Only their replies
are a contract.

One R change beyond the runners: the Snowflake column shaping was inline in
snowflake_describe_relation(), which also runs the query, so the contract
was not reachable without a connection. It is now
snowflake_describe_rows(), called by the same function. Behaviour is
unchanged. Databricks already had databricks_columns_from_describe().

Booleans travel as strings, because a bare JSON true reads back as a logical
in R and an absent one as NULL, which would make the two runners disagree
about a fixture neither had changed.

Both runners were confirmed to bite by changing one expected kind and
watching each suite fail.

Found by roborev job 335.
@jat255
jat255 force-pushed the jat255/xp65-databricks-reader branch from 865cb4e to 7aa91a8 Compare September 6, 2026 06:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

py Affects the Python implementation r Affects the R implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant