Наразі закордонні ключові обмеження реалізуються за допомогою спеціальних внутрішніх механізмів. Усі вони запущені FOR EACH ROW.
Зауважте, що це деталі реалізації, які можуть змінюватися, тому не покладайтеся на них. Але основи не змінилися за останні пару основних версій, тому серйозні зміни навряд чи.
Я провів швидкий тест із простим обмеженням ФК від tblдо tbltype. Простий FK реалізований з чотирма простими внутрішніми тригерами FOR EACH ROWв моєму тесті на сторінці 9.4.
Ось короткий пробіг про те, як розслідувати:
SELECT oid -- 74791
FROM pg_constraint
WHERE conrelid = 'tbl'::regclass
AND contype = 'f';
SELECT objid, classid::regclass -- 74792,74793,74794,74795 / 'pg_trigger'
FROM pg_depend
WHERE refobjid = 74791
AND deptype = 'i'
SELECT tgrelid::regclass, tgname, tgfoid, tgtype FROM pg_trigger
WHERE oid IN (74792,74793,74794,74795) ORDER BY tgfoid;
'tbl' ;'RI_ConstraintTrigger_c_74794';1644;5
'tbl' ;'RI_ConstraintTrigger_c_74795';1645;17
'tbltype';'RI_ConstraintTrigger_a_74792';1654;9
'tbltype';'RI_ConstraintTrigger_a_74793';1655;17
SELECT oid, proname FROM pg_proc
WHERE oid IN (1654,1655,1644,1645);
1644;'RI_FKey_check_ins'
1645;'RI_FKey_check_upd'
1654;'RI_FKey_noaction_del'
1655;'RI_FKey_noaction_upd'
Два внутрішніх "бездіяльності" спрацьовує tbltype.
Увімкнено два внутрішні тригери "перевірки" tbl.
Усі вони запускаються FOR EACH ROW, як зазначено непарними номерами в tgtype.
2 байти Postgres tgtype smallintпредставляють int16вихідний код С, де кодується найменш значущий біт TRIGGER_TYPE_ROW. Детальне пояснення тут:
Ви можете легко протестувати це за допомогою пари однакових тригерів, де ви лише змінюєте FOR ROW/ STATEMENT...