Skip to content

Commit fb0741a

Browse files
committed
Assert RI fast-path batches don't span subtransactions
A fast-path batch is filled and flushed within a single trigger-firing cycle, so all rows in a batch come from the subtransaction that created the cache entry. AtEOSubXact_RI() relies on this: it identifies an aborting subtransaction's entries by the subid stamped at entry creation. Assert the invariant in ri_FastPathBatchAdd() to catch any future code that would violate it. Suggested-by: Noah Misch <noah@leadboat.com> Discussion: https://postgr.es/m/20260705222115.be.noahmisch@microsoft.com Backpatch-through: 19
1 parent bfb18f4 commit fb0741a

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

src/backend/utils/adt/ri_triggers.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2907,6 +2907,14 @@ ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo,
29072907
return;
29082908
}
29092909

2910+
/*
2911+
* A batch is filled and flushed within a single trigger-firing cycle, so
2912+
* every row added to an entry comes from the subtransaction that created
2913+
* it. AtEOSubXact_RI() relies on this to identify an aborting
2914+
* subtransaction's entries by the subid stamped at entry creation.
2915+
*/
2916+
Assert(fpentry->subid == GetCurrentSubTransactionId());
2917+
29102918
/*
29112919
* Buffer the row. A full batch is flushed below and re-entry is handled
29122920
* above, so there is always room here; the bounds check just guards the

0 commit comments

Comments
 (0)