Commit de593708 authored by Tom Lane's avatar Tom Lane

Make sure that all variants of HeapTupleSatisfies will do the right thing

if presented with a tuple in process of being moved by VACUUM.  Per
bug report from Brian Hirt.
parent e7149330
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.44 2001/10/28 06:25:58 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.45 2001/12/19 17:18:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -31,7 +31,7 @@ bool ReferentialIntegritySnapshotOverride = false; ...@@ -31,7 +31,7 @@ bool ReferentialIntegritySnapshotOverride = false;
/* /*
* HeapTupleSatisfiesItself * HeapTupleSatisfiesItself
* True iff heap tuple is valid for "itself." * True iff heap tuple is valid for "itself."
* "{it}self" means valid as of everything that's happened * "itself" means valid as of everything that's happened
* in the current transaction, _including_ the current command. * in the current transaction, _including_ the current command.
* *
* Note: * Note:
...@@ -53,34 +53,50 @@ bool ReferentialIntegritySnapshotOverride = false; ...@@ -53,34 +53,50 @@ bool ReferentialIntegritySnapshotOverride = false;
bool bool
HeapTupleSatisfiesItself(HeapTupleHeader tuple) HeapTupleSatisfiesItself(HeapTupleHeader tuple)
{ {
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)) if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
{ {
if (tuple->t_infomask & HEAP_XMIN_INVALID) if (tuple->t_infomask & HEAP_XMIN_INVALID)
return false; return false;
if (tuple->t_infomask & HEAP_MOVED_OFF) if (tuple->t_infomask & HEAP_MOVED_OFF)
{
if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return false;
if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
{ {
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return false; return false;
} }
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
{ {
if (!TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
{
if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
return false;
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
else
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return false; return false;
} }
} }
}
else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin)) else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
{ {
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
return true; return true;
Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax));
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE) if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true; return true;
return false; return false;
} }
else if (!TransactionIdDidCommit(tuple->t_xmin)) else if (!TransactionIdDidCommit(tuple->t_xmin))
...@@ -89,9 +105,11 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) ...@@ -89,9 +105,11 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple)
tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */ tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
return false; return false;
} }
else
tuple->t_infomask |= HEAP_XMIN_COMMITTED; tuple->t_infomask |= HEAP_XMIN_COMMITTED;
} }
/* the tuple was inserted validly */
/* by here, the inserting transaction has committed */
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
return true; return true;
...@@ -117,7 +135,7 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) ...@@ -117,7 +135,7 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple)
return true; return true;
} }
/* by here, deleting transaction has committed */ /* xmax transaction committed */
tuple->t_infomask |= HEAP_XMAX_COMMITTED; tuple->t_infomask |= HEAP_XMAX_COMMITTED;
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE) if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
...@@ -176,21 +194,34 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) ...@@ -176,21 +194,34 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
return false; return false;
if (tuple->t_infomask & HEAP_MOVED_OFF) if (tuple->t_infomask & HEAP_MOVED_OFF)
{
if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return false;
if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
{ {
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return false; return false;
} }
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
{ {
if (!TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
{
if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
return false;
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
else
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return false; return false;
} }
} }
}
else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin)) else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
{ {
if (CommandIdGEScanCommandId(tuple->t_cmin)) if (CommandIdGEScanCommandId(tuple->t_cmin))
...@@ -215,6 +246,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) ...@@ -215,6 +246,7 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */ tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
return false; return false;
} }
else
tuple->t_infomask |= HEAP_XMIN_COMMITTED; tuple->t_infomask |= HEAP_XMIN_COMMITTED;
} }
...@@ -257,92 +289,106 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) ...@@ -257,92 +289,106 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
} }
int int
HeapTupleSatisfiesUpdate(HeapTuple tuple) HeapTupleSatisfiesUpdate(HeapTuple htuple)
{ {
HeapTupleHeader th = tuple->t_data; HeapTupleHeader tuple = htuple->t_data;
if (AMI_OVERRIDE) if (AMI_OVERRIDE)
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
if (!(th->t_infomask & HEAP_XMIN_COMMITTED)) if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
{ {
if (th->t_infomask & HEAP_XMIN_INVALID) /* xid invalid or aborted */ if (tuple->t_infomask & HEAP_XMIN_INVALID)
return HeapTupleInvisible; return HeapTupleInvisible;
if (th->t_infomask & HEAP_MOVED_OFF) if (tuple->t_infomask & HEAP_MOVED_OFF)
{ {
if (TransactionIdDidCommit((TransactionId) th->t_cmin)) if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return HeapTupleInvisible;
if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
{
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
{ {
th->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return HeapTupleInvisible; return HeapTupleInvisible;
} }
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
} }
else if (th->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
{ {
if (!TransactionIdDidCommit((TransactionId) th->t_cmin)) if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
{
if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
return HeapTupleInvisible;
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
else
{ {
th->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return HeapTupleInvisible; return HeapTupleInvisible;
} }
} }
else if (TransactionIdIsCurrentTransactionId(th->t_xmin)) }
else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
{ {
if (CommandIdGEScanCommandId(th->t_cmin)) if (CommandIdGEScanCommandId(tuple->t_cmin))
return HeapTupleInvisible; /* inserted after scan return HeapTupleInvisible; /* inserted after scan
* started */ * started */
if (th->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
Assert(TransactionIdIsCurrentTransactionId(th->t_xmax)); Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax));
if (th->t_infomask & HEAP_MARKED_FOR_UPDATE) if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
if (CommandIdGEScanCommandId(th->t_cmax)) if (CommandIdGEScanCommandId(tuple->t_cmax))
return HeapTupleSelfUpdated; /* updated after scan return HeapTupleSelfUpdated; /* updated after scan
* started */ * started */
else else
return HeapTupleInvisible; /* updated before scan return HeapTupleInvisible; /* updated before scan
* started */ * started */
} }
else if (!TransactionIdDidCommit(th->t_xmin)) else if (!TransactionIdDidCommit(tuple->t_xmin))
{ {
if (TransactionIdDidAbort(th->t_xmin)) if (TransactionIdDidAbort(tuple->t_xmin))
th->t_infomask |= HEAP_XMIN_INVALID; /* aborted */ tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
return HeapTupleInvisible; return HeapTupleInvisible;
} }
th->t_infomask |= HEAP_XMIN_COMMITTED; else
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
} }
/* by here, the inserting transaction has committed */ /* by here, the inserting transaction has committed */
if (th->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
if (th->t_infomask & HEAP_XMAX_COMMITTED) if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
{ {
if (th->t_infomask & HEAP_MARKED_FOR_UPDATE) if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
return HeapTupleUpdated; /* updated by other */ return HeapTupleUpdated; /* updated by other */
} }
if (TransactionIdIsCurrentTransactionId(th->t_xmax)) if (TransactionIdIsCurrentTransactionId(tuple->t_xmax))
{ {
if (th->t_infomask & HEAP_MARKED_FOR_UPDATE) if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
if (CommandIdGEScanCommandId(th->t_cmax)) if (CommandIdGEScanCommandId(tuple->t_cmax))
return HeapTupleSelfUpdated; /* updated after scan return HeapTupleSelfUpdated; /* updated after scan
* started */ * started */
else else
return HeapTupleInvisible; /* updated before scan started */ return HeapTupleInvisible; /* updated before scan started */
} }
if (!TransactionIdDidCommit(th->t_xmax)) if (!TransactionIdDidCommit(tuple->t_xmax))
{ {
if (TransactionIdDidAbort(th->t_xmax)) if (TransactionIdDidAbort(tuple->t_xmax))
{ {
th->t_infomask |= HEAP_XMAX_INVALID; /* aborted */ tuple->t_infomask |= HEAP_XMAX_INVALID; /* aborted */
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
} }
/* running xact */ /* running xact */
...@@ -350,9 +396,9 @@ HeapTupleSatisfiesUpdate(HeapTuple tuple) ...@@ -350,9 +396,9 @@ HeapTupleSatisfiesUpdate(HeapTuple tuple)
} }
/* xmax transaction committed */ /* xmax transaction committed */
th->t_infomask |= HEAP_XMAX_COMMITTED; tuple->t_infomask |= HEAP_XMAX_COMMITTED;
if (th->t_infomask & HEAP_MARKED_FOR_UPDATE) if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
return HeapTupleUpdated; /* updated by other */ return HeapTupleUpdated; /* updated by other */
...@@ -374,12 +420,10 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple) ...@@ -374,12 +420,10 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
if (tuple->t_infomask & HEAP_MOVED_OFF) if (tuple->t_infomask & HEAP_MOVED_OFF)
{ {
/*
* HeapTupleSatisfiesDirty is used by unique btree-s and so
* may be used while vacuuming.
*/
if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin)) if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return false; return false;
if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
{
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
...@@ -387,10 +431,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple) ...@@ -387,10 +431,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
} }
tuple->t_infomask |= HEAP_XMIN_COMMITTED; tuple->t_infomask |= HEAP_XMIN_COMMITTED;
} }
}
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
{ {
if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin)) if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
{ {
if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
return false;
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
tuple->t_infomask |= HEAP_XMIN_COMMITTED; tuple->t_infomask |= HEAP_XMIN_COMMITTED;
else else
...@@ -416,10 +463,11 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple) ...@@ -416,10 +463,11 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
{ {
if (TransactionIdDidAbort(tuple->t_xmin)) if (TransactionIdDidAbort(tuple->t_xmin))
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */ tuple->t_infomask |= HEAP_XMIN_INVALID;
return false; return false;
} }
SnapshotDirty->xmin = tuple->t_xmin; SnapshotDirty->xmin = tuple->t_xmin;
/* XXX shouldn't we fall through to look at xmax? */
return true; /* in insertion by other */ return true; /* in insertion by other */
} }
else else
...@@ -474,6 +522,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) ...@@ -474,6 +522,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
if (AMI_OVERRIDE) if (AMI_OVERRIDE)
return true; return true;
/* XXX this is horribly ugly: */
if (ReferentialIntegritySnapshotOverride) if (ReferentialIntegritySnapshotOverride)
return HeapTupleSatisfiesNow(tuple); return HeapTupleSatisfiesNow(tuple);
...@@ -483,21 +532,34 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) ...@@ -483,21 +532,34 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
return false; return false;
if (tuple->t_infomask & HEAP_MOVED_OFF) if (tuple->t_infomask & HEAP_MOVED_OFF)
{
if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return false;
if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
{ {
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return false; return false;
} }
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
{ {
if (!TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
{
if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
return false;
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
else
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return false; return false;
} }
} }
}
else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin)) else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
{ {
if (CommandIdGEScanCommandId(tuple->t_cmin)) if (CommandIdGEScanCommandId(tuple->t_cmin))
...@@ -519,9 +581,10 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) ...@@ -519,9 +581,10 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
else if (!TransactionIdDidCommit(tuple->t_xmin)) else if (!TransactionIdDidCommit(tuple->t_xmin))
{ {
if (TransactionIdDidAbort(tuple->t_xmin)) if (TransactionIdDidAbort(tuple->t_xmin))
tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */ tuple->t_infomask |= HEAP_XMIN_INVALID;
return false; return false;
} }
else
tuple->t_infomask |= HEAP_XMIN_COMMITTED; tuple->t_infomask |= HEAP_XMIN_COMMITTED;
} }
...@@ -623,24 +686,30 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin) ...@@ -623,24 +686,30 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
return HEAPTUPLE_DEAD; return HEAPTUPLE_DEAD;
else if (tuple->t_infomask & HEAP_MOVED_OFF) else if (tuple->t_infomask & HEAP_MOVED_OFF)
{ {
if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return HEAPTUPLE_DELETE_IN_PROGRESS;
if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
return HEAPTUPLE_DELETE_IN_PROGRESS;
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
{ {
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return HEAPTUPLE_DEAD; return HEAPTUPLE_DEAD;
} }
/* Assume we can only get here if previous VACUUM aborted, */
/* ie, it couldn't still be in progress */
tuple->t_infomask |= HEAP_XMIN_COMMITTED; tuple->t_infomask |= HEAP_XMIN_COMMITTED;
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
{ {
if (!TransactionIdDidCommit((TransactionId) tuple->t_cmin)) if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return HEAPTUPLE_INSERT_IN_PROGRESS;
if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
return HEAPTUPLE_INSERT_IN_PROGRESS;
if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
else
{ {
/* Assume we can only get here if previous VACUUM aborted */
tuple->t_infomask |= HEAP_XMIN_INVALID; tuple->t_infomask |= HEAP_XMIN_INVALID;
return HEAPTUPLE_DEAD; return HEAPTUPLE_DEAD;
} }
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
} }
else if (TransactionIdIsInProgress(tuple->t_xmin)) else if (TransactionIdIsInProgress(tuple->t_xmin))
return HEAPTUPLE_INSERT_IN_PROGRESS; return HEAPTUPLE_INSERT_IN_PROGRESS;
...@@ -671,6 +740,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin) ...@@ -671,6 +740,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
if (tuple->t_infomask & HEAP_XMAX_INVALID) if (tuple->t_infomask & HEAP_XMAX_INVALID)
return HEAPTUPLE_LIVE; return HEAPTUPLE_LIVE;
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
{
/* "deleting" xact really only marked it for update */
return HEAPTUPLE_LIVE;
}
if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED)) if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
{ {
if (TransactionIdIsInProgress(tuple->t_xmax)) if (TransactionIdIsInProgress(tuple->t_xmax))
...@@ -699,12 +774,6 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin) ...@@ -699,12 +774,6 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
* Deleter committed, but check special cases. * Deleter committed, but check special cases.
*/ */
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
{
/* "deleting" xact really only marked it for update */
return HEAPTUPLE_LIVE;
}
if (TransactionIdEquals(tuple->t_xmin, tuple->t_xmax)) if (TransactionIdEquals(tuple->t_xmin, tuple->t_xmax))
{ {
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment