Repository navigation
fix: recreate dependent views around a function DROP + CREATE (#601) - #619
Conversation
A function change that CREATE OR REPLACE cannot apply (return type, parameter names, OUT parameters) is planned as DROP FUNCTION + CREATE FUNCTION. Views calling the function were left out of the plan, so the drop failed with SQLSTATE 2BP01. Views whose live definition calls such a function now go through the recreate cycle: the views (and their transitive dependents) are dropped, the function is recreated, and the modify-views phase creates the views again with comments, indexes, triggers and grants. New views calling the function are held until it has been recreated so they do not bind to the old one. A view that is both marked for recreation and a dependent of another recreated view is now rebuilt once, after the view it reads. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The dependency ordering fix is coherent and covered by a focused end-to-end regression fixture.
Review effort: Balanced
Findings: None
What changed in this PR
Fixes function recreation when existing or newly added views depend on the function, ensuring dependency-safe ordering and restoration of associated view metadata.
Changes:
- Detects views that call functions requiring
DROP+CREATE. - Pre-drops calling views and transitive dependents, then recreates them in dependency order.
- Adds regression fixtures covering regular/materialized/stacked/new views, comments, grants, and indexes.
| File | Description |
|---|---|
internal/diff/diff.go |
Detects function-dependent views and coordinates recreation ordering. |
internal/diff/view.go |
Prevents duplicate recreation of dependent views. |
testdata/diff/dependency/issue_601_function_recreate_dependent_view/old.sql |
Defines the source regression schema. |
testdata/diff/dependency/issue_601_function_recreate_dependent_view/new.sql |
Defines the desired regression schema. |
testdata/diff/dependency/issue_601_function_recreate_dependent_view/diff.sql |
Records expected migration DDL. |
testdata/diff/dependency/issue_601_function_recreate_dependent_view/plan.sql |
Records expected SQL plan output. |
testdata/diff/dependency/issue_601_function_recreate_dependent_view/plan.json |
Records expected JSON plan output. |
testdata/diff/dependency/issue_601_function_recreate_dependent_view/plan.txt |
Records expected text plan output. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
) A modified view whose desired definition newly calls a function being dropped and created again was updated first, bound to the old function, and blocked its drop. Consider the desired definition of modified views when deciding which recreated functions run ahead of the views. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Summary
A function change that
CREATE OR REPLACEcannot apply (return type, parameter names, OUT parameters) is planned asDROP FUNCTION+CREATE FUNCTION(#326). Views calling that function were absent from the plan — their definition text is identical on both sides — so apply failed withcannot drop function ... because other objects depend on it (SQLSTATE 2BP01).Changes in
internal/diff:RequiresRecreate, alongside the existing recreated-column trigger from GENERATED ALWAYS AS expression changes are ignored by plan #591. This also routes it through the existing privilege/comment/index/trigger restoration for recreated views.preDropViewsWithDependents), the function is dropped and created, then modify-views emits only theCREATEs. Other modified functions keep their current position.CREATEwas emitted twice, the first possibly before its base view was back.No
CASCADEis used; all drops stayRESTRICT.Known limitation (unchanged, not in scope): other dependents of a recreated function — column defaults, CHECK constraints, generated columns, expression indexes, policies — are still not handled. Matching is by function name, so an overload of a recreated function can cause a redundant view recreation.
Fixes #601
Test plan
New case
testdata/diff/dependency/issue_601_function_recreate_dependent_viewcovering: an unchanged view with comment + grant, a stacked view that also calls the function, a materialized view with an index, a newly added view calling the function, and a recreated function with no dependents (stays on the old path).Confirmed red before the fix (apply failed with 2BP01). Also ran locally: full
./internal/diff, andTestPlanAndApplyfordependency/,create_function/,create_view/,create_materialized_view/.🤖 Generated with Claude Code