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(-)
