*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* HeapTupleSatisfiesItself
* 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.
*
* Note:
bool
HeapTupleSatisfiesItself(HeapTupleHeader tuple)
{
-
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
{
if (tuple->t_infomask & HEAP_XMIN_INVALID)
if (tuple->t_infomask & HEAP_MOVED_OFF)
{
- if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
- {
- tuple->t_infomask |= HEAP_XMIN_INVALID;
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return false;
+ if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
+ {
+ if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ {
+ tuple->t_infomask |= HEAP_XMIN_INVALID;
+ return false;
+ }
+ tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
{
- if (!TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
{
- tuple->t_infomask |= HEAP_XMIN_INVALID;
- return false;
+ 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;
+ return false;
+ }
}
}
else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
{
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
return true;
+
+ Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax));
+
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
+
return false;
}
else if (!TransactionIdDidCommit(tuple->t_xmin))
tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
return false;
}
- tuple->t_infomask |= HEAP_XMIN_COMMITTED;
+ else
+ 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 */
return true;
return true;
}
- /* by here, deleting transaction has committed */
+ /* xmax transaction committed */
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
if (tuple->t_infomask & HEAP_MOVED_OFF)
{
- if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
- {
- tuple->t_infomask |= HEAP_XMIN_INVALID;
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return false;
+ if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
+ {
+ if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ {
+ tuple->t_infomask |= HEAP_XMIN_INVALID;
+ return false;
+ }
+ tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
{
- if (!TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
{
- tuple->t_infomask |= HEAP_XMIN_INVALID;
- return false;
+ 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;
+ return false;
+ }
}
}
else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
return false;
}
- tuple->t_infomask |= HEAP_XMIN_COMMITTED;
+ else
+ tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
/* by here, the inserting transaction has committed */
}
int
-HeapTupleSatisfiesUpdate(HeapTuple tuple)
+HeapTupleSatisfiesUpdate(HeapTuple htuple)
{
- HeapTupleHeader th = tuple->t_data;
+ HeapTupleHeader tuple = htuple->t_data;
if (AMI_OVERRIDE)
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;
- if (th->t_infomask & HEAP_MOVED_OFF)
+ if (tuple->t_infomask & HEAP_MOVED_OFF)
{
- if (TransactionIdDidCommit((TransactionId) th->t_cmin))
- {
- th->t_infomask |= HEAP_XMIN_INVALID;
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return HeapTupleInvisible;
+ if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
+ {
+ if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ {
+ tuple->t_infomask |= HEAP_XMIN_INVALID;
+ 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))
{
- th->t_infomask |= HEAP_XMIN_INVALID;
- return HeapTupleInvisible;
+ if (TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
+ return HeapTupleInvisible;
+ if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ tuple->t_infomask |= HEAP_XMIN_COMMITTED;
+ else
+ {
+ tuple->t_infomask |= HEAP_XMIN_INVALID;
+ 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
* started */
- if (th->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
+ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
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;
- if (CommandIdGEScanCommandId(th->t_cmax))
+ if (CommandIdGEScanCommandId(tuple->t_cmax))
return HeapTupleSelfUpdated; /* updated after scan
* started */
else
return HeapTupleInvisible; /* updated before scan
* started */
}
- else if (!TransactionIdDidCommit(th->t_xmin))
+ else if (!TransactionIdDidCommit(tuple->t_xmin))
{
- if (TransactionIdDidAbort(th->t_xmin))
- th->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
+ if (TransactionIdDidAbort(tuple->t_xmin))
+ tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
return HeapTupleInvisible;
}
- th->t_infomask |= HEAP_XMIN_COMMITTED;
+ else
+ tuple->t_infomask |= HEAP_XMIN_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;
- 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 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;
- if (CommandIdGEScanCommandId(th->t_cmax))
+ if (CommandIdGEScanCommandId(tuple->t_cmax))
return HeapTupleSelfUpdated; /* updated after scan
* started */
else
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;
}
/* running xact */
}
/* 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 HeapTupleUpdated; /* updated by other */
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))
return false;
- if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
{
- tuple->t_infomask |= HEAP_XMIN_INVALID;
- return false;
+ if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ {
+ tuple->t_infomask |= HEAP_XMIN_INVALID;
+ return false;
+ }
+ tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
- tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
{
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
{
if (TransactionIdDidAbort(tuple->t_xmin))
{
- tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
+ tuple->t_infomask |= HEAP_XMIN_INVALID;
return false;
}
SnapshotDirty->xmin = tuple->t_xmin;
+ /* XXX shouldn't we fall through to look at xmax? */
return true; /* in insertion by other */
}
else
if (AMI_OVERRIDE)
return true;
+ /* XXX this is horribly ugly: */
if (ReferentialIntegritySnapshotOverride)
return HeapTupleSatisfiesNow(tuple);
if (tuple->t_infomask & HEAP_MOVED_OFF)
{
- if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
- {
- tuple->t_infomask |= HEAP_XMIN_INVALID;
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
return false;
+ if (!TransactionIdIsInProgress((TransactionId) tuple->t_cmin))
+ {
+ if (TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ {
+ tuple->t_infomask |= HEAP_XMIN_INVALID;
+ return false;
+ }
+ tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
{
- if (!TransactionIdDidCommit((TransactionId) tuple->t_cmin))
+ if (!TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_cmin))
{
- tuple->t_infomask |= HEAP_XMIN_INVALID;
- return false;
+ 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;
+ return false;
+ }
}
}
else if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
else if (!TransactionIdDidCommit(tuple->t_xmin))
{
if (TransactionIdDidAbort(tuple->t_xmin))
- tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
+ tuple->t_infomask |= HEAP_XMIN_INVALID;
return false;
}
- tuple->t_infomask |= HEAP_XMIN_COMMITTED;
+ else
+ tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
/*
return HEAPTUPLE_DEAD;
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))
{
tuple->t_infomask |= HEAP_XMIN_INVALID;
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;
}
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;
return HEAPTUPLE_DEAD;
}
- tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
else if (TransactionIdIsInProgress(tuple->t_xmin))
return HEAPTUPLE_INSERT_IN_PROGRESS;
if (tuple->t_infomask & HEAP_XMAX_INVALID)
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 (TransactionIdIsInProgress(tuple->t_xmax))
* 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))
{
/*