@ -12,7 +12,7 @@
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / utils / mmgr / portalmem . c , v 1.116 2010 / 01 / 18 02 : 30 : 25 tgl Exp $
* $ PostgreSQL : pgsql / src / backend / utils / mmgr / portalmem . c , v 1.117 2010 / 02 / 18 03 : 06 : 46 tgl Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -668,6 +668,7 @@ AtAbort_Portals(void)
{
Portal portal = hentry - > portal ;
/* Any portal that was actually running has to be considered broken */
if ( portal - > status = = PORTAL_ACTIVE )
portal - > status = PORTAL_FAILED ;
@ -677,6 +678,15 @@ AtAbort_Portals(void)
if ( portal - > createSubid = = InvalidSubTransactionId )
continue ;
/*
* If it was created in the current transaction , we can ' t do normal
* shutdown on a READY portal either ; it might refer to objects
* created in the failed transaction . See comments in
* AtSubAbort_Portals .
*/
if ( portal - > status = = PORTAL_READY )
portal - > status = PORTAL_FAILED ;
/* let portalcmds.c clean up the state it knows about */
if ( PointerIsValid ( portal - > cleanup ) )
{
@ -789,61 +799,41 @@ AtSubAbort_Portals(SubTransactionId mySubid,
continue ;
/*
* Force any act ive portals of my own transaction into FAILED state .
* This is mostly to ensure that a portal running a FETCH 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 .
* Force any l ive portals of my own sub transaction into FAILED state .
* We have to do this because they might refer to objects created or
* changed in the failed subtransaction , leading to crashes if
* execution is resumed , or even if we just try to run ExecutorEnd .
* ( Note we do NOT do this to upper - level portals , since they cannot
* have such references and hence may be able to continue . )
*/
if ( portal - > status = = PORTAL_ACTIVE )
if ( portal - > status = = PORTAL_READY | |
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 .
*
* Currently , we can ' t actually support that because the portal ' s
* query might refer to objects created or changed in the failed
* subtransaction , leading to crashes if execution is resumed . So ,
* even READY portals are deleted . It would be nice to detect whether
* the query actually depends on any such object , instead .
*/
# ifdef NOT_USED
if ( portal - > status = = PORTAL_READY )
/* let portalcmds.c clean up the state it knows about */
if ( PointerIsValid ( portal - > cleanup ) )
{
portal - > createSubid = parentSubid ;
if ( portal - > resowner )
ResourceOwnerNewParent ( portal - > resowner , parentXactOwner ) ;
( * portal - > cleanup ) ( portal ) ;
portal - > cleanup = NULL ;
}
else
# endif
{
/* let portalcmds.c clean up the state it knows about */
if ( PointerIsValid ( portal - > cleanup ) )
{
( * portal - > cleanup ) ( portal ) ;
portal - > cleanup = NULL ;
}
/* drop cached plan reference, if any */
PortalReleaseCachedPlan ( portal ) ;
/* drop cached plan reference, if any */
PortalReleaseCachedPlan ( portal ) ;
/*
* 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 ;
/*
* 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 ;
/*
* Although we can ' t delete the portal data structure proper , we
* can release any memory in subsidiary contexts , such as executor
* state . The cleanup hook was the last thing that might have
* needed data there .
*/
MemoryContextDeleteChildren ( PortalGetHeapMemory ( portal ) ) ;
}
/*
* Although we can ' t delete the portal data structure proper , we
* can release any memory in subsidiary contexts , such as executor
* state . The cleanup hook was the last thing that might have
* needed data there .
*/
MemoryContextDeleteChildren ( PortalGetHeapMemory ( portal ) ) ;
}
}