mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Improve comments about why SET DEFAULT triggers must recheck for matches.
I was confused about this, so try to make it clearer for the next person. (This seems like a fairly inefficient way of dealing with a corner case, but I don't have a better idea offhand. Maybe if there were a way to turn off the RI_FKey_keyequal_upd_fk event filter temporarily?)
This commit is contained in:
@ -2227,12 +2227,16 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
||||
heap_close(fk_rel, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
* In the case we delete the row who's key is equal to the default
|
||||
* values AND a referencing row in the foreign key table exists,
|
||||
* we would just have updated it to the same values. We need to do
|
||||
* another lookup now and in case a reference exists, abort the
|
||||
* operation. That is already implemented in the NO ACTION
|
||||
* trigger.
|
||||
* If we just deleted the PK row whose key was equal to the FK
|
||||
* columns' default values, and a referencing row exists in the FK
|
||||
* table, we would have updated that row to the same values it
|
||||
* already had --- and RI_FKey_keyequal_upd_fk would therefore
|
||||
* believe no check is necessary. So we need to do another lookup
|
||||
* now and in case a reference still exists, abort the operation.
|
||||
* That is already implemented in the NO ACTION trigger, so just
|
||||
* run it. (This recheck is only needed in the SET DEFAULT case,
|
||||
* since CASCADE would remove such rows, while SET NULL is certain
|
||||
* to result in rows that satisfy the FK constraint.)
|
||||
*/
|
||||
RI_FKey_noaction_del(fcinfo);
|
||||
|
||||
@ -2420,12 +2424,16 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
||||
heap_close(fk_rel, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
* In the case we updated the row who's key was equal to the
|
||||
* default values AND a referencing row in the foreign key table
|
||||
* exists, we would just have updated it to the same values. We
|
||||
* need to do another lookup now and in case a reference exists,
|
||||
* abort the operation. That is already implemented in the NO
|
||||
* ACTION trigger.
|
||||
* If we just updated the PK row whose key was equal to the FK
|
||||
* columns' default values, and a referencing row exists in the FK
|
||||
* table, we would have updated that row to the same values it
|
||||
* already had --- and RI_FKey_keyequal_upd_fk would therefore
|
||||
* believe no check is necessary. So we need to do another lookup
|
||||
* now and in case a reference still exists, abort the operation.
|
||||
* That is already implemented in the NO ACTION trigger, so just
|
||||
* run it. (This recheck is only needed in the SET DEFAULT case,
|
||||
* since CASCADE must change the FK key values, while SET NULL is
|
||||
* certain to result in rows that satisfy the FK constraint.)
|
||||
*/
|
||||
RI_FKey_noaction_upd(fcinfo);
|
||||
|
||||
|
Reference in New Issue
Block a user