1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-18 12:22:09 +03:00

Back-patch fixes for problems with VACUUM destroying t_ctid chains too soon,

and with insufficient paranoia in code that follows t_ctid links.
This patch covers the 8.0 branch.
This commit is contained in:
Tom Lane
2005-08-25 19:45:06 +00:00
parent 5576a611cd
commit 08e12b89d5
8 changed files with 398 additions and 208 deletions

View File

@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.177.4.1 2005/04/11 19:51:31 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.177.4.2 2005/08/25 19:44:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1567,14 +1567,18 @@ GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo,
if (newSlot != NULL)
{
int test;
ItemPointerData update_ctid;
TransactionId update_xmax;
*newSlot = NULL;
/*
* mark tuple for update
*/
*newSlot = NULL;
tuple.t_self = *tid;
ltrmark:;
test = heap_mark4update(relation, &tuple, &buffer, cid);
tuple.t_self = *tid;
test = heap_mark4update(relation, &tuple, &buffer,
&update_ctid, &update_xmax, cid);
switch (test)
{
case HeapTupleSelfUpdated:
@@ -1591,15 +1595,18 @@ ltrmark:;
ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("could not serialize access due to concurrent update")));
else if (!(ItemPointerEquals(&(tuple.t_self), tid)))
else if (!ItemPointerEquals(&update_ctid, &tuple.t_self))
{
TupleTableSlot *epqslot = EvalPlanQual(estate,
relinfo->ri_RangeTableIndex,
&(tuple.t_self));
/* it was updated, so look at the updated version */
TupleTableSlot *epqslot;
if (!(TupIsNull(epqslot)))
epqslot = EvalPlanQual(estate,
relinfo->ri_RangeTableIndex,
&update_ctid,
update_xmax);
if (!TupIsNull(epqslot))
{
*tid = tuple.t_self;
*tid = update_ctid;
*newSlot = epqslot;
goto ltrmark;
}
@@ -1634,6 +1641,7 @@ ltrmark:;
tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
tuple.t_len = ItemIdGetLength(lp);
tuple.t_self = *tid;
tuple.t_tableOid = RelationGetRelid(relation);
}
result = heap_copytuple(&tuple);