Skip to content

structural_diff: cover the extension's own schema #94

Description

@jnasbyupgrade

Part of #93 (defect D2 there).

bin/structural_diff never compares the cat_tools schema itself — not its ACL, not its comment. Every install script runs GRANT USAGE ON SCHEMA cat_tools TO cat_tools__usage, so if an update script ever failed to preserve that, structural_diff would report the two databases identical.

Why it is missed

bin/structural_diff.sql's members CTE enumerates extension members the usual way, via pg_depend with refclassid = 'pg_extension' and deptype = 'e'.

The cat_tools schema is not a member. cat_tools.control declares schema = 'cat_tools', so the schema is created by the CREATE EXTENSION machinery rather than by the script, and PostgreSQL records the relationship in the opposite direction — the extension depends on the schema, not the schema on the extension:

classid      | objid   | refclassid   | refobjid | deptype
pg_extension | 2563251 | pg_namespace | 2563250  | n

So the members CTE, which looks for rows where the extension is the referenced object, never sees it. Note _cat_tools IS a member and IS compared — it is created by the script — which is why this went unnoticed.

Demonstration

In two databases that are otherwise identical, revoking USAGE on schema cat_tools from cat_tools__usage in one of them leaves structural_diff reporting IDENTICAL. Doing the same to the member schema _cat_tools is correctly reported:

-ACL: cat_tools__usage=U/root,root=UC/root
+ACL: root=UC/root
FAIL: structural diff between 'sch_a' and 'sch_b' …

Fix

Extend the members CTE to include the extension's own schema. Either direction works — reading extnamespace from pg_extension directly, or picking up the inverted pg_depend row shown above. The pg_depend form is the more general expression of the relationship; extnamespace is simpler. Whichever is chosen, the schema then flows through the existing per-kind rendering and gets its ACL and comment compared like any other member.

Small and self-contained — no dependency on other work under #93.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    update-safetyALTER EXTENSION UPDATE correctness: fresh-vs-updated equivalence

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions