* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.173 2004/10/21 21:33:59 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.174 2004/10/30 20:52:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
TRIGGER_EVENT_BEFORE;
LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
- LocTriggerData.tg_newtuple = NULL;
LocTriggerData.tg_trigtuple = NULL;
+ LocTriggerData.tg_newtuple = NULL;
+ LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
for (i = 0; i < ntrigs; i++)
{
Trigger *trigger = &trigdesc->triggers[tgindx[i]];
TRIGGER_EVENT_BEFORE;
LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
LocTriggerData.tg_newtuple = NULL;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
for (i = 0; i < ntrigs; i++)
{
Trigger *trigger = &trigdesc->triggers[tgindx[i]];
if (!trigger->tgenabled)
continue;
LocTriggerData.tg_trigtuple = oldtuple = newtuple;
+ LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
LocTriggerData.tg_trigger = trigger;
newtuple = ExecCallTriggerFunc(&LocTriggerData,
relinfo->ri_TrigFunctions + tgindx[i],
LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
TRIGGER_EVENT_BEFORE;
LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
- LocTriggerData.tg_newtuple = NULL;
LocTriggerData.tg_trigtuple = NULL;
+ LocTriggerData.tg_newtuple = NULL;
+ LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
for (i = 0; i < ntrigs; i++)
{
Trigger *trigger = &trigdesc->triggers[tgindx[i]];
TRIGGER_EVENT_BEFORE;
LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
LocTriggerData.tg_newtuple = NULL;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
for (i = 0; i < ntrigs; i++)
{
Trigger *trigger = &trigdesc->triggers[tgindx[i]];
if (!trigger->tgenabled)
continue;
LocTriggerData.tg_trigtuple = trigtuple;
+ LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
LocTriggerData.tg_trigger = trigger;
newtuple = ExecCallTriggerFunc(&LocTriggerData,
relinfo->ri_TrigFunctions + tgindx[i],
LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
TRIGGER_EVENT_BEFORE;
LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
- LocTriggerData.tg_newtuple = NULL;
LocTriggerData.tg_trigtuple = NULL;
+ LocTriggerData.tg_newtuple = NULL;
+ LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
for (i = 0; i < ntrigs; i++)
{
Trigger *trigger = &trigdesc->triggers[tgindx[i]];
continue;
LocTriggerData.tg_trigtuple = trigtuple;
LocTriggerData.tg_newtuple = oldtuple = newtuple;
+ LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
LocTriggerData.tg_trigger = trigger;
newtuple = ExecCallTriggerFunc(&LocTriggerData,
relinfo->ri_TrigFunctions + tgindx[i],
HeapTupleData oldtuple;
HeapTupleData newtuple;
HeapTuple rettuple;
- Buffer oldbuffer;
- Buffer newbuffer;
+ Buffer oldbuffer = InvalidBuffer;
+ Buffer newbuffer = InvalidBuffer;
int tgindx;
/*
case TRIGGER_EVENT_INSERT:
LocTriggerData.tg_trigtuple = &newtuple;
LocTriggerData.tg_newtuple = NULL;
+ LocTriggerData.tg_trigtuplebuf = newbuffer;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
break;
case TRIGGER_EVENT_UPDATE:
LocTriggerData.tg_trigtuple = &oldtuple;
LocTriggerData.tg_newtuple = &newtuple;
+ LocTriggerData.tg_trigtuplebuf = oldbuffer;
+ LocTriggerData.tg_newtuplebuf = newbuffer;
break;
case TRIGGER_EVENT_DELETE:
LocTriggerData.tg_trigtuple = &oldtuple;
LocTriggerData.tg_newtuple = NULL;
+ LocTriggerData.tg_trigtuplebuf = oldbuffer;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
break;
}
/*
* Release buffers
*/
- if (ItemPointerIsValid(&(event->ate_oldctid)))
+ if (oldbuffer != InvalidBuffer)
ReleaseBuffer(oldbuffer);
- if (ItemPointerIsValid(&(event->ate_newctid)))
+ if (newbuffer != InvalidBuffer)
ReleaseBuffer(newbuffer);
}
LocTriggerData.tg_trigtuple = oldtup;
LocTriggerData.tg_newtuple = newtup;
LocTriggerData.tg_trigger = trigger;
+ /*
+ * We do not currently know which buffers the passed tuples
+ * are in, but it does not matter because RI_FKey_keyequal_upd
+ * does not care. We could expand the API of this function
+ * if it becomes necessary to set these fields accurately.
+ */
+ LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
+ LocTriggerData.tg_newtuplebuf = InvalidBuffer;
if (RI_FKey_keyequal_upd(&LocTriggerData))
{
*
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.74 2004/10/15 22:40:11 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.75 2004/10/30 20:52:59 tgl Exp $
*
* ----------
*/
Relation pk_rel;
HeapTuple new_row;
HeapTuple old_row;
+ Buffer new_row_buf;
RI_QueryKey qkey;
void *qplan;
int i;
{
old_row = trigdata->tg_trigtuple;
new_row = trigdata->tg_newtuple;
+ new_row_buf = trigdata->tg_newtuplebuf;
}
else
{
old_row = NULL;
new_row = trigdata->tg_trigtuple;
+ new_row_buf = trigdata->tg_trigtuplebuf;
}
/*
* 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 do not know what buffer the new_row is in, but it doesn't matter
- * since it's not possible for a hint-bit update to occur here (the
- * new_row could only contain our own XID, and we haven't yet committed
- * or aborted...)
*/
- if (new_row)
+ Assert(new_row_buf != InvalidBuffer);
+ if (!HeapTupleSatisfiesItself(new_row->t_data, new_row_buf))
{
- if (!HeapTupleSatisfiesItself(new_row->t_data, InvalidBuffer))
- {
- heap_close(pk_rel, RowShareLock);
- return PointerGetDatum(NULL);
- }
+ heap_close(pk_rel, RowShareLock);
+ return PointerGetDatum(NULL);
}
/* ----------
* SQL3 11.9 <referential constraint definition>
- * Gereral rules 2) a):
+ * General rules 2) a):
* If Rf and Rt are empty (no columns to compare given)
* constraint is true if 0 < (SELECT COUNT(*) FROM T)
*