fix(pg_catalog): deterministic, stable OIDs for pooled clients (#389, #390)#391
Closed
kadosh1000 wants to merge 2 commits into
Closed
fix(pg_catalog): deterministic, stable OIDs for pooled clients (#389, #390)#391kadosh1000 wants to merge 2 commits into
kadosh1000 wants to merge 2 commits into
Conversation
pg_catalog OIDs were assigned from a per-connection AtomicU32 counter in iteration order, so the same object got a different OID on each connection. Pooled clients (DBeaver, etc.) resolve an OID on one connection and reference it on another, so lookups like `pg_class WHERE relnamespace = <oid>` returned nothing and tables/columns didn't list. Separately, pg_catalog itself received a generated OID while the static catalog rows reference the canonical namespace OID 11 (pg_type.typnamespace = 11, ...), so type<->namespace joins failed and clients couldn't resolve any column's data type. Replace the counter with stable_oid(&OidCacheKey): a deterministic hash of the object's (catalog, schema, table) name, mapped into the positive int4 user-OID range, with pg_catalog pinned to its fixed OID 11. The same object now resolves to the same OID on every connection, independent of iteration order or which catalog table is queried first. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Member
|
@kadosh1000 thanks for the quick fix. please check the lint failure. |
sunng87
self-requested a review
July 21, 2026 13:11
stable_oid() made the counter unused; drop the field, constructor param, and pass-throughs, and use a let-chain for the pg_catalog check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01La5HhazCArDHemjcZ7B4z8
Author
|
@sunng87 no problem :) lint issues fixed |
Member
|
@kadosh1000 Thank you! I'm trying to fix the same issue with another method that can reuse our oid counter mechanism. The root cause is some valid keys in oid_cache may be accidentally dropped. Let me try if I can get it fixed in that way. |
Author
Author
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
Makes
pg_catalogOID assignment deterministic and stable, fixing two problems that break pooled PostgreSQL clients (e.g. DBeaver) against a datafusion-postgres server.Closes #389 — OIDs unstable across connections.
Closes #390 —
pg_catalognamespace should be the fixed OID 11.Problem
PgCatalogSchemaProviderassigns catalog/schema/table OIDs from a per-providerAtomicU32counter, incremented in iteration order. A typical pgwire server creates a freshSessionContext+setup_pg_catalogper connection, so the same object gets a different OID on different connections. Pooled clients resolve an OID on one connection and reference it on another, sopg_class WHERE relnamespace = <oid>matches nothing and no tables are listed.Separately,
pg_catalogreceives a generated OID, but the static catalog rows this crate ships reference the canonicalPG_CATALOG_NAMESPACEOID 11 (pg_type.typnamespace = 11,pg_proc.pronamespace = 11, …). No namespace with OID 11 exists inpg_namespace, so joins from a system object to its namespace fail — e.g. DBeaver can't resolve any column's data type (every column shows as unknown).Fix
Add
stable_oid(&OidCacheKey): a deterministic hash (DefaultHasher— fixed keys, so stable across processes) of the object's(catalog, schema, table)name, mapped into the positiveint4range[16384, i32::MAX], withpg_catalogpinned to its fixed OID11. The seven counter sites inpg_class/pg_namespace/pg_database/pg_attributenow callstable_oidinstead ofoid_counter.fetch_add.The same object now resolves to the same OID on every connection, independent of iteration order or which catalog table is queried first.
Notes
oid_counterfield/params in place to keep the diff minimal — happy to remove them (and theOrderingimports) if you'd prefer.