]> granicus.if.org Git - postgresql/commitdiff
Fix an error in the original coding of holdable cursors: PersistHoldablePortal
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 6 Feb 2007 22:49:48 +0000 (22:49 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 6 Feb 2007 22:49:48 +0000 (22:49 +0000)
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.

src/backend/commands/portalcmds.c

index 8c4c9fe282d8d37fdcb9f650ae3ff0b6ef2de36c..7263495d548e58cf4b64707640916ff197152315 100644 (file)
@@ -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;