1212 * Portions Copyright (c) 1994, Regents of the University of California
1313 *
1414 * IDENTIFICATION
15- * $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.116 2010/01 /1802:30:25 tgl Exp $
15+ * $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.117 2010/02 /1803:06:46 tgl Exp $
1616 *
1717 *-------------------------------------------------------------------------
1818 */
@@ -668,6 +668,7 @@ AtAbort_Portals(void)
668668{
669669Portal portal = hentry -> portal ;
670670
671+ /* Any portal that was actually running has to be considered broken */
671672if (portal -> status == PORTAL_ACTIVE )
672673portal -> status = PORTAL_FAILED ;
673674
@@ -677,6 +678,15 @@ AtAbort_Portals(void)
677678if (portal -> createSubid == InvalidSubTransactionId )
678679continue ;
679680
681+ /*
682+ * If it was created in the current transaction, we can't do normal
683+ * shutdown on a READY portal either; it might refer to objects
684+ * created in the failed transaction. See comments in
685+ * AtSubAbort_Portals.
686+ */
687+ if (portal -> status == PORTAL_READY )
688+ portal -> status = PORTAL_FAILED ;
689+
680690/* let portalcmds.c clean up the state it knows about */
681691if (PointerIsValid (portal -> cleanup ))
682692{
@@ -789,61 +799,41 @@ AtSubAbort_Portals(SubTransactionId mySubid,
789799continue ;
790800
791801/*
792- * Force anyactive portals of my owntransaction into FAILED state.
793- *This is mostly toensure that a portal running a FETCH will go
794- *FAILED if theunderlying cursor fails. (Note we do NOT want todo
795- *this to upper-level portals, since they may be able tocontinue.)
796- *
797- *This is only needed to dodge the sanity check in PortalDrop.
802+ * Force anylive portals of my ownsubtransaction into FAILED state.
803+ *We have todo this because they might refer to objects created or
804+ *changed in thefailed subtransaction, leading tocrashes if
805+ *execution is resumed, or even if we just try torun ExecutorEnd.
806+ * (Note we do NOT do this to upper-level portals, since they cannot
807+ *have such references and hence may be able to continue.)
798808 */
799- if (portal -> status == PORTAL_ACTIVE )
809+ if (portal -> status == PORTAL_READY ||
810+ portal -> status == PORTAL_ACTIVE )
800811portal -> status = PORTAL_FAILED ;
801812
802- /*
803- * If the portal is READY then allow it to survive into the parent
804- * transaction; otherwise shut it down.
805- *
806- * Currently, we can't actually support that because the portal's
807- * query might refer to objects created or changed in the failed
808- * subtransaction, leading to crashes if execution is resumed. So,
809- * even READY portals are deleted.It would be nice to detect whether
810- * the query actually depends on any such object, instead.
811- */
812- #ifdef NOT_USED
813- if (portal -> status == PORTAL_READY )
813+ /* let portalcmds.c clean up the state it knows about */
814+ if (PointerIsValid (portal -> cleanup ))
814815{
815- portal -> createSubid = parentSubid ;
816- if (portal -> resowner )
817- ResourceOwnerNewParent (portal -> resowner ,parentXactOwner );
816+ (* portal -> cleanup ) (portal );
817+ portal -> cleanup = NULL ;
818818}
819- else
820- #endif
821- {
822- /* let portalcmds.c clean up the state it knows about */
823- if (PointerIsValid (portal -> cleanup ))
824- {
825- (* portal -> cleanup ) (portal );
826- portal -> cleanup = NULL ;
827- }
828819
829- /* drop cached plan reference, if any */
830- PortalReleaseCachedPlan (portal );
820+ /* drop cached plan reference, if any */
821+ PortalReleaseCachedPlan (portal );
831822
832- /*
833- * Any resources belonging to the portal will be released in the
834- * upcoming transaction-wide cleanup; they will be gone before we
835- * run PortalDrop.
836- */
837- portal -> resowner = NULL ;
823+ /*
824+ * Any resources belonging to the portal will be released in the
825+ * upcoming transaction-wide cleanup; they will be gone before we
826+ * run PortalDrop.
827+ */
828+ portal -> resowner = NULL ;
838829
839- /*
840- * Although we can't delete the portal data structure proper, we
841- * can release any memory in subsidiary contexts, such as executor
842- * state. The cleanup hook was the last thing that might have
843- * needed data there.
844- */
845- MemoryContextDeleteChildren (PortalGetHeapMemory (portal ));
846- }
830+ /*
831+ * Although we can't delete the portal data structure proper, we
832+ * can release any memory in subsidiary contexts, such as executor
833+ * state. The cleanup hook was the last thing that might have
834+ * needed data there.
835+ */
836+ MemoryContextDeleteChildren (PortalGetHeapMemory (portal ));
847837}
848838}
849839