/*-------------------------------------------------------------------------
*
* tqual.h
- * POSTGRES "time" qualification definitions, ie, tuple visibility rules.
+ * POSTGRES "time qualification" definitions, ie, tuple visibility rules.
*
* Should be moved/renamed... - vadim 07/28/98
*
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: tqual.h,v 1.44 2003/02/23 23:20:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.69 2007/11/15 21:14:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#define TQUAL_H
#include "access/htup.h"
-#include "access/xact.h"
+#include "storage/buf.h"
+/*
+ * 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 */
+ int32 subxcnt; /* # of xact ids in subxip[], -1 if overflow */
+ TransactionId *subxip; /* array of subxact IDs in progress */
+
+ /*
+ * note: all ids in subxip[] are >= xmin, but we don't bother filtering
+ * out any that are >= xmax
+ */
CommandId curcid; /* in my xact, CID < curcid are visible */
- ItemPointerData tid; /* required for Dirty snapshot -:( */
} SnapshotData;
-typedef SnapshotData *Snapshot;
+#define InvalidSnapshot ((Snapshot) NULL)
-#define SnapshotNow ((Snapshot) 0x0)
-#define SnapshotSelf ((Snapshot) 0x1)
-#define SnapshotAny ((Snapshot) 0x2)
-#define SnapshotToast ((Snapshot) 0x3)
+/* Static variables representing various special snapshot semantics */
+extern PGDLLIMPORT SnapshotData SnapshotNowData;
+extern PGDLLIMPORT SnapshotData SnapshotSelfData;
+extern PGDLLIMPORT SnapshotData SnapshotAnyData;
+extern PGDLLIMPORT SnapshotData SnapshotToastData;
-extern DLLIMPORT Snapshot SnapshotDirty;
-extern DLLIMPORT Snapshot QuerySnapshot;
-extern DLLIMPORT Snapshot SerializableSnapshot;
+#define SnapshotNow (&SnapshotNowData)
+#define SnapshotSelf (&SnapshotSelfData)
+#define SnapshotAny (&SnapshotAnyData)
+#define SnapshotToast (&SnapshotToastData)
-extern TransactionId RecentXmin;
-extern TransactionId RecentGlobalXmin;
+/*
+ * 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)->satisfies == HeapTupleSatisfiesMVCC)
-extern bool ReferentialIntegritySnapshotOverride;
-#define IsSnapshotNow(snapshot) ((Snapshot) (snapshot) == SnapshotNow)
-#define IsSnapshotSelf(snapshot) ((Snapshot) (snapshot) == SnapshotSelf)
-#define IsSnapshotAny(snapshot) ((Snapshot) (snapshot) == SnapshotAny)
-#define IsSnapshotToast(snapshot) ((Snapshot) (snapshot) == SnapshotToast)
-#define IsSnapshotDirty(snapshot) ((Snapshot) (snapshot) == SnapshotDirty)
+extern PGDLLIMPORT Snapshot SerializableSnapshot;
+extern PGDLLIMPORT Snapshot LatestSnapshot;
+extern PGDLLIMPORT Snapshot ActiveSnapshot;
+extern TransactionId TransactionXmin;
+extern TransactionId RecentXmin;
+extern TransactionId RecentGlobalXmin;
/*
* HeapTupleSatisfiesVisibility
* True iff heap tuple satisfies a time qual.
*
* Notes:
- * Assumes heap tuple is valid.
- * Beware of multiple evaluations of snapshot argument.
+ * 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;
+ * if so, the indicated buffer is marked dirty.
*/
-#define HeapTupleSatisfiesVisibility(tuple, snapshot) \
-(IsSnapshotNow(snapshot) ? \
- HeapTupleSatisfiesNow((tuple)->t_data) \
-: \
- (IsSnapshotSelf(snapshot) ? \
- HeapTupleSatisfiesItself((tuple)->t_data) \
- : \
- (IsSnapshotAny(snapshot) ? \
- true \
- : \
- (IsSnapshotToast(snapshot) ? \
- HeapTupleSatisfiesToast((tuple)->t_data) \
- : \
- (IsSnapshotDirty(snapshot) ? \
- HeapTupleSatisfiesDirty((tuple)->t_data) \
- : \
- HeapTupleSatisfiesSnapshot((tuple)->t_data, snapshot) \
- ) \
- ) \
- ) \
- ) \
-)
+#define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer) \
+ ((*(snapshot)->satisfies) ((tuple)->t_data, snapshot, buffer))
/* Result codes for HeapTupleSatisfiesUpdate */
-#define HeapTupleMayBeUpdated 0
-#define HeapTupleInvisible 1
-#define HeapTupleSelfUpdated 2
-#define HeapTupleUpdated 3
-#define HeapTupleBeingUpdated 4
+typedef enum
+{
+ HeapTupleMayBeUpdated,
+ HeapTupleInvisible,
+ HeapTupleSelfUpdated,
+ HeapTupleUpdated,
+ HeapTupleBeingUpdated
+} HTSU_Result;
/* Result codes for HeapTupleSatisfiesVacuum */
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);
-extern bool HeapTupleSatisfiesNow(HeapTupleHeader tuple);
-extern bool HeapTupleSatisfiesDirty(HeapTupleHeader tuple);
-extern bool HeapTupleSatisfiesToast(HeapTupleHeader tuple);
-extern bool HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple,
- Snapshot snapshot);
-extern int HeapTupleSatisfiesUpdate(HeapTuple tuple,
- CommandId curcid);
+/* 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,
- TransactionId OldestXmin);
+ TransactionId OldestXmin, Buffer buffer);
-extern Snapshot GetSnapshotData(bool serializable);
-extern void SetQuerySnapshot(void);
-extern Snapshot CopyQuerySnapshot(void);
+extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
+ uint16 infomask, TransactionId xid);
+
+extern Snapshot GetTransactionSnapshot(void);
+extern Snapshot GetLatestSnapshot(void);
+extern Snapshot CopySnapshot(Snapshot snapshot);
+extern void FreeSnapshot(Snapshot snapshot);
extern void FreeXactSnapshot(void);
+/* in procarray.c; declared here to avoid including tqual.h in procarray.h: */
+extern Snapshot GetSnapshotData(Snapshot snapshot, bool serializable);
+
#endif /* TQUAL_H */