OSDN Git Service

Add some notes about why it's not a bug that RI_FKey_check calls
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 27 Aug 2006 21:41:21 +0000 (21:41 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 27 Aug 2006 21:41:21 +0000 (21:41 +0000)
HeapTupleSatisfiesItself without doing LockBuffer first.  This code
is a bit fragile, but AFAICS it's not actually broken.

src/backend/utils/adt/ri_triggers.c

index 21ae21d..b58b99d 100644 (file)
@@ -17,7 +17,7 @@
  *
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.87 2006/08/21 19:15:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.88 2006/08/27 21:41:21 tgl Exp $
  *
  * ----------
  */
@@ -212,9 +212,19 @@ RI_FKey_check(PG_FUNCTION_ARGS)
        }
 
        /*
-        * We should not even consider checking the row if it is no longer valid
-        * since it was either deleted (doesn't matter) or updated (in which case
-        * it'll be checked with its final values).
+        * We should not even consider checking the row if it is no longer valid,
+        * since it was either deleted (so the deferred check should be skipped)
+        * or updated (in which case only the latest version of the row should
+        * be checked).  Test its liveness with HeapTupleSatisfiesItself.
+        *
+        * NOTE: The normal coding rule is that one must acquire the buffer
+        * content lock to call HeapTupleSatisfiesFOO.  We can skip that here
+        * because we know that AfterTriggerExecute just fetched the tuple
+        * successfully, so there cannot be a VACUUM compaction in progress
+        * on the page (either heap_fetch would have waited for the VACUUM,
+        * or the VACUUM's LockBufferForCleanup would be waiting for us to drop
+        * pin).  And since this is a row inserted by our open transaction,
+        * no one else can be entitled to change its xmin/xmax.
         */
        Assert(new_row_buf != InvalidBuffer);
        if (!HeapTupleSatisfiesItself(new_row->t_data, new_row_buf))