Repository navigation
Schema change: renaming a table keeps the old name working as a view - #6
Merged
Merged
Conversation
…ach table After a run the catalog is compared with the views each table should have, so a compatibility view left by a rename is expected and a view nobody planned is reported.
For an existing table, one step renames it and creates a view under the old name in the same transaction, with the table's SELECT, INSERT, UPDATE and DELETE grants copied onto the view. From PostgreSQL 15 the view runs with the caller's own rights (security_invoker); before that a table with row-level security is refused, because the view would run as its owner. An optional contract step drops the view later, and the undo puts the table's name back. Later steps in the plan know the view depends on the columns. The catalog now reads each table's privileges and whether row-level security is on. compatViews (default on) turns it off.
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.
What changed
A table rename used to break every query using the old name the moment it ran (the step was flagged "breaks callers"). For an existing table it now takes one step that renames the table and creates a view under the old name in the same transaction, so applications keep working until they have switched. A second step, not run by default, drops the old name later; the undo drops the view and renames the table back.
compatViews(default on) turns it off; a table the plan itself creates is renamed directly.Things a compatibility view could get wrong, and how each is handled:
GRANTstatements (the owner's own are skipped). Grants a view cannot hold (TRUNCATE and so on) and column-level grants are not copied, and the step's notes say so.WITH (security_invoker = true), so the caller's own rights and policies apply as before.The catalog now reads each table's privileges and whether row-level security is on. The expected state compared after a run includes the views each table should have.
How it was checked
rename.test.ts); the repo suite passes (1,743 tests) and both type-checks are clean.renamesection inscripts/schema-change-pg16.tsruns the rename with real roles: a role with the old grants still reads and writes through the old name (sequence and constant defaults applied), a read-only role still cannot write, a foreign key from another table follows the renamed table, the catalog matches the compiler's expected state, later changes to a listed column are refused, the contract step removes the old name, and the undo puts the table back. From 15 a caller still sees only the rows its policy allows through the old name; before 15 the row-level-security case is refused. All 15 sections of that script pass on every version.Reviewer notes
scripts/schema-change-pg16.tsandscripts/lib/are still not in the repository, so the scenarios above ran from a local copy.