Hi John,
 
Please find answers below.
 
20.07.2020, 17:44, "J Lumby" <johnlumby@hotmail.com>:

This has come up before elsewhere e.g.

https://stackoverflow.com/questions/26034752/postgresql-inheritance-and-foreign-key-referencing-parent-table

but I don't see any mention in any pg mailing list.


postgresql permits creation of a foreign key referencing a table which
is the parent of child tables via inheritance

but enforces that every foreign key value must exist as pkey ONLY in the
parent  -  it throws an ERROR otherwise, even if the pkey exists in a
child table.

Having of primary key on child table with the same columns doesn't mean that it guarantees uniqueness of a record among parent and child tables. Each primary key provides uniqueness of records only in the table on which they are created.


This is problematic (to me) for three slightly different reasons :

1)   it is surprising.    The expectation is that a reference to
accessing row(s) in a parent table will also search all children,   as
with SELECT,  unless the ONLY keyword is specified.

which then leads to ...


The answer above is also valid here :)



2)    it is inconsistent with,  and less useful than,    the somewhat
similar CHECK clause in a CREATE/ALTER TABLE :

_____________________________________________________

          CHECK ( expression ) [ NO INHERIT ]

A constraint marked with NO INHERIT will not propagate to child tables.

_____________________________________________________

For CHECK,   the default is propagation to child tables unless
explicitly prevented,  which is consistent with SELECT and the ONLY
qualifier.

For FOREIGN KEY there is no optional qualifier to express "propagation" 
(i.e. propagation of the search for primary key) or "ONLY" and the
behaviour is always "ONLY".


3)   I am probably wrong but as far as I can tell this behaviour is not
documented anywhere.

https://www.postgresql.org/docs/12/ddl-inherit.html#DDL-INHERIT-CAVEATS
https://www.postgresql.org/docs/12/ddl-partitioning.html  - Title 5.11.3.3. Caveats



Would there be any interest in providing a choice,   e.g. an optional  [
INHERIT ] on the REFERENCES clause,  in a future release?

 
The most important part is why you need to use foreign key referencing to parent table of inheritance. Depending on your answer, there are multiple solution. For example, if the reason why you need it is that you use table partitioning implemented by using triggers and table inheritance, such as in the document below[1], you can switch declarative partitioning with PostgreSQL 12. PostgreSQL 12 supports foreign keys referencing to partitioned tables. [2]
 
[1]: https://www.postgresql.org/docs/12/ddl-partitioning.html#DDL-PARTITIONING-IMPLEMENTATION-INHERITANCE
[2]: https://www.postgresql.org/docs/12/sql-createtable.html
If table partitioning is not the reason, the most generalized solution can be to use constraint triggers[3] rather than foreign keys. And you can guarantee uniqueness of records among parent and child tables by using check constraints and primary key/unique key constraints together.
 
[3]: https://www.postgresql.org/docs/12/sql-createtrigger.html
 


Cheers,  John

 

Best regards.
Samed YILDIRIM