Here's my current work in progress for 8.1 devel related to fixing the
timing issues with referential actions having their checks run on
intermediate states. I've only put in a simple test that failed against
8.0 in the regression patch and regression still passes for me. There's
still an outstanding question of whether looping gives the correct result
in the presence of explicit inserts and set constraints immediate in
before triggers.Index: src/backend/commands/trigger.c
===
RCS file: /projects/cvsroot/pgsql/src/backend/commands/trigger.c,v
retrieving revision 1.193
diff -c -r1.193 trigger.c
*** src/backend/commands/trigger.c 23 Aug 2005 22:40:08 - 1.193
--- src/backend/commands/trigger.c 24 Aug 2005 03:24:48 -
***
*** 2281,2286
--- 2280,2286
TriggerDesc *trigdesc = NULL;
FmgrInfo *finfo = NULL;
Instrumentation *instr = NULL;
+ bool last_relation_loaded = false;
/* Make a per-tuple memory context for trigger function calls */
per_tuple_context =
***
*** 2309,2314
--- 2309,2328
*/
if (rel == NULL || rel-rd_id != event-ate_relid)
{
+ bool found_relation_in_estate = false;
+ if (last_relation_loaded) {
+ if (rel)
+ heap_close(rel, NoLock);
+ if (trigdesc)
+ FreeTriggerDesc(trigdesc);
+ if (finfo)
+ pfree(finfo);
+ Assert(instr == NULL); /* never used
in this case */
+ rel = NULL;
+ trigdesc = NULL;
+ finfo = NULL;
+ }
+
if (estate)
{
/* Find target relation among estate's
result rels */
***
*** 2324,2348
rInfo++;
nr--;
}
! if (nr = 0)
/* should not happen */
! elog(ERROR, could not find
relation %u among query result relations,
!event-ate_relid);
! rel = rInfo-ri_RelationDesc;
! trigdesc = rInfo-ri_TrigDesc;
! finfo = rInfo-ri_TrigFunctions;
! instr = rInfo-ri_TrigInstrument;
}
- else
- {
- /* Hard way: we manage the resources
for ourselves */
- if (rel)
- heap_close(rel, NoLock);
- if (trigdesc)
- FreeTriggerDesc(trigdesc);
- if (finfo)
- pfree(finfo);
- Assert(instr == NULL); /* never used
in this case */
/*
* We assume that an appropriate lock
is still held by
* the executor, so grab no new lock
here.
--- 2338,2355
rInfo++;
nr--;
}
! if (nr 0)
! {
! rel = rInfo-ri_RelationDesc;
! trigdesc = rInfo-ri_TrigDesc;
! finfo = rInfo-ri_TrigFunctions;
! instr =
rInfo-ri_TrigInstrument;
! found_relation_in_estate = true;
! }
}
+ if (!found_relation_in_estate)
+ {
/*
* We assume that an appropriate lock
is still held by
* the executor, so grab no new lock
here.