View dependency query produces false positives and misses view-to-view dependencies

Open Beginner friendly
#283 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
go, postgresql, sql
Domain
databases

Research direction

Start in internal/queries/queries.sql at the GetViews query and its table_dependencies subquery. Run the issue's t1/v1/v2 reproducer through pg-schema-diff plan, then verify the generated order is t1 → v1 → v2 without a false cycle.

Written by the indexing model from the issue text.

Description

View dependency query produces false positives and misses view-to-view dependencies

pg-schema-diff version

v1.0.5

Problem

The GetViews query in internal/queries/queries.sql has two issues in its table_dependencies subquery:

1. Missing view-to-view dependencies

The join filter dep_c.relkind IN ('r', 'p') excludes views ('v'). Views that depend on other views (e.g. CREATE VIEW a AS SELECT * FROM other_view) have no dependency edge, so they can be ordered before the view they reference.

Fix: Change to dep_c.relkind IN ('r', 'p', 'v') and add dep_c.oid != c.oid to exclude self-references (every view's rewrite rule has a dependency on itself).

2. False-positive dependencies from other views' rewrite rules

The join path:

FROM pg_catalog.pg_depend AS d
INNER JOIN pg_catalog.pg_rewrite AS r ON d.objid = r.oid
INNER JOIN pg_catalog.pg_depend AS d2 ON r.oid = d2.objid
...
WHERE d.refobjid = c.oid

This finds rewrite rules that reference the current view (d.refobjid = c.oid), then finds what those rules depend on. But OTHER views' rewrite rules also reference this view (if they SELECT from it). This causes view A to appear to depend on view B's dependencies, creating false cycles.

Fix: Add AND r.ev_class = c.oid to the pg_rewrite join to restrict to the view's own rewrite rule only.

Reproducer

CREATE TABLE t1 (id int PRIMARY KEY, val text);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM v1;  -- v2 depends on v1

Running pg-schema-diff plan --from-dsn empty --to-dsn target:

  • Without fix: v2 may be ordered before v1 (missing dep), or cycle detected (false positive from other rules)
  • With fix: correct order t1 → v1 → v2

Related

  • #248 (function composite type ordering — different issue but same dependency-tracking gap)
Dominant language
Go
Stars
884
Forks
82
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from stripe/pg-schema-diff

All issues in stripe/pg-schema-diff

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.