Skip to content

fix: constrain pg_depend lookups to the right catalog - #68

Open
DavidBoone wants to merge 1 commit into
loresoft:mainfrom
DavidBoone:pg-depend-classid
Open

fix: constrain pg_depend lookups to the right catalog#68
DavidBoone wants to merge 1 commit into
loresoft:mainfrom
DavidBoone:pg-depend-classid

Conversation

@DavidBoone

Copy link
Copy Markdown
Contributor

pg_depend.objid is only unique within the catalog named by classid, but the PostgreSQL reader matched on objid alone. Any extension member from another catalog whose oid collides with a relation's pg_class oid made the NOT EXISTS fire and silently dropped that object from the model.

Observed on a PostGIS database where four of 57 requested tables went missing. Each was excluded by a deptype 'e' row that belonged to a pg_proc or pg_operator object rather than to the table, the two oids having collided:

SELECT ns.nspname, cls.relname, cls.oid,
dep.classid::regclass, dep.deptype
FROM pg_class cls
JOIN pg_namespace ns ON ns.oid = cls.relnamespace
JOIN pg_depend dep ON dep.objid = cls.oid AND dep.deptype IN ('e', 'x');

Extensions installed or upgraded after the tables were created leave their member oids interleaved with relation oids, so the collision is ordinary rather than exotic.

Tables and views now require classid = 'pg_class' and objsubid = 0 (extension membership is recorded on the whole relation); routines require classid = 'pg_proc'. The sequence reader's identity/serial ownership probe had the same defect and is fixed alongside.

No fixture reproduces this: the collision depends on oid allocation order, which a freshly created test database cannot arrange.

pg_depend.objid is only unique within the catalog named by classid, but
the PostgreSQL reader matched on objid alone. Any extension member from
another catalog whose oid collides with a relation's pg_class oid made
the NOT EXISTS fire and silently dropped that object from the model.

Observed on a PostGIS database where four of 57 requested tables went
missing. Each was excluded by a deptype 'e' row that belonged to a
pg_proc or pg_operator object rather than to the table, the two oids
having collided:

  SELECT ns.nspname, cls.relname, cls.oid,
         dep.classid::regclass, dep.deptype
  FROM pg_class cls
  JOIN pg_namespace ns ON ns.oid = cls.relnamespace
  JOIN pg_depend dep ON dep.objid = cls.oid AND dep.deptype IN ('e', 'x');

Extensions installed or upgraded after the tables were created leave
their member oids interleaved with relation oids, so the collision is
ordinary rather than exotic.

Tables and views now require classid = 'pg_class' and objsubid = 0
(extension membership is recorded on the whole relation); routines
require classid = 'pg_proc'. The sequence reader's identity/serial
ownership probe had the same defect and is fixed alongside.

No fixture reproduces this: the collision depends on oid allocation
order, which a freshly created test database cannot arrange.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@pwelter34

Copy link
Copy Markdown
Member

@DavidBoone can you help resolve conflict? Thanks for fixes.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants