fix: order multi-file dump includes by dependency, not directory (#580) - #581
Conversation
dump --multi-file emitted \i includes in a fixed directory sequence (functions before tables before views), discarding the cross-category order the diff package had already computed. A function whose signature uses a table's or view's row type was therefore included before that relation, and main.sql failed to apply with "type ... does not exist". The include order now follows each file's first appearance in the diff sequence. The one adjustment is for table files: they bundle triggers, policies, and deferred constraints that the diff emits after functions, so functions whose signature references no relation are hoisted ahead of the first table file. Functions that do use a relation's row type keep the diff's placement, after that relation. The check reuses the diff package's existing signature detection via a small exported wrapper. Fixes #580 Fixes #579 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Greptile SummaryThis PR changes multi-file dump generation so
Confidence Score: 4/5The PR is not yet safe to merge because multi-file dumps can move body-dependent functions before tables that must exist when those functions are created. The new hoisting predicate models only relation types in function signatures, while the diff's established ordering also accounts for table references in function bodies; discarding that dependency can make generated dumps fail to replay. Files Needing Attention: internal/dump/formatter.go Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
D[Topologically ordered diff steps] --> G[Group statements by object file]
G --> F[Record each file's first appearance]
F --> H{Function signature references relation?}
H -->|No| B[Hoist before first table]
H -->|Yes| K[Keep diff position]
B --> M[Write main.sql includes]
K --> M
Reviews (1): Last reviewed commit: "fix: order multi-file dump includes by d..." | Re-trigger Greptile |
…bility Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The function “hoisting” rule in multi-file ordering can override diff-intended ordering for functions that depend on relations via their bodies (not signatures), potentially reintroducing replay failures.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR fixes dump --multi-file producing a main.sql that could not be replayed due to \i include lines being ordered by fixed directory buckets instead of dependency order (notably functions/aggregates that depend on table/view composite row types).
Changes:
- Reworks multi-file dump include ordering to follow the diff package’s dependency/topological sequence, rather than a fixed directory order.
- Exposes small helper wrappers in
internal/diffto reuse existing “function signature references relation” logic from the dump formatter. - Adds an integration test to validate correct cross-category ordering and replayability of the generated multi-file output; updates docs to reflect the new behavior.
File summaries
| File | Description |
|---|---|
| internal/dump/formatter.go | Changes multi-file grouping and computes main.sql include order based on diff sequence, with a function-hoisting adjustment. |
| internal/diff/diff.go | Exports wrappers to build a relation lookup and to test whether a function signature references a relation. |
| cmd/dump/multifile_integration_test.go | Adds an integration test that asserts include ordering and replays the dumped files into an empty schema. |
| docs/workflow/modular-schema-files.mdx | Updates documentation to describe dependency-based include ordering for multi-file dumps. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…tions Reuse the diff package's full function dependency check (signature plus body, the #530 logic) for SQL-language functions, whose bodies PostgreSQL validates at creation. Other languages keep the signature-only check so plpgsql trigger functions that write to another table are not demoted below the table file that bundles their trigger. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Aggregate-to-view and SQL-function-body-to-view dependencies remain incorrectly ordered despite being included in issue #580.
Review details
Suppressed comments (1)
internal/dump/formatter.go:121
- The baseline is not dependency-ordered for two view cases described in #580.
generateCreateAggregatesSQLruns atinternal/diff/diff.go:2009before views at line 2060, andfunctionReferencesNewViewonly checks signatures, so an aggregate using a view row type—or an SQL function whose body queries a view—still appears beforeviews/<view>.sql; this formatter preserves that invalid order. Please add these relation dependencies to the diff ordering and cover both replay cases.
// Compute the include order. The diff package already emits statements in
// dependency order, so the first appearance of each file is the baseline.
- Files reviewed: 4/4 changed files
- Comments generated: 0 new
- Review effort level: Balanced
|
Re the review note on aggregate-to-view and SQL-function-body-to-view ordering: confirmed, both are real, but they are diff-package ordering bugs rather than formatter bugs. I reproduced each in single-file dump, where they fail the same way ( These will be handled in a follow-up PR in |
Summary
dump --multi-filewrote its\iincludes in a fixed directory sequence (functions/beforetables/beforeviews/), discarding the cross-category dependency order the diff package had already computed for the single-file dump. Any function whose signature uses a table's or view's row type landed before that relation, so the generatedmain.sqlfailed to apply withtype "..." does not exist.The include order now follows each file's first appearance in the diff sequence, which is already topologically ordered. One adjustment is needed: a table's triggers, policies, and deferred constraints are bundled into the table's file even though the diff emits them after functions, so functions whose signature references no relation are hoisted ahead of the first table file. Functions that do reference a relation's row type keep the diff's placement, after that relation. The relation check reuses the diff package's existing
functionSignatureReferencesRelationthrough a small exported wrapper rather than duplicating it.This also fixes the domain-with-function-CHECK case (
domains/was emitted beforefunctions/) as a side effect of following the diff order.Known gaps left for follow-up PRs, all of which also fail in single-file dump and plan today:
Addresses the multi-file include ordering in #580. The aggregate-to-view and SQL-body-to-view cases from that issue are diff-package ordering bugs and will be fixed in a follow-up PR, so #580 stays open until then.
Fixes #579
Test plan
TestDumpCommand_Issue580MultiFileIncludeOrderincmd/dump/multifile_integration_test.gocovers both dump --multi-file orders \i includes by fixed object-category buckets, not by dependency #580 variants (table row type parameter, view row type return), the type does not exist #579 shape, trigger and policy functions that must stay ahead of their tables, and a domain CHECK function. It asserts the pairwise include order and replays the multi-file output into an empty schema. Fails before the fix on three files, passes after.TestCreateMultiFileOutput,TestMultiFileIncludeOrderDeterministic,TestDumpFormatterHelpers,TestIncludeIntegration, andTestIgnore*pass.🤖 Generated with Claude Code