aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/time/tqual.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/time/tqual.c')
-rw-r--r--src/backend/utils/time/tqual.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c
index 6d8f86acc96..32eeabb9994 100644
--- a/src/backend/utils/time/tqual.c
+++ b/src/backend/utils/time/tqual.c
@@ -50,7 +50,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.113 2009/06/11 14:49:06 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.114 2009/12/19 01:32:37 sriggs Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1257,42 +1257,84 @@ XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
return true;
/*
- * If the snapshot contains full subxact data, the fastest way to check
- * things is just to compare the given XID against both subxact XIDs and
- * top-level XIDs. If the snapshot overflowed, we have to use pg_subtrans
- * to convert a subxact XID to its parent XID, but then we need only look
- * at top-level XIDs not subxacts.
+ * Snapshot information is stored slightly differently in snapshots
+ * taken during recovery.
*/
- if (snapshot->subxcnt >= 0)
+ if (!snapshot->takenDuringRecovery)
{
- /* full data, so search subxip */
- int32 j;
+ /*
+ * If the snapshot contains full subxact data, the fastest way to check
+ * things is just to compare the given XID against both subxact XIDs and
+ * top-level XIDs. If the snapshot overflowed, we have to use pg_subtrans
+ * to convert a subxact XID to its parent XID, but then we need only look
+ * at top-level XIDs not subxacts.
+ */
+ if (!snapshot->suboverflowed)
+ {
+ /* full data, so search subxip */
+ int32 j;
- for (j = 0; j < snapshot->subxcnt; j++)
+ for (j = 0; j < snapshot->subxcnt; j++)
+ {
+ if (TransactionIdEquals(xid, snapshot->subxip[j]))
+ return true;
+ }
+
+ /* not there, fall through to search xip[] */
+ }
+ else
{
- if (TransactionIdEquals(xid, snapshot->subxip[j]))
- return true;
+ /* overflowed, so convert xid to top-level */
+ xid = SubTransGetTopmostTransaction(xid);
+
+ /*
+ * If xid was indeed a subxact, we might now have an xid < xmin, so
+ * recheck to avoid an array scan. No point in rechecking xmax.
+ */
+ if (TransactionIdPrecedes(xid, snapshot->xmin))
+ return false;
}
- /* not there, fall through to search xip[] */
+ for (i = 0; i < snapshot->xcnt; i++)
+ {
+ if (TransactionIdEquals(xid, snapshot->xip[i]))
+ return true;
+ }
}
else
{
- /* overflowed, so convert xid to top-level */
- xid = SubTransGetTopmostTransaction(xid);
+ int32 j;
/*
- * If xid was indeed a subxact, we might now have an xid < xmin, so
- * recheck to avoid an array scan. No point in rechecking xmax.
+ * In recovery we store all xids in the subxact array because it
+ * is by far the bigger array, and we mostly don't know which xids
+ * are top-level and which are subxacts. The xip array is empty.
+ *
+ * We start by searching subtrans, if we overflowed.
*/
- if (TransactionIdPrecedes(xid, snapshot->xmin))
- return false;
- }
+ if (snapshot->suboverflowed)
+ {
+ /* overflowed, so convert xid to top-level */
+ xid = SubTransGetTopmostTransaction(xid);
- for (i = 0; i < snapshot->xcnt; i++)
- {
- if (TransactionIdEquals(xid, snapshot->xip[i]))
- return true;
+ /*
+ * If xid was indeed a subxact, we might now have an xid < xmin, so
+ * recheck to avoid an array scan. No point in rechecking xmax.
+ */
+ if (TransactionIdPrecedes(xid, snapshot->xmin))
+ return false;
+ }
+
+ /*
+ * We now have either a top-level xid higher than xmin or an
+ * indeterminate xid. We don't know whether it's top level or subxact
+ * but it doesn't matter. If it's present, the xid is visible.
+ */
+ for (j = 0; j < snapshot->subxcnt; j++)
+ {
+ if (TransactionIdEquals(xid, snapshot->subxip[j]))
+ return true;
+ }
}
return false;