Skip to content

Commit 1e3b21d

Browse files
committed
Change FK trigger naming convention to fix self-referential FKs.
Use names like "RI_ConstraintTrigger_a_NNNN" for FK action triggers and "RI_ConstraintTrigger_c_NNNN" for FK check triggers. This ensures the action trigger fires first in self-referential cases where the very same row update fires both an action and a check trigger. This change provides a non-probabilistic solution for bug #6268, at the risk that it could break client code that is making assumptions about the exact names assigned to auto-generated FK triggers. Hence, change this in HEAD only. No need for forced initdb since old triggers continue to work fine.
1 parent 5895872 commit 1e3b21d

File tree

1 file changed

+12
-14
lines changed

1 file changed

+12
-14
lines changed

src/backend/commands/tablecmds.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6467,8 +6467,17 @@ CreateFKCheckTrigger(RangeVar *myRel, Constraint *fkconstraint,
64676467
{
64686468
CreateTrigStmt *fk_trigger;
64696469

6470+
/*
6471+
* Note: for a self-referential FK (referencing and referenced tables are
6472+
* the same), it is important that the ON UPDATE action fires before the
6473+
* CHECK action, since both triggers will fire on the same row during an
6474+
* UPDATE event; otherwise the CHECK trigger will be checking a non-final
6475+
* state of the row. Triggers fire in name order, so we ensure this by
6476+
* using names like "RI_ConstraintTrigger_a_NNNN" for the action triggers
6477+
* and "RI_ConstraintTrigger_c_NNNN" for the check triggers.
6478+
*/
64706479
fk_trigger = makeNode(CreateTrigStmt);
6471-
fk_trigger->trigname = "RI_ConstraintTrigger";
6480+
fk_trigger->trigname = "RI_ConstraintTrigger_c";
64726481
fk_trigger->relation = myRel;
64736482
fk_trigger->row = true;
64746483
fk_trigger->timing = TRIGGER_TYPE_AFTER;
@@ -6524,7 +6533,7 @@ createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
65246533
* DELETE action on the referenced table.
65256534
*/
65266535
fk_trigger = makeNode(CreateTrigStmt);
6527-
fk_trigger->trigname = "RI_ConstraintTrigger";
6536+
fk_trigger->trigname = "RI_ConstraintTrigger_a";
65286537
fk_trigger->relation = fkconstraint->pktable;
65296538
fk_trigger->row = true;
65306539
fk_trigger->timing = TRIGGER_TYPE_AFTER;
@@ -6577,7 +6586,7 @@ createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
65776586
* UPDATE action on the referenced table.
65786587
*/
65796588
fk_trigger = makeNode(CreateTrigStmt);
6580-
fk_trigger->trigname = "RI_ConstraintTrigger";
6589+
fk_trigger->trigname = "RI_ConstraintTrigger_a";
65816590
fk_trigger->relation = fkconstraint->pktable;
65826591
fk_trigger->row = true;
65836592
fk_trigger->timing = TRIGGER_TYPE_AFTER;
@@ -6628,17 +6637,6 @@ createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
66286637
/*
66296638
* Build and execute CREATE CONSTRAINT TRIGGER statements for the CHECK
66306639
* action for both INSERTs and UPDATEs on the referencing table.
6631-
*
6632-
* Note: for a self-referential FK (referencing and referenced tables are
6633-
* the same), it is important that the ON UPDATE action fires before the
6634-
* CHECK action, since both triggers will fire on the same row during an
6635-
* UPDATE event; otherwise the CHECK trigger will be checking a non-final
6636-
* state of the row. Because triggers fire in name order, we are
6637-
* effectively relying on the OIDs of the triggers to sort correctly as
6638-
* text. This will work except when the OID counter wraps around or adds
6639-
* a digit, eg "99999" sorts after "100000". That is infrequent enough,
6640-
* and the use of self-referential FKs is rare enough, that we live with
6641-
* it for now. There will be a real fix in PG 9.2.
66426640
*/
66436641
CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, true);
66446642
CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, false);

0 commit comments

Comments
 (0)