*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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");
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);
*
*
* 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.209 2009/10/02 17:57:30 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
}
}
- /*
- * 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
* 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.11 2009/10/02 17:57:30 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
static bool registered_serializable = false;
-static Snapshot CopySnapshot(Snapshot snapshot);
static void FreeSnapshot(Snapshot snapshot);
static void SnapshotResetXmin(void);
* 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;
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/snapmgr.h,v 1.5 2009/06/11 14:49:13 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/snapmgr.h,v 1.6 2009/10/02 17:57:30 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
extern Snapshot GetTransactionSnapshot(void);
extern Snapshot GetLatestSnapshot(void);
extern void SnapshotSetCommandId(CommandId curcid);
+extern Snapshot CopySnapshot(Snapshot snapshot);
extern void PushActiveSnapshot(Snapshot snapshot);
extern void PushUpdatedSnapshot(Snapshot snapshot);
DELETE FROM ucview WHERE CURRENT OF c1; -- fail, views not supported
ERROR: WHERE CURRENT OF on a view is not implemented
ROLLBACK;
+-- Make sure snapshot management works okay, per bug report in
+BEGIN;
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+CREATE TABLE cursor (a int);
+INSERT INTO cursor VALUES (1);
+DECLARE c1 NO SCROLL CURSOR FOR SELECT * FROM cursor FOR UPDATE;
+UPDATE cursor SET a = 2;
+FETCH ALL FROM c1;
+ a
+---
+(0 rows)
+
+COMMIT;
+DROP TABLE cursor;
FETCH FROM c1;
DELETE FROM ucview WHERE CURRENT OF c1; -- fail, views not supported
ROLLBACK;
+
+-- Make sure snapshot management works okay, per bug report in
+BEGIN;
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+CREATE TABLE cursor (a int);
+INSERT INTO cursor VALUES (1);
+DECLARE c1 NO SCROLL CURSOR FOR SELECT * FROM cursor FOR UPDATE;
+UPDATE cursor SET a = 2;
+FETCH ALL FROM c1;
+COMMIT;
+DROP TABLE cursor;