summaryrefslogtreecommitdiff
path: root/src/include/utils/tqual.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/utils/tqual.h')
-rw-r--r--src/include/utils/tqual.h117
1 files changed, 60 insertions, 57 deletions
diff --git a/src/include/utils/tqual.h b/src/include/utils/tqual.h
index 0b3ef50ac34..e3596e2d507 100644
--- a/src/include/utils/tqual.h
+++ b/src/include/utils/tqual.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.65 2007/01/05 22:19:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.66 2007/03/25 19:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,23 +20,31 @@
/*
- * "Regular" snapshots are pointers to a SnapshotData structure.
- *
- * We also have some "special" snapshot values that have fixed meanings
- * and don't need any backing SnapshotData. These are encoded by small
- * integer values, which of course is a gross violation of ANSI C, but
- * it works fine on all known platforms.
- *
- * SnapshotDirty is an even more special case: its semantics are fixed,
- * but there is a backing SnapshotData struct for it. That struct is
- * actually used as *output* data from tqual.c, not input into it.
- * (But hey, SnapshotDirty ought to have a dirty implementation, no? ;-))
+ * We use SnapshotData structures to represent both "regular" (MVCC)
+ * snapshots and "special" snapshots that have non-MVCC semantics.
+ * The specific semantics of a snapshot are encoded by the "satisfies"
+ * function.
*/
+typedef struct SnapshotData *Snapshot;
+
+typedef bool (*SnapshotSatisfiesFunc) (HeapTupleHeader tuple,
+ Snapshot snapshot, Buffer buffer);
typedef struct SnapshotData
{
- TransactionId xmin; /* XID < xmin are visible to me */
- TransactionId xmax; /* XID >= xmax are invisible to me */
+ SnapshotSatisfiesFunc satisfies; /* tuple test function */
+ /*
+ * The remaining fields are used only for MVCC snapshots, and are
+ * normally just zeroes in special snapshots. (But xmin and xmax
+ * are used specially by HeapTupleSatisfiesDirty.)
+ *
+ * An MVCC snapshot can never see the effects of XIDs >= xmax.
+ * It can see the effects of all older XIDs except those listed in
+ * the snapshot. xmin is stored as an optimization to avoid needing
+ * to search the XID arrays for most tuples.
+ */
+ TransactionId xmin; /* all XID < xmin are visible to me */
+ TransactionId xmax; /* all XID >= xmax are invisible to me */
uint32 xcnt; /* # of xact ids in xip[] */
TransactionId *xip; /* array of xact IDs in progress */
/* note: all ids in xip[] satisfy xmin <= xip[i] < xmax */
@@ -50,24 +58,30 @@ typedef struct SnapshotData
CommandId curcid; /* in my xact, CID < curcid are visible */
} SnapshotData;
-typedef SnapshotData *Snapshot;
+#define InvalidSnapshot ((Snapshot) NULL)
-/* Special snapshot values: */
-#define InvalidSnapshot ((Snapshot) 0x0) /* same as NULL */
-#define SnapshotNow ((Snapshot) 0x1)
-#define SnapshotSelf ((Snapshot) 0x2)
-#define SnapshotAny ((Snapshot) 0x3)
-#define SnapshotToast ((Snapshot) 0x4)
+/* Static variables representing various special snapshot semantics */
+extern DLLIMPORT SnapshotData SnapshotNowData;
+extern DLLIMPORT SnapshotData SnapshotSelfData;
+extern DLLIMPORT SnapshotData SnapshotAnyData;
+extern DLLIMPORT SnapshotData SnapshotToastData;
-extern DLLIMPORT Snapshot SnapshotDirty;
+#define SnapshotNow (&SnapshotNowData)
+#define SnapshotSelf (&SnapshotSelfData)
+#define SnapshotAny (&SnapshotAnyData)
+#define SnapshotToast (&SnapshotToastData)
+
+/*
+ * We don't provide a static SnapshotDirty variable because it would be
+ * non-reentrant. Instead, users of that snapshot type should declare a
+ * local variable of type SnapshotData, and initialize it with this macro.
+ */
+#define InitDirtySnapshot(snapshotdata) \
+ ((snapshotdata).satisfies = HeapTupleSatisfiesDirty)
/* This macro encodes the knowledge of which snapshots are MVCC-safe */
#define IsMVCCSnapshot(snapshot) \
- ((snapshot) != SnapshotNow && \
- (snapshot) != SnapshotSelf && \
- (snapshot) != SnapshotAny && \
- (snapshot) != SnapshotToast && \
- (snapshot) != SnapshotDirty)
+ ((snapshot)->satisfies == HeapTupleSatisfiesMVCC)
extern DLLIMPORT Snapshot SerializableSnapshot;
@@ -78,7 +92,6 @@ extern TransactionId TransactionXmin;
extern TransactionId RecentXmin;
extern TransactionId RecentGlobalXmin;
-
/*
* HeapTupleSatisfiesVisibility
* True iff heap tuple satisfies a time qual.
@@ -86,30 +99,11 @@ extern TransactionId RecentGlobalXmin;
* Notes:
* Assumes heap tuple is valid.
* Beware of multiple evaluations of snapshot argument.
- * Hint bits in the HeapTuple's t_infomask may be updated as a side effect.
+ * Hint bits in the HeapTuple's t_infomask may be updated as a side effect;
+ * if so, the indicated buffer is marked dirty.
*/
#define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer) \
-((snapshot) == SnapshotNow ? \
- HeapTupleSatisfiesNow((tuple)->t_data, buffer) \
-: \
- ((snapshot) == SnapshotSelf ? \
- HeapTupleSatisfiesItself((tuple)->t_data, buffer) \
- : \
- ((snapshot) == SnapshotAny ? \
- true \
- : \
- ((snapshot) == SnapshotToast ? \
- HeapTupleSatisfiesToast((tuple)->t_data, buffer) \
- : \
- ((snapshot) == SnapshotDirty ? \
- HeapTupleSatisfiesDirty((tuple)->t_data, buffer) \
- : \
- HeapTupleSatisfiesSnapshot((tuple)->t_data, snapshot, buffer) \
- ) \
- ) \
- ) \
- ) \
-)
+ ((*(snapshot)->satisfies) ((tuple)->t_data, snapshot, buffer))
/* Result codes for HeapTupleSatisfiesUpdate */
typedef enum
@@ -127,16 +121,25 @@ typedef enum
HEAPTUPLE_DEAD, /* tuple is dead and deletable */
HEAPTUPLE_LIVE, /* tuple is live (committed, no deleter) */
HEAPTUPLE_RECENTLY_DEAD, /* tuple is dead, but not deletable yet */
- HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */
+ HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */
HEAPTUPLE_DELETE_IN_PROGRESS /* deleting xact is still in progress */
} HTSV_Result;
-extern bool HeapTupleSatisfiesItself(HeapTupleHeader tuple, Buffer buffer);
-extern bool HeapTupleSatisfiesNow(HeapTupleHeader tuple, Buffer buffer);
-extern bool HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Buffer buffer);
-extern bool HeapTupleSatisfiesToast(HeapTupleHeader tuple, Buffer buffer);
-extern bool HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple,
- Snapshot snapshot, Buffer buffer);
+/* These are the "satisfies" test routines for the various snapshot types */
+extern bool HeapTupleSatisfiesMVCC(HeapTupleHeader tuple,
+ Snapshot snapshot, Buffer buffer);
+extern bool HeapTupleSatisfiesNow(HeapTupleHeader tuple,
+ Snapshot snapshot, Buffer buffer);
+extern bool HeapTupleSatisfiesSelf(HeapTupleHeader tuple,
+ Snapshot snapshot, Buffer buffer);
+extern bool HeapTupleSatisfiesAny(HeapTupleHeader tuple,
+ Snapshot snapshot, Buffer buffer);
+extern bool HeapTupleSatisfiesToast(HeapTupleHeader tuple,
+ Snapshot snapshot, Buffer buffer);
+extern bool HeapTupleSatisfiesDirty(HeapTupleHeader tuple,
+ Snapshot snapshot, Buffer buffer);
+
+/* Special "satisfies" routines with different APIs */
extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTupleHeader tuple,
CommandId curcid, Buffer buffer);
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,