diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index fc03a349f0..090258aea4 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -1318,16 +1318,16 @@ CREATE TABLE posts (
A foreign key must reference columns that either are a primary key or
- form a unique constraint. This means that the referenced columns always
- have an index (the one underlying the primary key or unique constraint);
- so checks on whether a referencing row has a match will be efficient.
- Since a DELETE of a row from the referenced table
- or an UPDATE of a referenced column will require
- a scan of the referencing table for rows matching the old value, it
- is often a good idea to index the referencing columns too. Because this
- is not always needed, and there are many choices available on how
- to index, declaration of a foreign key constraint does not
- automatically create an index on the referencing columns.
+ form a unique constraint, or are columns from a non-partial unique index.
+ This means that the referenced columns always have an index to allow
+ efficient lookups on whether a referencing row has a match. Since a
+ DELETE of a row from the referenced table or an
+ UPDATE of a referenced column will require a scan of
+ the referencing table for rows matching the old value, it is often a good
+ idea to index the referencing columns too. Because this is not always
+ needed, and there are many choices available on how to index, declaration
+ of a foreign key constraint does not automatically create an index on the
+ referencing columns.
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 079af9126a..2b43be605e 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -1165,10 +1165,11 @@ WITH ( MODULUS numeric_literal, REM
column(s) of some row of the referenced table. If the 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. The user
- must have REFERENCES permission on the referenced table
- (either the whole table, or the specific referenced columns). The
+ is used. Otherwise the refcolumn
+ list must refer to the columns of a non-deferrable unique or primary key
+ constraint or be the columns of a non-partial unique index. The user
+ must have REFERENCES permission on the referenced
+ table (either the whole table, or the specific referenced columns). The
addition of a foreign key constraint requires a
SHARE ROW EXCLUSIVE lock on the referenced table.
Note that foreign key constraints cannot be defined between temporary
@@ -2305,13 +2306,19 @@ CREATE TABLE cities_partdef
- Foreign-Key Constraint Actions
+ Foreign-Key Constraints
The ability to specify column lists in the foreign-key actions
SET DEFAULT and SET NULL is a
PostgreSQL extension.
+
+
+ It is a PostgreSQL extension that a
+ foreign key constraint may reference columns of a unique index instead of
+ columns of a primary key or unique constraint.
+
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 68f658e834..9f51696740 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -12117,15 +12117,19 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
/*
* transformFkeyCheckAttrs -
*
- * Make sure that the attributes of a referenced table belong to a unique
- * (or primary key) constraint. Return the OID of the index supporting
- * the constraint, as well as the opclasses associated with the index
- * columns.
+ * Validate that the 'attnums' columns in the 'pkrel' relation are valid to
+ * reference as part of a foreign key constraint.
+ *
+ * Returns the OID of the unique index supporting the constraint and
+ * populates the caller-provided 'opclasses' array with the opclasses
+ * associated with the index columns.
+ *
+ * Raises an ERROR on validation failure.
*/
static Oid
transformFkeyCheckAttrs(Relation pkrel,
int numattrs, int16 *attnums,
- Oid *opclasses) /* output parameter */
+ Oid *opclasses)
{
Oid indexoid = InvalidOid;
bool found = false;