Deferred RI trigger for non-key UPDATEs and subxacts - Mailing list pgsql-patches

From Affan Salman
Subject Deferred RI trigger for non-key UPDATEs and subxacts
Date
Msg-id 469806F7.40502@enterprisedb.com
Whole thread Raw
Responses Re: Deferred RI trigger for non-key UPDATEs and subxacts
Re: Deferred RI trigger for non-key UPDATEs and subxacts
List pgsql-patches
With some time to spare, I thought I'd submit a quick-fix patch to the
issue I reported here:

      http://archives.postgresql.org/pgsql-hackers/2007-07/msg00339.php

This should preclude optimizing away a deferred RI trigger if the
UPDATEd row (in the FK table) was inserted by "current" transaction
(i.e. defined by TransactionIdIsCurrentTransactionId()) and not
necessarily "by our own transaction" as the code currently says.
________________________________________________________________________

    backend/commands/trigger.c            |   17 !!!!!!!!!!!!!!!!!
    test/regress/expected/foreign_key.out |   15 +++++++++++++++
    test/regress/sql/foreign_key.sql      |   19 +++++++++++++++++++
    3 files changed, 34 insertions(+), 17 modifications(!)
________________________________________________________________________

--
Affan Salman
EnterpriseDB Corporation                      http://www.enterprisedb.com

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".

pgsql-patches by date:

Previous
From: "Simon Riggs"
Date:
Subject: Re: Transaction Guarantee, updated version
Next
From: Stefan Kaltenbrunner
Date:
Subject: GSSAPI support on solaris