aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-02-06 22:49:48 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-02-06 22:49:48 +0000
commitdec65c942116f6b21222f29627a79cb133740879 (patch)
tree76bc6c2800d20bbfb4011acdcb305f02a718d9f9 /src
parentf0083ccfde0cfc5028afe8c3a6d647f627516b61 (diff)
downloadpostgresql-dec65c942116f6b21222f29627a79cb133740879.tar.gz
postgresql-dec65c942116f6b21222f29627a79cb133740879.zip
Fix an error in the original coding of holdable cursors: PersistHoldablePortal
thought that it didn't have to reposition the underlying tuplestore if the portal is atEnd. But this is not so, because tuplestores have separate read and write cursors ... and the read cursor hasn't moved from the start. This mistake explains bug #2970 from William Zhang. Note: the coding here is pretty inefficient, but given that no one has noticed this bug until now, I'd say hardly anyone uses the case where the cursor has been advanced before being persisted. So maybe it's not worth worrying about.
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/portalcmds.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index 8c4c9fe282d..7263495d548 100644
--- a/src/backend/commands/portalcmds.c
+++ b/src/backend/commands/portalcmds.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.24.2.1 2004/11/28 22:16:49 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.24.2.2 2007/02/06 22:49:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -363,7 +363,20 @@ PersistHoldablePortal(Portal portal)
*/
MemoryContextSwitchTo(portal->holdContext);
- if (!portal->atEnd)
+ if (portal->atEnd)
+ {
+ /* we can handle this case even if posOverflow */
+ HeapTuple tup;
+ bool should_free;
+
+ while ((tup = tuplestore_gettuple(portal->holdStore, true,
+ &should_free)) != NULL)
+ {
+ if (should_free)
+ pfree(tup);
+ }
+ }
+ else
{
long store_pos;