Re: ExecForceStoreHeapTuple() loses tts_tid, so ORDER BY-op index scans project an invalid ctid

From: Andres Freund <andres(at)anarazel(dot)de>
To: Greg Burd <greg(at)burd(dot)me>
Cc: Michael Paquier <michael(at)paquier(dot)xyz>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: ExecForceStoreHeapTuple() loses tts_tid, so ORDER BY-op index scans project an invalid ctid
Date: 2026-09-14 15:22:42
Message-ID: m3qxog6pr6glo7s5d3k4kyox2g5ipzbrdtt3tutvuokdkrs7yi@apmwbtwwyqej
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On 2026-09-14 11:08:48 -0400, Greg Burd wrote:
> On Mon, Sep 14, 2026, at 10:56 AM, Andres Freund wrote:
> > On 2026-09-09 09:03:46 +0900, Michael Paquier wrote:
> >> On Tue, Sep 08, 2026 at 01:28:22PM -0400, Greg Burd wrote:
> >> > ExecClearTuple() reaches tts_buffer_heap_clear(), which does
> >> > ItemPointerSetInvalid(&slot->tts_tid). The tuple is then copied in, but
> >> > tts_tid is left invalid. The sibling path, ExecStoreHeapTuple() ->
> >> > tts_heap_store_tuple() — *does* slot->tts_tid = tuple->t_self, so this
> >> > reads as a plain asymmetry rather than an intentional choice.
> >>
> >> That's strange. Once thing that I can see why scanning this file is
> >> the same code pattern in tts_buffer_heap_copyslot(), where a slot is
> >> similarly cleared in a copy-paste fashion.
> >
> >> Andres?
> >
>
> Hey Andres, thanks for taking time to review this. The thread is moving to
> the one started by the first person to report this issue [1].

Just had replied there...

> > The assymmetry does suggest we should fix this. I'm somewhat sceptical that
> > it's sane to expect uses of ExecForceStoreHeapTuple() to actually have valid
> > tids, but ...
> >
> > For a bit I was wondering whether the tuple's tid is actually the right one,
> > due to stuff like walking a HOT chain. But it seems we set both to the same
> > value (there's some subtleties around this nearby that I think I was confusing
> > this with, with the tid for a HOT updated needing to point to the root tuple
> > in some cases). I wonder if we ought to have an assertion for the two tids
> > being the same that, perhaps only on master?
>
> So, that I'm sure I understand the suggestion, you'd like to ensure that for any
> heap or buffer-heap slot holding a tuple, slot->tts_tid == slot's stored
> tuple->t_self. Correct?

I don't think we can do that in general, there are legitimate cases of those
differing due to HOT IIRC. But in the reorder case I don't think that
difference exists, and it'd lead to different query results, so I think we
should just assert it there.

Greetings,

Andres Freund

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Manuel Reyes Bravo 2026-09-14 15:25:26 Re: Does postgresql have a diff tool?
Previous Message Andres Freund 2026-09-14 15:21:18 Re: [PATCH] Corruption Issue: Fix missing tts_tid in ExecForceStoreHeapTuple