diff options
Diffstat (limited to 'src/include/utils/tqual.h')
-rw-r--r-- | src/include/utils/tqual.h | 117 |
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, |