diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2023-11-28 11:59:09 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2023-11-28 11:59:53 +0200 |
commit | b8a606e21b0619ac378558bdd258c54aee7cb4ed (patch) | |
tree | 2442ab30aea3b5f8df22e4f4c905534982306dc8 /src/backend/access/heap | |
parent | a5e95ff46f58c1aa15760ee3b2aa074f695f53d1 (diff) | |
download | postgresql-b8a606e21b0619ac378558bdd258c54aee7cb4ed.tar.gz postgresql-b8a606e21b0619ac378558bdd258c54aee7cb4ed.zip |
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
Diffstat (limited to 'src/backend/access/heap')
-rw-r--r-- | src/backend/access/heap/heapam.c | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 657af12a399..e1e54a265cf 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2677,13 +2677,7 @@ l1: result = TM_Deleted; } - if (crosscheck != InvalidSnapshot && result == TM_Ok) - { - /* Perform additional check for transaction-snapshot mode RI updates */ - if (!HeapTupleSatisfiesVisibility(&tp, crosscheck, buffer)) - result = TM_Updated; - } - + /* sanity check the result HeapTupleSatisfiesUpdate() and the logic above */ if (result != TM_Ok) { Assert(result == TM_SelfModified || @@ -2693,6 +2687,17 @@ l1: Assert(!(tp.t_data->t_infomask & HEAP_XMAX_INVALID)); Assert(result != TM_Updated || !ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid)); + } + + if (crosscheck != InvalidSnapshot && result == TM_Ok) + { + /* Perform additional check for transaction-snapshot mode RI updates */ + if (!HeapTupleSatisfiesVisibility(&tp, crosscheck, buffer)) + result = TM_Updated; + } + + if (result != TM_Ok) + { tmfd->ctid = tp.t_data->t_ctid; tmfd->xmax = HeapTupleHeaderGetUpdateXid(tp.t_data); if (result == TM_SelfModified) @@ -3320,16 +3325,7 @@ l2: result = TM_Deleted; } - if (crosscheck != InvalidSnapshot && result == TM_Ok) - { - /* Perform additional check for transaction-snapshot mode RI updates */ - if (!HeapTupleSatisfiesVisibility(&oldtup, crosscheck, buffer)) - { - result = TM_Updated; - Assert(!ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid)); - } - } - + /* Sanity check the result HeapTupleSatisfiesUpdate() and the logic above */ if (result != TM_Ok) { Assert(result == TM_SelfModified || @@ -3339,6 +3335,17 @@ l2: Assert(!(oldtup.t_data->t_infomask & HEAP_XMAX_INVALID)); Assert(result != TM_Updated || !ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid)); + } + + if (crosscheck != InvalidSnapshot && result == TM_Ok) + { + /* Perform additional check for transaction-snapshot mode RI updates */ + if (!HeapTupleSatisfiesVisibility(&oldtup, crosscheck, buffer)) + result = TM_Updated; + } + + if (result != TM_Ok) + { tmfd->ctid = oldtup.t_data->t_ctid; tmfd->xmax = HeapTupleHeaderGetUpdateXid(oldtup.t_data); if (result == TM_SelfModified) |