aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-02-06 22:49:30 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-02-06 22:49:30 +0000
commit04dc48b5280bf692b4995ce9d4f80a5e75eb7074 (patch)
tree2473cd166124ce006bb15ae056d35d970c68a688
parentb93d4a75a037f5b5717f2de48f681fcc7336df0f (diff)
downloadpostgresql-04dc48b5280bf692b4995ce9d4f80a5e75eb7074.tar.gz
postgresql-04dc48b5280bf692b4995ce9d4f80a5e75eb7074.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.
-rw-r--r--src/backend/commands/portalcmds.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index 72d3eadcbfb..0fefb66174f 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.57 2006/10/19 19:53:03 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.57.2.1 2007/02/06 22:49:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -392,15 +392,23 @@ PersistHoldablePortal(Portal portal)
ExecutorEnd(queryDesc);
/*
- * Reset the position in the result set: ideally, this could be
+ * Set the position in the result set: ideally, this could be
* implemented by just skipping straight to the tuple # that we need
* to be at, but the tuplestore API doesn't support that. So we start
* at the beginning of the tuplestore and iterate through it until we
- * reach where we need to be. FIXME someday?
+ * reach where we need to be. FIXME someday? (Fortunately, the
+ * typical case is that we're supposed to be at or near the start
+ * of the result set, so this isn't as bad as it sounds.)
*/
MemoryContextSwitchTo(portal->holdContext);
- if (!portal->atEnd)
+ if (portal->atEnd)
+ {
+ /* we can handle this case even if posOverflow */
+ while (tuplestore_advance(portal->holdStore, true))
+ /* continue */ ;
+ }
+ else
{
long store_pos;