From: Tom Lane Date: Tue, 19 Jun 2012 02:45:07 +0000 (-0400) Subject: Improve comments about why SET DEFAULT triggers must recheck for matches. X-Git-Tag: REL9_3_BETA1~1327 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=48756be9cf31c37a936eecff051bf143d5866551;p=postgresql 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?) --- diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 5b439aab6f..2fb060b477 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -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);