Skip to content

pg_class OIDs collide for names sharing first 3 chars and length #93

Open

Description

@erans

The canonical table-identity OID formula reads only the first three characters and the length:

((unicode(c1)*1000000) + (unicode(c2)*10000) + (unicode(c3)*100) + (len*7)) % 1000000 + 16384

Any two relations sharing those produce one OID. Demonstrated:

Names Shared OID
orders / orderz 166426
user_roles / user_rolez 176554
customers / customerz 197947

OID is the join key from pg_class to pg_attribute, pg_index, pg_constraint, and pg_depend, so an ORM introspecting orders can receive orderz's columns.

Pre-existing, not introduced by #87. Fixing it means one canonical low-collision function shared by every view and Rust site, plus a data migration rewriting persisted OIDs in pg_constraint.conrelid, pg_index.indrelid, pg_attrdef.adrelid, and pg_depend.objid/refobjid.

Related: oid_hash (src/functions/hash_functions.rs) uses Rust's DefaultHasher, which is not guaranteed stable across Rust releases, so OIDs derived from it could change on rebuild. It should be retired in the same work.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions