From 64d4da511c012faff8ac309595620938a43c6817 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 31 Mar 2017 18:11:25 -0400 Subject: [PATCH] For foreign keys, check REFERENCES privilege only on the referenced table. We were requiring that the user have REFERENCES permission on both the referenced and referencing tables --- but this doesn't seem to have any support in the SQL standard, which says only that you need REFERENCES permission on the referenced table. And ALTER TABLE ADD FOREIGN KEY has already checked that you own the referencing table, so the check could only fail if a table owner has revoked his own REFERENCES permission. Moreover, the symmetric interpretation of this permission is unintuitive and confusing, as per complaint from Paul Jungwirth. So let's drop the referencing-side check. In passing, do a bit of wordsmithing on the GRANT reference page so that all the privilege types are described in similar fashion. Discussion: https://postgr.es/m/8940.1490906755@sss.pgh.pa.us --- doc/src/sgml/ref/create_table.sgml | 8 +++++--- doc/src/sgml/ref/grant.sgml | 19 +++++++++---------- src/backend/commands/tablecmds.c | 8 ++++++-- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e1ec14e1c1..121418b6ca 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -750,9 +750,11 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI class="parameter">refcolumn list is omitted, the primary key of the reftable is used. The referenced columns must be the columns of a non-deferrable - unique or primary key constraint in the referenced table. Note that - foreign key constraints cannot be defined between temporary tables and - permanent tables. + unique or primary key constraint in the referenced table. The user + must have REFERENCES permission on the referenced table + (either the whole table, or the specific referenced columns). + Note that foreign key constraints cannot be defined between temporary + tables and permanent tables. diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index 9fb4c2fd7e..d7b6d5fb30 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -257,10 +257,9 @@ GRANT role_name [, ...] TO REFERENCES - To create a foreign key constraint, it is - necessary to have this privilege on both the referencing and - referenced columns. The privilege may be granted for all columns - of a table, or just specific columns. + Allows creation of a foreign key constraint referencing the specified + table, or specified column(s) of the table. (See the + statement.) @@ -351,7 +350,7 @@ GRANT role_name [, ...] TO currval and nextval functions. - For types and domains, this privilege allow the use of the type or + For types and domains, this privilege allows the use of the type or domain in the creation of tables, functions, and other schema objects. (Note that it does not control general usage of the type, such as values of the type appearing in queries. It only prevents @@ -360,13 +359,13 @@ GRANT role_name [, ...] TO - For foreign-data wrappers, this privilege enables the grantee - to create new servers using that foreign-data wrapper. + For foreign-data wrappers, this privilege allows creation of + new servers using the foreign-data wrapper. - For servers, this privilege enables the grantee to create foreign - tables using the server, and also to create, alter, or drop their own - user's user mappings associated with that server. + For servers, this privilege allows creation of foreign tables using + the server. Grantees may also create, alter, or drop their own + user mappings associated with that server. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 4cf2efb2ad..d418d56b54 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -6817,7 +6817,6 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, * Now we can check permissions. */ checkFkeyPermissions(pkrel, pkattnum, numpks); - checkFkeyPermissions(rel, fkattnum, numfks); /* * Look up the equality operators to use in the constraint. @@ -7745,7 +7744,12 @@ findFkeyCast(Oid targetTypeId, Oid sourceTypeId, Oid *funcid) return ret; } -/* Permissions checks for ADD FOREIGN KEY */ +/* + * Permissions checks on the referenced table for ADD FOREIGN KEY + * + * Note: we have already checked that the user owns the referencing table, + * else we'd have failed much earlier; no additional checks are needed for it. + */ static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts) {