Skip to content

fix: order views and materialized views after the views they read - #314

Draft
dilame wants to merge 1 commit into
stripe:mainfrom
dilame:fix/view-on-view-deps
Draft

dilame wants to merge 1 commit into
stripe:mainfrom
dilame:fix/view-on-view-deps

Conversation

@dilame

@dilame dilame commented Sep 26, 2026

Copy link
Copy Markdown

What changed

A view or materialized view is now ordered after the views and materialized views its defining query reads.

  • The view/materialized-view dependency query collects relkind in r, p, v, m and carries the kind in each dependency.
  • TableDependency gains Kind, and the view and materialized-view generators map a dependency to the vertex that emits that relation's statement: a view is created under the table vertex id but dropped under its own, a materialized view under its own.
  • The dependency query now restricts to the object's own rewrite rule. d.refobjid = c.oid alone also matches the rules of every other view that reads this one, so those readers were reported as dependencies of this object; with only tables in the filter the extra rows were harmless, with views and materialized views they are not.

Why

PostgreSQL resolves a view's defining query at CREATE VIEW time, and a view's query may read another view. Nothing ordered a view against the views it reads, so a plan that creates both could emit the reader first and fail:

CREATE MATERIALIZED VIEW "deposit"."product_opening_question_by_axis" AS
 ... FROM deposit.product_coverage_warning coverage ...
WITH NO DATA: ERROR: relation "deposit.product_coverage_warning" does not exist

Known limitation

A view whose dependency view is dropped or recreated is not itself recreated by this change: the per-column recreation check only applies to tables, whose columns are modelled per column. That case already failed before this change (the dependency was not tracked at all), so nothing regresses, but the cascade is not implemented.

Validation

go test ./...

New acceptance cases: a materialized view reading a view created in the same plan, and a view reading another view, each asserting the exact statement order.

A view's defining query is resolved at CREATE time, and it may read another
view or a materialized view. The dependency query only collected tables
(relkind in r, p), so a view that reads a view carried no dependency and was
emitted in an arbitrary order.

The dependency now carries the relation's relkind, and the generators map it to
the vertex that emits that relation's statement — a view is created under the
table vertex id but dropped under its own, a materialized view under its own.
The dependency query also now restricts to the object's own rewrite rule:
`d.refobjid = c.oid` alone also matches the rules of every other view that
reads this one, which reported those readers as dependencies of this object.
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