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;