Conversation
PostgreSQL validates a routine's body at CREATE time, resolving the relations, composite types, domains and so on that the body names. It records none of those body references in pg_depend, so a plan cannot order them: a plan that creates a relation and a routine whose body names that relation's row type failed validation. Disable the check for the plan's session, exactly as pg_dump does when it emits `SET check_function_bodies = false` at the start of a dump. Covered in the three places a plan runs: plan validation against the temporary database, the `apply` command, and the SQL script the `plan` command prints.
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 plan now runs with
check_function_bodiesdisabled, in all three places a plan executes:executeStatementsIgnoreTimeouts, which also seeds the temporary database);applycommand;plancommand prints, which starts withSET check_function_bodies = false;.Why
PostgreSQL validates a routine's body at
CREATEtime: the body validator resolves the relations, composite types, domains and so on that the body names. None of those body references are recorded inpg_depend— verified directly:So a plan cannot order them, and one that creates a relation and a routine whose body names that relation failed validation:
This is exactly why
pg_dumpemitsSET check_function_bodies = falseat the start of a dump, and the same reasoning applies here. Ordering the routine after every relation instead is not an option: it closes a cycle whenever a domain'sCHECKcalls the routine while a table column is typed with that domain (routine → table → domain → routine).The declarative DDL schema source keeps the check on: there the file order is the author's, so a bad body reference is theirs to see.
Validation
go test ./...New acceptance case: a plpgsql function whose body declares a variable of a table row type, with the table created in the same plan. The plan orders the function first, as it must — the body reference is untrackable — and applies because the session has the check disabled. The
plancommand's golden SQL output asserts the new preamble.