This one really works and includes a basic test case. You were right
that the extra Register was bogus :-( I had to expose CopySnapshot,
which I still don't like but ... (I could have added an extra
Unregister somewhere during portal close, but it would have meant making
everything messier).
--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
*** src/backend/commands/portalcmds.c 11 Jun 2009 14:48:56 -0000 1.79
--- src/backend/commands/portalcmds.c 1 Oct 2009 23:24:33 -0000
***************
*** 47,52 ****
--- 47,53 ----
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,127 ****
}
/*
* Start execution, inserting parameters if any.
*/
! PortalStart(portal, params, GetActiveSnapshot());
Assert(portal->strategy == PORTAL_ONE_SELECT);
--- 120,136 ----
}
/*
+ * 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, snapshot);
Assert(portal->strategy == PORTAL_ONE_SELECT);
*** src/backend/executor/spi.c 11 Jun 2009 14:48:57 -0000 1.208
--- src/backend/executor/spi.c 1 Oct 2009 23:26:31 -0000
***************
*** 1211,1220 ****
}
}
! /*
! * Set up the snapshot to use. (PortalStart will do PushActiveSnapshot,
! * so we skip that here.)
! */
if (read_only)
snapshot = GetActiveSnapshot();
else
--- 1211,1217 ----
}
}
! /* Set up the snapshot to use. */
if (read_only)
snapshot = GetActiveSnapshot();
else
*** src/backend/utils/time/snapmgr.c 11 Jun 2009 14:49:06 -0000 1.10
--- src/backend/utils/time/snapmgr.c 1 Oct 2009 23:29:05 -0000
***************
*** 104,110 ****
static bool registered_serializable = false;
- static Snapshot CopySnapshot(Snapshot snapshot);
static void FreeSnapshot(Snapshot snapshot);
static void SnapshotResetXmin(void);
--- 104,109 ----
***************
*** 192,198 ****
* The copy is palloc'd in TopTransactionContext and has initial refcounts set
* to 0. The returned snapshot has the copied flag set.
*/
! static Snapshot
CopySnapshot(Snapshot snapshot)
{
Snapshot newsnap;
--- 191,197 ----
* The copy is palloc'd in TopTransactionContext and has initial refcounts set
* to 0. The returned snapshot has the copied flag set.
*/
! Snapshot
CopySnapshot(Snapshot snapshot)
{
Snapshot newsnap;
*** src/include/utils/snapmgr.h 11 Jun 2009 14:49:13 -0000 1.5
--- src/include/utils/snapmgr.h 1 Oct 2009 23:28:19 -0000
***************
*** 26,31 ****
--- 26,32 ----
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);
*** src/test/regress/expected/portals.out 27 Jan 2009 12:40:15 -0000 1.21
--- src/test/regress/expected/portals.out 1 Oct 2009 23:44:17 -0000
***************
*** 1242,1244 ****
--- 1242,1259 ----
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
+ -- [email protected]
+ 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;
*** src/test/regress/sql/portals.sql 16 Nov 2008 17:34:28 -0000 1.16
--- src/test/regress/sql/portals.sql 1 Oct 2009 23:39:08 -0000
***************
*** 458,460 ****
--- 458,472 ----
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
+ -- [email protected]
+ 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;
--
Sent via pgsql-general mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general