Repository navigation
feat: return column expression ranges with the node SQL read - #1426
Merged
Merged
Conversation
Lineage rows keep the output expression's byte range in the cleaned analysis SQL, the analysis cache stores it, shared analyses rebase it onto each member's relation names, and query_expression_ranges maps it back to the model's query SQL. Not yet exposed by the snapshot or UI.
Snapshot model nodes carry each output column's expression range as a byte range of compiled_sql, mapped back through typed SQL macro markers and cursor bounds; the node SQL read returns them. DuckDB e2e passes; the Snowflake DuckShop edge model and DuckDB qualified columns are strict xfails until SQLQuack's strict parsers record projection spans.
Ranges move out of the node definition into the per-snapshot columns document, so they never change a node hash or record a node change; the node SQL read ignores unknown per-column keys and drops malformed or misplaced ranges.
Map a cleaned range edge only between source-adjacent characters, so a range beside a removed reference call or inside generated text is dropped instead of moved. Skip unnamed output columns. Split helpers into single-function entry modules, make the tests table-driven, and add a DuckShop edge model qualified by its reference call.
kvlonge
marked this pull request as ready for review
November 12, 2026 12:54
kvlonge
enabled auto-merge
November 12, 2026 12:56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
SQLQuack gives each output column's defining expression as a byte range of the SQL it analysed. The UI needs them in the compiled SQL the node SQL read returns, which differs from the analysed text.
Changes
compiled_sql. An edge beside removed or generated text (a__ref(...)call, a filled placeholder) is dropped, never moved.columnssnapshot document,{node_key: {column: {"expression_range": [start, end]}}}, documented with the document kinds; out of node hashes, so a SQLQuack span change never marks a model changed. No schema change.NodeSqlreturnsexpression_ranges. Readers ignore unknown per-column keys; a missing or malformed range means no highlight. The OpenAPI client is regenerated.int_edge_expression_spansandint_edge_reference_qualified_spans, with unit tests. Expectations captured on the Snowflake edge target; they equal the hand derivation, with only literal spelling changed.Verification
__refand cursor bounds give byte-exact ranges; a reference-qualified column gets none; node JSON has no ranges. The installed CLI's person SQL read returns them.columnsdocument: 397 B (184 B compressed); every column ranged: 208,377 B (21,851 B).make check-cipasses.