planner/lint: classify column and table renames as app-breaking - #19
Merged
Conversation
PostgreSQL executes RENAME COLUMN as a metadata-only catalog flip, but the rename cannot land atomically across running application instances: code still referencing the old name breaks the instant it commits. The planner now carries a dedicated app-breaking-rename reason (route stays native) and lint surfaces it as a warning recommending expand/contract: add, dual-write/backfill, switch reads, drop separately. The declarative differ already refuses to guess renames; a regression test pins the drop+add shape.
A table rename has the same pod-atomicity hazard as a column rename: running code queries the old table name and breaks the instant the flip commits. Spirit's unsafe linter passes table renames because they lose no data — data loss is our separate destructive code, so the app-compatibility warning applies here too. Index renames stay metadata-only: SQL never references an index by name.
Kiran01bm
marked this pull request as ready for review
August 11, 2026 21:53
Kiran01bm
requested review from
JashLal,
aparajon,
eeSeeGee,
jayjanssen,
jemiahw and
morgo
as code owners
August 11, 2026 21:53
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
* origin/main: testutil: gate Ministack harness behind build tag, demote CI job to signal vision: claim only what standalone use enforces today ci: make docs-only detection honor its exclusion patterns docs: reword README from research notes to decided outcomes ci: run the test matrix against one long-lived database Tighten the diffplan library seam per PR #20 API review Export the declarative diff→plan pipeline as pkg/diffplan Add pkg/executor native CREATE INDEX CONCURRENTLY with fail-closed recovery Add pkg/suggest: advisory safer-form rewrites with typed caveats Clarify safer rewrites are safer forms, not semantic equivalents testutil: control-plane error contract and rotation-seam tests testutil: AWS-boundary test tier via Ministack RDS/Aurora vision: standalone CLI use is a supported front door
morgo
approved these changes
Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A direct
RENAME COLUMN/RENAME TOpreviously classified asmetadata-onlyand lint passed it clean — mechanically true for PostgreSQL, but a rename cannot land atomically across running application instances: code still referencing the old name breaks the instant it commits. This PR gives renames their own typed classification so lint and plan consumers can steer to a safe sequence.What
app-breaking-renamefor column and table renames; the route staysnative— the engine still executes the rename when asked.app-breaking-rename, derived from the classifier (single-rulebook: the linter adds severity and presentation, never a second opinion). Nosuggestionarray — the safe sequence involves application work the engine cannot construct SQL for.metadata-only: SQL never references an index by name.Why
The safe path for a column rename is expand/contract — add the new column, dual-write and backfill, switch reads, then drop the old column as its own reviewed change. For a table rename, the rename must be coordinated with the application deploy that adopts the new name. Machine consumers (CI, orchestrator adapters) branch on the typed code; humans get the remedy in the report docs.
Severity is warning, not error: this repo's lint contract defines error as "the engine would refuse", and the engine executes renames (per the LLD: simple, unambiguous non-PK renames are allowed). Spirit flags column renames as an error but passes table renames because its unsafe linter is scoped to data loss — data loss is this repo's separate
destructivecode, so the app-compatibility warning applies to both rename kinds here.Before / after