Skip to content

Commit b8a606e

Browse files
committed
Fix assertions with RI triggers in heap_update and heap_delete.
If the tuple being updated is not visible to the crosscheck snapshot, we return TM_Updated but the assertions would not hold in that case. Move them to before the cross-check. Fixes bug #17893. Backpatch to all supported versions. Author: Alexander Lakhin Backpatch-through: 12 Discussion: https://www.postgresql.org/message-id/17893-35847009eec517b5%40postgresql.org
1 parent a5e95ff commit b8a606e

File tree

2 files changed

+26
-19
lines changed

2 files changed

+26
-19
lines changed

src/backend/access/heap/heapam.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2677,13 +2677,7 @@ heap_delete(Relation relation, ItemPointer tid,
26772677
result = TM_Deleted;
26782678
}
26792679

2680-
if (crosscheck != InvalidSnapshot && result == TM_Ok)
2681-
{
2682-
/* Perform additional check for transaction-snapshot mode RI updates */
2683-
if (!HeapTupleSatisfiesVisibility(&tp, crosscheck, buffer))
2684-
result = TM_Updated;
2685-
}
2686-
2680+
/* sanity check the result HeapTupleSatisfiesUpdate() and the logic above */
26872681
if (result != TM_Ok)
26882682
{
26892683
Assert(result == TM_SelfModified ||
@@ -2693,6 +2687,17 @@ heap_delete(Relation relation, ItemPointer tid,
26932687
Assert(!(tp.t_data->t_infomask & HEAP_XMAX_INVALID));
26942688
Assert(result != TM_Updated ||
26952689
!ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid));
2690+
}
2691+
2692+
if (crosscheck != InvalidSnapshot && result == TM_Ok)
2693+
{
2694+
/* Perform additional check for transaction-snapshot mode RI updates */
2695+
if (!HeapTupleSatisfiesVisibility(&tp, crosscheck, buffer))
2696+
result = TM_Updated;
2697+
}
2698+
2699+
if (result != TM_Ok)
2700+
{
26962701
tmfd->ctid = tp.t_data->t_ctid;
26972702
tmfd->xmax = HeapTupleHeaderGetUpdateXid(tp.t_data);
26982703
if (result == TM_SelfModified)
@@ -3320,16 +3325,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
33203325
result = TM_Deleted;
33213326
}
33223327

3323-
if (crosscheck != InvalidSnapshot && result == TM_Ok)
3324-
{
3325-
/* Perform additional check for transaction-snapshot mode RI updates */
3326-
if (!HeapTupleSatisfiesVisibility(&oldtup, crosscheck, buffer))
3327-
{
3328-
result = TM_Updated;
3329-
Assert(!ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid));
3330-
}
3331-
}
3332-
3328+
/* Sanity check the result HeapTupleSatisfiesUpdate() and the logic above */
33333329
if (result != TM_Ok)
33343330
{
33353331
Assert(result == TM_SelfModified ||
@@ -3339,6 +3335,17 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
33393335
Assert(!(oldtup.t_data->t_infomask & HEAP_XMAX_INVALID));
33403336
Assert(result != TM_Updated ||
33413337
!ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid));
3338+
}
3339+
3340+
if (crosscheck != InvalidSnapshot && result == TM_Ok)
3341+
{
3342+
/* Perform additional check for transaction-snapshot mode RI updates */
3343+
if (!HeapTupleSatisfiesVisibility(&oldtup, crosscheck, buffer))
3344+
result = TM_Updated;
3345+
}
3346+
3347+
if (result != TM_Ok)
3348+
{
33423349
tmfd->ctid = oldtup.t_data->t_ctid;
33433350
tmfd->xmax = HeapTupleHeaderGetUpdateXid(oldtup.t_data);
33443351
if (result == TM_SelfModified)

src/include/access/tableam.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,8 +1220,8 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots,
12201220
* TM_BeingModified (the last only possible if wait == false).
12211221
*
12221222
* In the failure cases, the routine fills *tmfd with the tuple's t_ctid,
1223-
* t_xmax, and, if possible, and, if possible, t_cmax. See comments for
1224-
* struct TM_FailureData for additional info.
1223+
* t_xmax, and, if possible, t_cmax. See comments for struct
1224+
* TM_FailureData for additional info.
12251225
*/
12261226
static inline TM_Result
12271227
table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid,

0 commit comments

Comments
 (0)