On Fri, Oct 9, 2026 at 9:50 AM Paul A Jungwirth
<pj@illuminatedcomputing.com> wrote:
>
> Hi Hackers,
>
> Andres reported that a WITHOUT OVERLAPS replica identity using
> multiranges can update/delete the wrong row, because a recheck is
> needed.[0] This patch fixes that problem by performing a recheck when
> the scan indicates one is needed.
>
> RelationFindReplTupleByIndex() and
> RelationFindDeletedTupleInfoByIndex() skipped the tuples_equal() check
> whenever the scan used the primary key or replica identity index,
> assuming any match is exact. But a GiST index on a multirange is
> lossy: two multiranges with the same bounding range, like {[1,5)} and
> {[1,2),[3,5)}, look the same to the index. Now we recheck the
> candidate whenever the scan sets xs_recheck, like
> check_exclusion_or_unique_constraint() does. Btree and range-type GiST
> indexes never set it, so they keep the fast path. When we do recheck,
> we compare only the key columns, since those are all the search slot
> has (and we only look up that bitmap if we need it).
>
> The second function is used for conflict detection with
> retain_dead_tuples. There the bug can't modify the wrong row, but it
> can report update_deleted (blaming the transaction that deleted an
> unrelated row) instead of update_missing.[1]
>
> The patch adds a TAP test to 034_temporal.pl using two multiranges
> with the same bounding range.
>
Hi Paul,
Thanks for the patch. I reviewed v1 and tested it manually. I was able
to reproduce both the wrong-row update/delete and the update_deleted
misreport (update_deleted reported instead of update_missing with
retain_dead_tuples) using a multirange key, and the patch fixes both.
I didn't find any critical issues. Just a few small suggestions:
1) The change to RelationFindDeletedTupleInfoByIndex() doesn't seem to
be covered by a test. Maybe we could add a case to 035_conflicts.pl?
2) The header comment of RelationFindReplTupleByIndex() needs an
update. It still says:
* 'skipduplicates' specifies whether the first matching tuple can be used
* without comparing it against 'searchslot'.
-- This no longer holds when the index scan requires a recheck.
3) The commit message could also mention the update_deleted vs.
update_missing impact, and that this patch fixes it.
--
Thanks,
Nisha