From 31b9eaae36fd2d7e8c04fe714f15ca081c1142fe Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Fri, 30 Oct 2026 11:10:56 -0500 Subject: [PATCH v10 1/1] Fix missing tts_tid assignment in ExecForceStoreHeapTuple(). ExecForceStoreHeapTuple() clears the slot before storing the tuple, which invalidates the slot's TID, but it only sets the TID again for slots of type TTSOpsHeapTuple. As a result, tuples stored into other kinds of slots this way (e.g., those that pass through the reorder queue in nodeIndexscan.c) have an invalid ctid. Besides producing wrong query results, this can lead to data corruption if such a tuple is locked (e.g., via SELECT ... FOR UPDATE). To fix, set the slot's TID in all cases. Oversight in commit b8d71745ea. Author: Virender Singla Co-authored-by: Greg Burd Reviewed-by: Andres Freund Reviewed-by: Dilip Kumar Reviewed-by: Nikolay Samokhvalov Tested-by: Shihao Zhong Discussion: https://postgr.es/m/CAM6Zo8wZOLnCWRO_tuuXVX9J4N4JN6GsEnk8WJtT0%3D_0zy-1dw%40mail.gmail.com Discussion: https://postgr.es/m/0498c10f-839b-4f68-9994-c29b454e55a4%40app.fastmail.com Backpatch-through: 14 --- src/backend/executor/execTuples.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index b8e8f52c64c..9bc241aecf9 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -1752,6 +1752,8 @@ ExecForceStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree) { + ItemPointerData tid = tuple->t_self; + if (TTS_IS_HEAPTUPLE(slot)) { ExecStoreHeapTuple(tuple, slot, shouldFree); @@ -1784,6 +1786,13 @@ ExecForceStoreHeapTuple(HeapTuple tuple, pfree(tuple); } } + + /* + * ExecClearTuple() invalidated the slot's TID, so we need to set it again + * here. Note that the tuple might have already been freed, so we use the + * copy of its TID that we saved above. + */ + slot->tts_tid = tid; } /* -- 2.55.0