]> granicus.if.org Git - postgresql/commitdiff
Improve comments about why SET DEFAULT triggers must recheck for matches.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 19 Jun 2012 02:45:07 +0000 (22:45 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 19 Jun 2012 02:45:07 +0000 (22:45 -0400)
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?)

src/backend/utils/adt/ri_triggers.c

index 5b439aab6fb3126cd3cc6dc6d8129d56b22a70e2..2fb060b4779ea76d2f217224395a9981c7ae1bb7 100644 (file)
@@ -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);