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 /18 02:30:25 tgl Exp $
15+ * $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.117 2010/02 /18 03:06:46 tgl Exp $
1616 *
1717 *-------------------------------------------------------------------------
1818 */
@@ -668,6 +668,7 @@ AtAbort_Portals(void)
668668 {
669669 Portal portal = hentry -> portal ;
670670
671+ /* Any portal that was actually running has to be considered broken */
671672 if (portal -> status == PORTAL_ACTIVE )
672673 portal -> status = PORTAL_FAILED ;
673674
@@ -677,6 +678,15 @@ AtAbort_Portals(void)
677678 if (portal -> createSubid == InvalidSubTransactionId )
678679 continue ;
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 */
681691 if (PointerIsValid (portal -> cleanup ))
682692 {
@@ -789,61 +799,41 @@ AtSubAbort_Portals(SubTransactionId mySubid,
789799 continue ;
790800
791801 /*
792- * Force any active portals of my own transaction into FAILED state.
793- * This is mostly to ensure that a portal running a FETCH will go
794- * FAILED if the underlying cursor fails. (Note we do NOT want to do
795- * this to upper-level portals, since they may be able to continue.)
796- *
797- * This is only needed to dodge the sanity check in PortalDrop.
802+ * Force any live portals of my own subtransaction into FAILED state.
803+ * We have to do this because they might refer to objects created or
804+ * changed in the failed subtransaction, leading to crashes if
805+ * execution is resumed, or even if we just try to run 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 )
800811 portal -> 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
0 commit comments