Index: src/backend/commands/trigger.c
===================================================================
RCS file: /home/affan/repos/cvs/pgsql/pgsql/src/backend/commands/trigger.c,v
retrieving revision 1.215
diff -p -c -b -r1.215 trigger.c
*** src/backend/commands/trigger.c	1 Jul 2007 17:45:42 -0000	1.215
--- src/backend/commands/trigger.c	13 Jul 2007 20:13:13 -0000
*************** AfterTriggerSaveEvent(ResultRelInfo *rel
*** 3389,3403 ****
  					 * Update on FK table
  					 *
  					 * There is one exception when updating FK tables: if the
! 					 * updated row was inserted by our own transaction and the
! 					 * FK is deferred, we still need to fire the trigger. This
! 					 * is because our UPDATE will invalidate the INSERT so the
! 					 * end-of-transaction INSERT RI trigger will not do
! 					 * anything, so we have to do the check for the UPDATE
! 					 * anyway.
  					 */
! 					if (HeapTupleHeaderGetXmin(oldtup->t_data) !=
! 						GetCurrentTransactionId() &&
  						RI_FKey_keyequal_upd_fk(trigger, rel, oldtup, newtup))
  					{
  						continue;
--- 3389,3404 ----
  					 * Update on FK table
  					 *
  					 * There is one exception when updating FK tables: if the
! 					 * updated row was inserted by "current" transaction (any
! 					 * active or sub-committed xact from the local transaction
! 					 * tree) and the FK is deferred, we still need to fire the
! 					 * trigger.  This is because our UPDATE will invalidate the
! 					 * INSERT so the end-of-transaction INSERT RI trigger will
! 					 * not do anything, so we have to do the check for the
! 					 * UPDATE anyway.
  					 */
! 					if (!TransactionIdIsCurrentTransactionId(
! 								   HeapTupleHeaderGetXmin(oldtup->t_data)) &&
  						RI_FKey_keyequal_upd_fk(trigger, rel, oldtup, newtup))
  					{
  						continue;
Index: src/test/regress/sql/foreign_key.sql
===================================================================
RCS file: /home/affan/repos/cvs/pgsql/pgsql/src/test/regress/sql/foreign_key.sql,v
retrieving revision 1.19
diff -p -c -b -r1.19 foreign_key.sql
*** src/test/regress/sql/foreign_key.sql	5 Jun 2007 21:31:09 -0000	1.19
--- src/test/regress/sql/foreign_key.sql	13 Jul 2007 21:22:56 -0000
*************** UPDATE fktable SET id = id + 1;
*** 830,832 ****
--- 830,851 ----
  
  -- should catch error from initial INSERT
  COMMIT;
+ 
+ -- Now test the same UPDATE from a SAVEPOINT to validate that we do
+ -- not optimize away the FK RI trigger when the transaction that
+ -- created the being-UPDATEd row isn't the same as the transaction
+ -- UPDATing the row; but is a "current" transaction.
+ 
+ BEGIN;
+ 
+ -- doesn't match PK, but no error yet
+ INSERT INTO fktable VALUES (0, 20);
+ 
+ -- subxact for this SAVEPOINT will be active now
+ SAVEPOINT updSavept;
+ 
+ -- don't change FK
+ UPDATE fktable SET id = id + 1;
+ 
+ -- should catch error from initial INSERT
+ COMMIT;
Index: src/test/regress/expected/foreign_key.out
===================================================================
RCS file: /home/affan/repos/cvs/pgsql/pgsql/src/test/regress/expected/foreign_key.out,v
retrieving revision 1.43
diff -p -c -b -r1.43 foreign_key.out
*** src/test/regress/expected/foreign_key.out	5 Jun 2007 21:31:09 -0000	1.43
--- src/test/regress/expected/foreign_key.out	13 Jul 2007 21:23:12 -0000
*************** UPDATE fktable SET id = id + 1;
*** 1193,1195 ****
--- 1193,1210 ----
  COMMIT;
  ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_fk_fkey"
  DETAIL:  Key (fk)=(20) is not present in table "pktable".
+ -- Now test the same UPDATE from a SAVEPOINT to validate that we do
+ -- not optimize away the FK RI trigger when the transaction that
+ -- created the being-UPDATEd row isn't the same as the transaction
+ -- UPDATing the row; but is a "current" transaction.
+ BEGIN;
+ -- doesn't match PK, but no error yet
+ INSERT INTO fktable VALUES (0, 20);
+ -- subxact for this SAVEPOINT will be active now
+ SAVEPOINT updSavept;
+ -- don't change FK
+ UPDATE fktable SET id = id + 1;
+ -- should catch error from initial INSERT
+ COMMIT;
+ ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_fk_fkey"
+ DETAIL:  Key (fk)=(20) is not present in table "pktable".
