Use SPI for RI checks whose FK values need a cast function

When the FK column's type needs a cast function to reach the equality
operator's input type, the RI fast path calls that function directly.
The SPI path instead applies the cast as an expression in its query,
which takes care of the function's declared arguments, its input
collation, a NULL result, volatility, and replanning when the function
changes.  The direct call doesn't cover all of that; for example, a
NULL result raises an internal error rather than a foreign key
violation, and if the cast's function is dropped and replaced, later
checks fail with "cache lookup failed for function".  Coercions that
aren't a call to one function, array coercion and coercion via I/O,
fail outright with "no conversion function".

Rather than replicate expression evaluation, leave FK values that
aren't binary-coercible to the operator's input type to SPI.  The fast
path keeps handling cross-type operators, domains and binary-compatible
types.  As eligibility now depends on pg_cast, invalidate cached
constraint information on pg_cast changes too.

Because the check needs catalog lookups, it is made in
ri_check_fastpath_index(), which caches its result in fastpath_state
until the constraint's cached information is invalidated, rather than
for every row in ri_fastpath_is_applicable().

The two tests that used a cast function to exercise fast-path code that
still exists (metadata invalidation and the active snapshot) now use
the equality function of a custom opclass, the only user code a
fast-path check still runs.

The fast-path code that calls cast functions is now unused; the next
commit removes it.

Reported-by: Nikolay Samokhvalov <[email protected]>
Reported-by: Amit Langote <[email protected]>
Reviewed-by: Matheus Alcantara <[email protected]>
Discussion: 
https://postgr.es/m/cam527d9bgpjeooymbcbtd57r145qhck-dzw9qnq+nordq1j...@mail.gmail.com
Backpatch-through: 19

Branch
------
REL_19_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/a18d2bfc1d339a5b52754f23a168475657571837

Modified Files
--------------
src/backend/utils/adt/ri_triggers.c       |  70 +++++++--
src/test/regress/expected/foreign_key.out | 239 ++++++++++++++++++++----------
src/test/regress/sql/foreign_key.sql      | 228 +++++++++++++++++++---------
3 files changed, 372 insertions(+), 165 deletions(-)

Reply via email to