On Thu, Nov 05, 2026 at 10:40:40PM -0500, Narek Galstyan wrote:
> The commit restores the characteristics right after AbortTransaction()
> when a transaction block fails, so they last until the block ends. A
> failed transaction that was itself started by AND CHAIN already keeps
> them, because they are not set through the GUC stack.
> 
> Bug present since AND CHAIN was added in v12.

Sounds like a valid complaint to me.

@@ -3547,6 +3547,7 @@ static bool
 AbortCurrentTransactionInternal(void)
 {
     TransactionState s = CurrentTransactionState;
+    SavedTransactionCharacteristics savetc;
 
     switch (s->blockState)
     {
@@ -3603,7 +3604,10 @@ AbortCurrentTransactionInternal(void)
              */
         case TBLOCK_INPROGRESS:
         case TBLOCK_PARALLEL_INPROGRESS:
+            /* Restore characteristics in case AND CHAIN is coming */
+            SaveTransactionCharacteristics(&savetc);
             AbortTransaction();
+            RestoreTransactionCharacteristics(&savetc);
             s->blockState = TBLOCK_ABORT;
             /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
             break;

How about being consistent with CommitTransactionCommandInternal(),
where the state is saved at the top of the function and then restored
in the blocks required?

Do we have other blocks where we may want to case about a restore of
the state and some of the characteristics?  I have not double-checked,
but...
--
Michael

Attachment: signature.asc
Description: PGP signature

Reply via email to