summaryrefslogtreecommitdiff
path: root/src/backend/utils/time
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/time')
-rw-r--r--src/backend/utils/time/Makefile4
-rw-r--r--src/backend/utils/time/snapmgmt.c172
-rw-r--r--src/backend/utils/time/tqual.c153
3 files changed, 175 insertions, 154 deletions
diff --git a/src/backend/utils/time/Makefile b/src/backend/utils/time/Makefile
index 5e886d425e..68b13e4c39 100644
--- a/src/backend/utils/time/Makefile
+++ b/src/backend/utils/time/Makefile
@@ -4,7 +4,7 @@
# Makefile for utils/time
#
# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/utils/time/Makefile,v 1.13 2008/02/19 10:30:09 petere Exp $
+# $PostgreSQL: pgsql/src/backend/utils/time/Makefile,v 1.14 2008/03/26 16:20:47 alvherre Exp $
#
#-------------------------------------------------------------------------
@@ -12,6 +12,6 @@ subdir = src/backend/utils/time
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
-OBJS = combocid.o tqual.o
+OBJS = combocid.o tqual.o snapmgmt.o
include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/utils/time/snapmgmt.c b/src/backend/utils/time/snapmgmt.c
new file mode 100644
index 0000000000..b406b4bc69
--- /dev/null
+++ b/src/backend/utils/time/snapmgmt.c
@@ -0,0 +1,172 @@
+/*-------------------------------------------------------------------------
+ * snapmgmt.c
+ * PostgreSQL snapshot management code.
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/time/snapmgmt.c,v 1.1 2008/03/26 16:20:47 alvherre Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/xact.h"
+#include "access/transam.h"
+#include "storage/procarray.h"
+#include "utils/snapmgmt.h"
+#include "utils/tqual.h"
+
+
+/*
+ * These SnapshotData structs are static to simplify memory allocation
+ * (see the hack in GetSnapshotData to avoid repeated malloc/free).
+ */
+static SnapshotData SerializableSnapshotData = {HeapTupleSatisfiesMVCC};
+static SnapshotData LatestSnapshotData = {HeapTupleSatisfiesMVCC};
+
+/* Externally visible pointers to valid snapshots: */
+Snapshot SerializableSnapshot = NULL;
+Snapshot LatestSnapshot = NULL;
+
+/*
+ * This pointer is not maintained by this module, but it's convenient
+ * to declare it here anyway. Callers typically assign a copy of
+ * GetTransactionSnapshot's result to ActiveSnapshot.
+ */
+Snapshot ActiveSnapshot = NULL;
+
+/*
+ * These are updated by GetSnapshotData. We initialize them this way
+ * for the convenience of TransactionIdIsInProgress: even in bootstrap
+ * mode, we don't want it to say that BootstrapTransactionId is in progress.
+ */
+TransactionId TransactionXmin = FirstNormalTransactionId;
+TransactionId RecentXmin = FirstNormalTransactionId;
+TransactionId RecentGlobalXmin = FirstNormalTransactionId;
+
+
+/*
+ * GetTransactionSnapshot
+ * Get the appropriate snapshot for a new query in a transaction.
+ *
+ * The SerializableSnapshot is the first one taken in a transaction.
+ * In serializable mode we just use that one throughout the transaction.
+ * In read-committed mode, we take a new snapshot each time we are called.
+ *
+ * Note that the return value points at static storage that will be modified
+ * by future calls and by CommandCounterIncrement(). Callers should copy
+ * the result with CopySnapshot() if it is to be used very long.
+ */
+Snapshot
+GetTransactionSnapshot(void)
+{
+ /* First call in transaction? */
+ if (SerializableSnapshot == NULL)
+ {
+ SerializableSnapshot = GetSnapshotData(&SerializableSnapshotData, true);
+ return SerializableSnapshot;
+ }
+
+ if (IsXactIsoLevelSerializable)
+ return SerializableSnapshot;
+
+ LatestSnapshot = GetSnapshotData(&LatestSnapshotData, false);
+
+ return LatestSnapshot;
+}
+
+/*
+ * GetLatestSnapshot
+ * Get a snapshot that is up-to-date as of the current instant,
+ * even if we are executing in SERIALIZABLE mode.
+ */
+Snapshot
+GetLatestSnapshot(void)
+{
+ /* Should not be first call in transaction */
+ if (SerializableSnapshot == NULL)
+ elog(ERROR, "no snapshot has been set");
+
+ LatestSnapshot = GetSnapshotData(&LatestSnapshotData, false);
+
+ return LatestSnapshot;
+}
+
+/*
+ * CopySnapshot
+ * Copy the given snapshot.
+ *
+ * The copy is palloc'd in the current memory context.
+ */
+Snapshot
+CopySnapshot(Snapshot snapshot)
+{
+ Snapshot newsnap;
+ Size subxipoff;
+ Size size;
+
+ /* We allocate any XID arrays needed in the same palloc block. */
+ size = subxipoff = sizeof(SnapshotData) +
+ snapshot->xcnt * sizeof(TransactionId);
+ if (snapshot->subxcnt > 0)
+ size += snapshot->subxcnt * sizeof(TransactionId);
+
+ newsnap = (Snapshot) palloc(size);
+ memcpy(newsnap, snapshot, sizeof(SnapshotData));
+
+ /* setup XID array */
+ if (snapshot->xcnt > 0)
+ {
+ newsnap->xip = (TransactionId *) (newsnap + 1);
+ memcpy(newsnap->xip, snapshot->xip,
+ snapshot->xcnt * sizeof(TransactionId));
+ }
+ else
+ newsnap->xip = NULL;
+
+ /* setup subXID array */
+ if (snapshot->subxcnt > 0)
+ {
+ newsnap->subxip = (TransactionId *) ((char *) newsnap + subxipoff);
+ memcpy(newsnap->subxip, snapshot->subxip,
+ snapshot->subxcnt * sizeof(TransactionId));
+ }
+ else
+ newsnap->subxip = NULL;
+
+ return newsnap;
+}
+
+/*
+ * FreeSnapshot
+ * Free a snapshot previously copied with CopySnapshot.
+ *
+ * This is currently identical to pfree, but is provided for cleanliness.
+ *
+ * Do *not* apply this to the results of GetTransactionSnapshot or
+ * GetLatestSnapshot, since those are just static structs.
+ */
+void
+FreeSnapshot(Snapshot snapshot)
+{
+ pfree(snapshot);
+}
+
+/*
+ * FreeXactSnapshot
+ * Free snapshot(s) at end of transaction.
+ */
+void
+FreeXactSnapshot(void)
+{
+ /*
+ * We do not free the xip arrays for the static snapshot structs; they
+ * will be reused soon. So this is now just a state change to prevent
+ * outside callers from accessing the snapshots.
+ */
+ SerializableSnapshot = NULL;
+ LatestSnapshot = NULL;
+ ActiveSnapshot = NULL; /* just for cleanliness */
+}
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c
index 6fbc935a6b..b6737d4069 100644
--- a/src/backend/utils/time/tqual.c
+++ b/src/backend/utils/time/tqual.c
@@ -31,7 +31,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.109 2008/01/01 19:45:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.110 2008/03/26 16:20:47 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,33 +53,6 @@ SnapshotData SnapshotSelfData = {HeapTupleSatisfiesSelf};
SnapshotData SnapshotAnyData = {HeapTupleSatisfiesAny};
SnapshotData SnapshotToastData = {HeapTupleSatisfiesToast};
-/*
- * These SnapshotData structs are static to simplify memory allocation
- * (see the hack in GetSnapshotData to avoid repeated malloc/free).
- */
-static SnapshotData SerializableSnapshotData = {HeapTupleSatisfiesMVCC};
-static SnapshotData LatestSnapshotData = {HeapTupleSatisfiesMVCC};
-
-/* Externally visible pointers to valid snapshots: */
-Snapshot SerializableSnapshot = NULL;
-Snapshot LatestSnapshot = NULL;
-
-/*
- * This pointer is not maintained by this module, but it's convenient
- * to declare it here anyway. Callers typically assign a copy of
- * GetTransactionSnapshot's result to ActiveSnapshot.
- */
-Snapshot ActiveSnapshot = NULL;
-
-/*
- * These are updated by GetSnapshotData. We initialize them this way
- * for the convenience of TransactionIdIsInProgress: even in bootstrap
- * mode, we don't want it to say that BootstrapTransactionId is in progress.
- */
-TransactionId TransactionXmin = FirstNormalTransactionId;
-TransactionId RecentXmin = FirstNormalTransactionId;
-TransactionId RecentGlobalXmin = FirstNormalTransactionId;
-
/* local functions */
static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
@@ -1236,130 +1209,6 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
/*
- * GetTransactionSnapshot
- * Get the appropriate snapshot for a new query in a transaction.
- *
- * The SerializableSnapshot is the first one taken in a transaction.
- * In serializable mode we just use that one throughout the transaction.
- * In read-committed mode, we take a new snapshot each time we are called.
- *
- * Note that the return value points at static storage that will be modified
- * by future calls and by CommandCounterIncrement(). Callers should copy
- * the result with CopySnapshot() if it is to be used very long.
- */
-Snapshot
-GetTransactionSnapshot(void)
-{
- /* First call in transaction? */
- if (SerializableSnapshot == NULL)
- {
- SerializableSnapshot = GetSnapshotData(&SerializableSnapshotData, true);
- return SerializableSnapshot;
- }
-
- if (IsXactIsoLevelSerializable)
- return SerializableSnapshot;
-
- LatestSnapshot = GetSnapshotData(&LatestSnapshotData, false);
-
- return LatestSnapshot;
-}
-
-/*
- * GetLatestSnapshot
- * Get a snapshot that is up-to-date as of the current instant,
- * even if we are executing in SERIALIZABLE mode.
- */
-Snapshot
-GetLatestSnapshot(void)
-{
- /* Should not be first call in transaction */
- if (SerializableSnapshot == NULL)
- elog(ERROR, "no snapshot has been set");
-
- LatestSnapshot = GetSnapshotData(&LatestSnapshotData, false);
-
- return LatestSnapshot;
-}
-
-/*
- * CopySnapshot
- * Copy the given snapshot.
- *
- * The copy is palloc'd in the current memory context.
- */
-Snapshot
-CopySnapshot(Snapshot snapshot)
-{
- Snapshot newsnap;
- Size subxipoff;
- Size size;
-
- /* We allocate any XID arrays needed in the same palloc block. */
- size = subxipoff = sizeof(SnapshotData) +
- snapshot->xcnt * sizeof(TransactionId);
- if (snapshot->subxcnt > 0)
- size += snapshot->subxcnt * sizeof(TransactionId);
-
- newsnap = (Snapshot) palloc(size);
- memcpy(newsnap, snapshot, sizeof(SnapshotData));
-
- /* setup XID array */
- if (snapshot->xcnt > 0)
- {
- newsnap->xip = (TransactionId *) (newsnap + 1);
- memcpy(newsnap->xip, snapshot->xip,
- snapshot->xcnt * sizeof(TransactionId));
- }
- else
- newsnap->xip = NULL;
-
- /* setup subXID array */
- if (snapshot->subxcnt > 0)
- {
- newsnap->subxip = (TransactionId *) ((char *) newsnap + subxipoff);
- memcpy(newsnap->subxip, snapshot->subxip,
- snapshot->subxcnt * sizeof(TransactionId));
- }
- else
- newsnap->subxip = NULL;
-
- return newsnap;
-}
-
-/*
- * FreeSnapshot
- * Free a snapshot previously copied with CopySnapshot.
- *
- * This is currently identical to pfree, but is provided for cleanliness.
- *
- * Do *not* apply this to the results of GetTransactionSnapshot or
- * GetLatestSnapshot, since those are just static structs.
- */
-void
-FreeSnapshot(Snapshot snapshot)
-{
- pfree(snapshot);
-}
-
-/*
- * FreeXactSnapshot
- * Free snapshot(s) at end of transaction.
- */
-void
-FreeXactSnapshot(void)
-{
- /*
- * We do not free the xip arrays for the static snapshot structs; they
- * will be reused soon. So this is now just a state change to prevent
- * outside callers from accessing the snapshots.
- */
- SerializableSnapshot = NULL;
- LatestSnapshot = NULL;
- ActiveSnapshot = NULL; /* just for cleanliness */
-}
-
-/*
* XidInMVCCSnapshot
* Is the given XID still-in-progress according to the snapshot?
*