mirror of
https://github.com/postgres/postgres.git
synced 2025-08-22 21:53:06 +03:00
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.
This commit is contained in:
@@ -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.80 2009/10/02 17:57:29 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");
|
||||
@@ -118,10 +119,18 @@ PerformCursorOpen(PlannedStmt *stmt, ParamListInfo params,
|
||||
portal->cursorOptions |= CURSOR_OPT_NO_SCROLL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
Reference in New Issue
Block a user