@@ -269,7 +269,7 @@ static TransactionId RecordTransactionAbort(bool isSubXact);
269269static void StartTransaction (void );
270270
271271static void StartSubTransaction (void );
272- static void CommitSubTransaction (bool isTopLevel );
272+ static void CommitSubTransaction (void );
273273static void AbortSubTransaction (void );
274274static void CleanupSubTransaction (void );
275275static void PushTransaction (void );
@@ -2578,7 +2578,7 @@ CommitTransactionCommand(void)
25782578 case TBLOCK_SUBRELEASE :
25792579 do
25802580 {
2581- CommitSubTransaction (false );
2581+ CommitSubTransaction ();
25822582 s = CurrentTransactionState ; /* changed by pop */
25832583 } while (s -> blockState == TBLOCK_SUBRELEASE );
25842584
@@ -2588,12 +2588,17 @@ CommitTransactionCommand(void)
25882588
25892589 /*
25902590 * We were issued a COMMIT, so we end the current subtransaction
2591- * hierarchy and perform final commit.
2591+ * hierarchy and perform final commit. We do this by rolling up
2592+ * any subtransactions into their parent, which leads to O(N^2)
2593+ * operations with respect to resource owners - this isn't that
2594+ * bad until we approach a thousands of savepoints but is necessary
2595+ * for correctness should after triggers create new resource
2596+ * owners.
25922597 */
25932598 case TBLOCK_SUBCOMMIT :
25942599 do
25952600 {
2596- CommitSubTransaction (true );
2601+ CommitSubTransaction ();
25972602 s = CurrentTransactionState ; /* changed by pop */
25982603 } while (s -> blockState == TBLOCK_SUBCOMMIT );
25992604 /* If we had a COMMIT command, finish off the main xact too */
@@ -3745,7 +3750,7 @@ ReleaseCurrentSubTransaction(void)
37453750 BlockStateAsString (s -> blockState ));
37463751 Assert (s -> state == TRANS_INPROGRESS );
37473752 MemoryContextSwitchTo (CurTransactionContext );
3748- CommitSubTransaction (false );
3753+ CommitSubTransaction ();
37493754 s = CurrentTransactionState ; /* changed by pop */
37503755 Assert (s -> state == TRANS_INPROGRESS );
37513756}
@@ -4009,13 +4014,9 @@ StartSubTransaction(void)
40094014 *
40104015 * The caller has to make sure to always reassign CurrentTransactionState
40114016 * if it has a local pointer to it after calling this function.
4012- *
4013- * isTopLevel means that this CommitSubTransaction() is being issued as a
4014- * sequence of actions leading directly to a main transaction commit
4015- * allowing some actions to be optimised.
40164017 */
40174018static void
4018- CommitSubTransaction (bool isTopLevel )
4019+ CommitSubTransaction (void )
40194020{
40204021 TransactionState s = CurrentTransactionState ;
40214022
@@ -4069,14 +4070,10 @@ CommitSubTransaction(bool isTopLevel)
40694070
40704071 /*
40714072 * Other locks should get transferred to their parent resource owner.
4072- * Doing that is an O(N^2) operation, so if isTopLevel then we can just
4073- * leave the lock records as they are, knowing they will all get released
4074- * by the top level commit using ProcReleaseLocks(). We only optimize
4075- * this for commit; aborts may need to do other cleanup.
40764073 */
40774074 ResourceOwnerRelease (s -> curTransactionOwner ,
40784075 RESOURCE_RELEASE_LOCKS ,
4079- true, isTopLevel );
4076+ true, false );
40804077 ResourceOwnerRelease (s -> curTransactionOwner ,
40814078 RESOURCE_RELEASE_AFTER_LOCKS ,
40824079 true, false);
0 commit comments