Summary
First, thank you for maintaining pgschema.
The fix from #316 appears not to cover the plan-time temporary-schema path completely. With pgschema v1.12.0, a view that calls an extension function can still produce the same CREATE OR REPLACE VIEW modification on every plan, even after the plan has been applied.
This looks closely related to #314, but it is still reproducible when the desired schema is inspected through the temporary plan schema.
Environment
- pgschema: v1.12.0
- PostgreSQL: 17.x
- Extension:
ltree installed in public
- Desired state validation: temporary plan schema (
pgschema_tmp_*)
Minimal example
Desired schema:
CREATE EXTENSION IF NOT EXISTS ltree;
CREATE OR REPLACE VIEW categories_valid AS
SELECT id
FROM categories
WHERE nlevel(path) = 8;
After applying the generated plan, a subsequent plan still reports a view modification whose effective difference is:
- nlevel(path)
+ public.nlevel(path)
Applying that modification does not make the next plan converge.
What may be happening
From reading the v1.12.0 code, normalizeView() strips qualifiers using view.Schema:
view.Definition = StripSchemaPrefixFromBody(view.Definition, view.Schema)
For the desired state, however, view.Schema is still pgschema_tmp_* at that point. Since nlevel belongs to the public extension schema, public.nlevel(...) is not considered a same-schema reference and remains qualified.
Later, normalizeSchemaNames() changes the view schema from the temporary schema to public, but the view definition only receives replaceString():
view.Schema = toSchema
view.Definition = replaceString(view.Definition)
Unlike column expressions, policy expressions, and trigger conditions, the view definition does not appear to receive stripQualifiers() after the temporary schema is normalized. This seems to leave the comparison as:
current: nlevel(path)
desired: public.nlevel(path)
Expected behavior
Same-schema qualification of an extension function should not cause a repeated view diff, and a second plan after apply should report no changes.
Possible direction
Would it make sense to apply the same post-normalizeSchemaNames() qualifier stripping to view definitions, for example:
view.Definition = stripQualifiers(replaceString(view.Definition))
A regression test that exercises the actual temporary-schema path with an extension function in public may also help, since the unit test added in #316 starts with both the view schema and function qualifier already set to public.
I’d also be open to contributing a pull request if that would be useful, but I’m equally happy for this to be handled in whatever way works best for the project. Thank you for taking a look.
Summary
First, thank you for maintaining pgschema.
The fix from #316 appears not to cover the plan-time temporary-schema path completely. With pgschema v1.12.0, a view that calls an extension function can still produce the same
CREATE OR REPLACE VIEWmodification on everyplan, even after the plan has been applied.This looks closely related to #314, but it is still reproducible when the desired schema is inspected through the temporary plan schema.
Environment
ltreeinstalled inpublicpgschema_tmp_*)Minimal example
Desired schema:
After applying the generated plan, a subsequent
planstill reports a view modification whose effective difference is:Applying that modification does not make the next plan converge.
What may be happening
From reading the v1.12.0 code,
normalizeView()strips qualifiers usingview.Schema:For the desired state, however,
view.Schemais stillpgschema_tmp_*at that point. Sincenlevelbelongs to thepublicextension schema,public.nlevel(...)is not considered a same-schema reference and remains qualified.Later,
normalizeSchemaNames()changes the view schema from the temporary schema topublic, but the view definition only receivesreplaceString():Unlike column expressions, policy expressions, and trigger conditions, the view definition does not appear to receive
stripQualifiers()after the temporary schema is normalized. This seems to leave the comparison as:Expected behavior
Same-schema qualification of an extension function should not cause a repeated view diff, and a second plan after apply should report no changes.
Possible direction
Would it make sense to apply the same post-
normalizeSchemaNames()qualifier stripping to view definitions, for example:A regression test that exercises the actual temporary-schema path with an extension function in
publicmay also help, since the unit test added in #316 starts with both the view schema and function qualifier already set topublic.I’d also be open to contributing a pull request if that would be useful, but I’m equally happy for this to be handled in whatever way works best for the project. Thank you for taking a look.