Index: doc/src/sgml/ref/rollback_to.sgml =================================================================== RCS file: /home/alvherre/cvs/pgsql/doc/src/sgml/ref/rollback_to.sgml,v retrieving revision 1.5 diff -c -r1.5 rollback_to.sgml *** doc/src/sgml/ref/rollback_to.sgml 27 Nov 2004 21:27:07 -0000 1.5 --- doc/src/sgml/ref/rollback_to.sgml 26 Jan 2005 21:15:18 -0000 *************** *** 74,81 **** Cursors have somewhat non-transactional behavior with respect to ! savepoints. Any cursor that is opened inside the savepoint is not closed ! when the savepoint is rolled back. If a cursor is affected by a FETCH command inside a savepoint that is later rolled back, the cursor position remains at the position that FETCH left it pointing to (that is, FETCH is not rolled back). --- 74,83 ---- Cursors have somewhat non-transactional behavior with respect to ! savepoints. Any cursor that is opened inside the savepoint is closed ! when the savepoint is rolled back, and a cursor that is closed inside ! the savepoint remains closed if the savepoint is rolled back. ! If a cursor is affected by a FETCH command inside a savepoint that is later rolled back, the cursor position remains at the position that FETCH left it pointing to (that is, FETCH is not rolled back). Index: src/backend/utils/mmgr/portalmem.c =================================================================== RCS file: /home/alvherre/cvs/pgsql/src/backend/utils/mmgr/portalmem.c,v retrieving revision 1.76 diff -c -r1.76 portalmem.c *** src/backend/utils/mmgr/portalmem.c 31 Dec 2004 22:02:48 -0000 1.76 --- src/backend/utils/mmgr/portalmem.c 26 Jan 2005 22:36:17 -0000 *************** *** 601,609 **** /* * Subtransaction abort handling for portals. * ! * Deactivate failed portals created during the failed subtransaction. * Note that per AtSubCommit_Portals, this will catch portals created * in descendants of the subtransaction too. */ void AtSubAbort_Portals(SubTransactionId mySubid, --- 601,612 ---- /* * Subtransaction abort handling for portals. * ! * Deactivate portals created during the failed subtransaction. * Note that per AtSubCommit_Portals, this will catch portals created * in descendants of the subtransaction too. + * + * Note that we don't destroy any portals here; that's done in + * AtSubCleanup_Portals. */ void AtSubAbort_Portals(SubTransactionId mySubid, *************** *** 628,663 **** * will go FAILED if the underlying cursor fails. (Note we do NOT * want to do this to upper-level portals, since they may be able * to continue.) */ if (portal->status == PORTAL_ACTIVE) portal->status = PORTAL_FAILED; ! /* ! * If the portal is READY then allow it to survive into the parent ! * transaction; otherwise shut it down. ! */ ! if (portal->status == PORTAL_READY) ! { ! portal->createSubid = parentSubid; ! if (portal->resowner) ! ResourceOwnerNewParent(portal->resowner, parentXactOwner); ! } ! else { ! /* let portalcmds.c clean up the state it knows about */ ! if (PointerIsValid(portal->cleanup)) ! { ! (*portal->cleanup) (portal); ! portal->cleanup = NULL; ! } ! ! /* ! * Any resources belonging to the portal will be released in ! * the upcoming transaction-wide cleanup; they will be gone ! * before we run PortalDrop. ! */ ! portal->resowner = NULL; } } } --- 631,655 ---- * will go FAILED if the underlying cursor fails. (Note we do NOT * want to do this to upper-level portals, since they may be able * to continue.) + * + * This is only needed to dodge the sanity check in PortalDrop. */ if (portal->status == PORTAL_ACTIVE) portal->status = PORTAL_FAILED; ! /* let portalcmds.c clean up the state it knows about */ ! if (PointerIsValid(portal->cleanup)) { ! (*portal->cleanup) (portal); ! portal->cleanup = NULL; } + + /* + * Any resources belonging to the portal will be released in + * the upcoming transaction-wide cleanup; they will be gone + * before we run PortalDrop. + */ + portal->resowner = NULL; } }