Repository navigation
fix(postgres): read primary and foreign keys from pg_catalog - #1604
Open
dimitri-yatsenko wants to merge 1 commit into
Open
dimitri-yatsenko wants to merge 1 commit into
dimitri-yatsenko wants to merge 1 commit into
Conversation
PostgreSQL's `information_schema.table_constraints` lists only constraints on tables the current user owns or holds a privilege other than SELECT on. A login with only SELECT therefore saw no primary key on any table: `Table.primary_key` was empty, `parents(primary=True)` returned nothing so `key_source` raised, and `len()` built `count(DISTINCT )`. MySQL was unaffected. The keys are now read from `pg_constraint` and `pg_attribute`, which every login can read, the same way `load_foreign_keys_sql` already did: - `get_primary_key_sql` (the heading, `Table.primary_key`) and `load_primary_keys_sql` (the dependency graph) select `contype = 'p'`, ordered by position within the constraint -- the same column order `information_schema` reported. - `get_foreign_keys_sql` had the same problem, worse: `constraint_column_usage` shows only tables the user owns. It also joined the two column lists on constraint name alone, so a multi-column foreign key came back as a cross product of its columns. It now returns one row per foreign-key column, pairing each with the column it references, as the MySQL adapter does. Nothing in the library calls it today; output column names are unchanged. The new integration test creates a SELECT-only login on each backend and checks that primary keys, headings, parents and children, the dependency graph, `key_source`, and `get_foreign_keys_sql` all match what the owner sees. Against the previous code all five PostgreSQL cases fail; MySQL passed before and after. Closes #1554.
dimitri-yatsenko
requested review from
MilagrosMarin,
lum-agilyti and
ttngu207
October 17, 2026 22:02
This branch has not been deployed
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.
PostgreSQL's
information_schema.table_constraintslists only constraints on tables the current user owns or holds a privilege other than SELECT on. A login with only SELECT therefore saw no primary key on any table:Table.primary_keywas empty,parents(primary=True)returned nothing sokey_sourceraised, andlen()builtcount(DISTINCT ). MySQL was unaffected.The keys are now read from
pg_constraintandpg_attribute, which every login can read, the same wayload_foreign_keys_sqlalready did:get_primary_key_sql(the heading,Table.primary_key) andload_primary_keys_sql(the dependency graph) selectcontype = 'p', ordered by position within the constraint -- the same column orderinformation_schemareported.get_foreign_keys_sqlhad the same problem, worse:constraint_column_usageshows only tables the user owns. It also joined the two column lists on constraint name alone, so a multi-column foreign key came back as a cross product of its columns. It now returns one row per foreign-key column, pairing each with the column it references, as the MySQL adapter does. Nothing in the library calls it today; output column names are unchanged.The new integration test creates a SELECT-only login on each backend and checks that primary keys, headings, parents and children, the dependency graph,
key_source, andget_foreign_keys_sqlall match what the owner sees. Against the previous code all five PostgreSQL cases fail; MySQL passed before and after.Closes #1554.