Skip to content

Deployment build order should take into account dimension links - #2531

Merged
shangyian merged 3 commits into
mainfrom
dim-link-deploy-ordering
Sep 9, 2026
Merged

Deployment build order should take into account dimension links#2531
shangyian merged 3 commits into
mainfrom
dim-link-deploy-ordering

Conversation

@shangyian

@shangyian shangyian commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

A deployment that both adds a column to an existing dimension and adds a node linking to that new column fails. The root cause is that the deploy order is not taking into account the dimension link dependency, and so the dim is processed before the node-update gets processed.

Problem

A dimension node exists with two columns:

name: default.us_state
query: SELECT state_id, state_name FROM default.us_states"

A change adds a third column and, at the same time, a node that links to it:

-- us_state gains a column
name: default.us_state
query: SELECT state_id, state_name, state_abbr FROM default.us_states"
-- and a new node links to the column this push is adding
name: default.hard_hat
query: SELECT hard_hat_id, state FROM default.hard_hats
dimension_links:
  - type: reference
    node_column: state
    dimension: us_state.state_abbr

Deploy ordering is only derived from query lineage, so us_state and hard_hat sort into the same level:

LEVELS   [['…hard_hats', '…us_states'],     level 0: the two sources
          ['…hard_hat',  '…us_state']]      level 1: both, together

Both are validated as one batch, and _prefetch_dimension_link_nodes resolves the dimension's columns from the database, where us_state is still the old version without the column. state_abbr exists only in the spec being deployed in that same batch, so the link fails:

[invalid] Dimension attribute 'state_abbr' not found in dimension node '…us_state'

Solution

This PR adds dimension links to the deploy-ordering graph so that the dimension node lands in an earlier level than anything linking to it.

Each spec's dimension_links targets become ordering edges, added to the ordering_graph. They're not added to plan.node_graph, so they influence ordering without being mistaken for parents.

Test Plan

  • PR has an associated issue: #
  • make check passes
  • make test shows 100% unit test coverage

Deployment Plan

The one exception that we'll fix in a follow-up PR: dimension links can also be cyclic (and query lineage cannot), e.g., join links support self-joins with a role. The case where two dimensions link to each other and where one adds a column the other's link targets would still fail.

A push that both adds a column to an existing dimension and adds a node
linking to that new attribute marks the linking node INVALID with
"Dimension attribute '...' not found". Four tests pin the behavior:

- reference link: the deploy fails, and the identical retry succeeds
- join link: the node is INVALID but the deploy reports success
- with query lineage on the dimension: the identical link passes
- brand-new dimension in an empty namespace: passes

The failure needs the dimension to already be persisted with its old
column set. Link validation reads the persisted revision's columns
(_prefetch_dimension_link_nodes), and the prefetch runs once per
topological level, which is built from query lineage only -- dimension
link edges are not ordering edges. With no query dependency between
them, the dimension and the linking node share a level, so the link
resolves against pre-push columns. Query lineage or an absent dimension
both avoid it, which is why the last two cases pass.
The two characterization tests now assert the intended behavior: a push that
adds a dimension column and a link onto it deploys the link successfully, for
both the reference and the join form. Two cycle cases join them -- a self-join
with a role and a mutually linked pair of dimensions -- which link ordering
must not turn into a hard failure.
Link validation resolves a dimension attribute against the dimension's
persisted columns, and the deploy order came from query lineage alone. A push
that added a column to an existing dimension and a link onto that column put
both in the same topological level, so the link resolved against the pre-push
column set and the linking node landed INVALID; the identical push then
succeeded on a retry.

Each spec's dimension_links now contribute deploy-ordering edges alongside
required_dimensions, kept out of plan.node_graph so they never become parents.
Links can be cyclic where query lineage cannot, so an edge that would close a
cycle -- a self-join with a role, or two dimensions linking to each other -- is
dropped instead, leaving those nodes ordered by lineage as before.

Deploy order now differs for specs whose links are not query parents, which
reorders the results list of three existing deployment tests.
@netlify

netlify Bot commented Sep 9, 2026

Copy link
Copy Markdown

Deploy Preview for thriving-cassata-78ae72 canceled.

Name Link
🔨 Latest commit f63ccd9
🔍 Latest deploy log https://app.netlify.com/projects/thriving-cassata-78ae72/deploys/6aa0fdf43cdf1000094e6841

@shangyian shangyian added the bug Something isn't working label Sep 9, 2026
@shangyian shangyian changed the title Dim link deploy ordering Deployment build order should take into account dimension links Sep 9, 2026
@shangyian
shangyian marked this pull request as ready for review September 9, 2026 23:36
@shangyian
shangyian merged commit 2af640b into main Sep 9, 2026
27 checks passed
@shangyian
shangyian deleted the dim-link-deploy-ordering branch September 9, 2026 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant