12
12
* Portions Copyright (c) 1994, Regents of the University of California
13
13
*
14
14
* 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 $
16
16
*
17
17
*-------------------------------------------------------------------------
18
18
*/
@@ -668,6 +668,7 @@ AtAbort_Portals(void)
668
668
{
669
669
Portal portal = hentry -> portal ;
670
670
671
+ /* Any portal that was actually running has to be considered broken */
671
672
if (portal -> status == PORTAL_ACTIVE )
672
673
portal -> status = PORTAL_FAILED ;
673
674
@@ -677,6 +678,15 @@ AtAbort_Portals(void)
677
678
if (portal -> createSubid == InvalidSubTransactionId )
678
679
continue ;
679
680
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
+
680
690
/* let portalcmds.c clean up the state it knows about */
681
691
if (PointerIsValid (portal -> cleanup ))
682
692
{
@@ -789,61 +799,41 @@ AtSubAbort_Portals(SubTransactionId mySubid,
789
799
continue ;
790
800
791
801
/*
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.)
798
808
*/
799
- if (portal -> status == PORTAL_ACTIVE )
809
+ if (portal -> status == PORTAL_READY ||
810
+ portal -> status == PORTAL_ACTIVE )
800
811
portal -> status = PORTAL_FAILED ;
801
812
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 ))
814
815
{
815
- portal -> createSubid = parentSubid ;
816
- if (portal -> resowner )
817
- ResourceOwnerNewParent (portal -> resowner , parentXactOwner );
816
+ (* portal -> cleanup ) (portal );
817
+ portal -> cleanup = NULL ;
818
818
}
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
- }
828
819
829
- /* drop cached plan reference, if any */
830
- PortalReleaseCachedPlan (portal );
820
+ /* drop cached plan reference, if any */
821
+ PortalReleaseCachedPlan (portal );
831
822
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 ;
838
829
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 ));
847
837
}
848
838
}
849
839
0 commit comments