aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2009-10-02 17:58:21 +0000
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2009-10-02 17:58:21 +0000
commitae35363dced47a99178b4a4129e3ea1f990b829c (patch)
treec0a113330d1b9039764b82a1e59820c420b6fe7a /src/backend
parentd4bd8423c9939a30f0f29e70745917e4635b4973 (diff)
downloadpostgresql-ae35363dced47a99178b4a4129e3ea1f990b829c.tar.gz
postgresql-ae35363dced47a99178b4a4129e3ea1f990b829c.zip
Ensure that a cursor has an immutable snapshot throughout its lifespan.
The old coding was using a regular snapshot, referenced elsewhere, that was subject to having its command counter updated. Fix by creating a private copy of the snapshot exclusively for the cursor. Backpatch to 8.4, which is when the bug was introduced during the snapshot management rewrite.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/portalcmds.c13
-rw-r--r--src/backend/executor/spi.c7
-rw-r--r--src/backend/utils/time/snapmgr.c5
3 files changed, 15 insertions, 10 deletions
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index 17192341739..d31fde65b6b 100644
--- a/src/backend/commands/portalcmds.c
+++ b/src/backend/commands/portalcmds.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.79 2009/06/11 14:48:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.79.2.1 2009/10/02 17:58:21 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -47,6 +47,7 @@ PerformCursorOpen(PlannedStmt *stmt, ParamListInfo params,
DeclareCursorStmt *cstmt = (DeclareCursorStmt *) stmt->utilityStmt;
Portal portal;
MemoryContext oldContext;
+ Snapshot snapshot;
if (cstmt == NULL || !IsA(cstmt, DeclareCursorStmt))
elog(ERROR, "PerformCursorOpen called for non-cursor query");
@@ -119,9 +120,17 @@ PerformCursorOpen(PlannedStmt *stmt, ParamListInfo params,
}
/*
+ * Set up snapshot for portal. Note that we need a fresh, independent copy
+ * of the snapshot because we don't want it to be modified by future
+ * CommandCounterIncrement calls. We do not register it, because
+ * portalmem.c will take care of that internally.
+ */
+ snapshot = CopySnapshot(GetActiveSnapshot());
+
+ /*
* Start execution, inserting parameters if any.
*/
- PortalStart(portal, params, GetActiveSnapshot());
+ PortalStart(portal, params, snapshot);
Assert(portal->strategy == PORTAL_ONE_SELECT);
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 40f43ee011b..3cffc2ad72b 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.208 2009/06/11 14:48:57 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.208.2.1 2009/10/02 17:58:21 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1211,10 +1211,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
}
}
- /*
- * Set up the snapshot to use. (PortalStart will do PushActiveSnapshot,
- * so we skip that here.)
- */
+ /* Set up the snapshot to use. */
if (read_only)
snapshot = GetActiveSnapshot();
else
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 73d597d7b37..12ca81616d1 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -19,7 +19,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/time/snapmgr.c,v 1.10 2009/06/11 14:49:06 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/time/snapmgr.c,v 1.10.2.1 2009/10/02 17:58:21 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -104,7 +104,6 @@ bool FirstSnapshotSet = false;
static bool registered_serializable = false;
-static Snapshot CopySnapshot(Snapshot snapshot);
static void FreeSnapshot(Snapshot snapshot);
static void SnapshotResetXmin(void);
@@ -192,7 +191,7 @@ SnapshotSetCommandId(CommandId curcid)
* The copy is palloc'd in TopTransactionContext and has initial refcounts set
* to 0. The returned snapshot has the copied flag set.
*/
-static Snapshot
+Snapshot
CopySnapshot(Snapshot snapshot)
{
Snapshot newsnap;