]> granicus.if.org Git - postgresql/commitdiff
For foreign keys, check REFERENCES privilege only on the referenced table.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 31 Mar 2017 22:11:25 +0000 (18:11 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 31 Mar 2017 22:11:30 +0000 (18:11 -0400)
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
doc/src/sgml/ref/grant.sgml
src/backend/commands/tablecmds.c

index e1ec14e1c1bfe94cf0d895d624ab3db7d2eaa15a..121418b6ca2350e6379c2a571e023bd832dee792 100644 (file)
@@ -750,9 +750,11 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
       class="parameter">refcolumn</replaceable> list is omitted, the
       primary key of the <replaceable class="parameter">reftable</replaceable>
       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 <literal>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.
      </para>
 
      <para>
index 9fb4c2fd7e3aafa32131d8ee81c191bc2125c0ec..d7b6d5fb300320103d3e821aff788189c04738b4 100644 (file)
@@ -257,10 +257,9 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace
      <term>REFERENCES</term>
      <listitem>
       <para>
-       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
+       <xref linkend="sql-createtable"> statement.)
       </para>
      </listitem>
     </varlistentry>
@@ -351,7 +350,7 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace
        <function>currval</function> and <function>nextval</function> functions.
       </para>
       <para>
-       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 <quote>usage</quote> of the type,
        such as values of the type appearing in queries.  It only prevents
@@ -360,13 +359,13 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace
        which could prevent the owner from changing the type later.)
       </para>
       <para>
-       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.
       </para>
       <para>
-       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.
       </para>
      </listitem>
     </varlistentry>
index 4cf2efb2ad95b725489f6ea98399859ef476d375..d418d56b549ec077b3ba1f6ec00f27cb099d765c 100644 (file)
@@ -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)
 {