Re: Fix WITHOUT OVERLAPS multirange with location replication

From: Nisha Moond <nisha(dot)moond412(at)gmail(dot)com>
To: Paul A Jungwirth <pj(at)illuminatedcomputing(dot)com>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Andres Freund <andres(at)anarazel(dot)de>, Peter Eisentraut <peter(at)eisentraut(dot)org>
Subject: Re: Fix WITHOUT OVERLAPS multirange with location replication
Date: 2026-10-09 14:56:49
Message-ID: CABdArM5bBR2Ju6eexH-tVKMHtU3H6WnFBECkqkwszOLbZboGWw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Fri, Oct 9, 2026 at 9:50 AM Paul A Jungwirth
<pj(at)illuminatedcomputing(dot)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

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Zhijie Hou 2026-10-09 15:28:32 Re: Bug in logical decoding with DDL and subtransactions
Previous Message Hunaid Sohail 2026-10-09 14:13:03 Re: Proposal: SELECT * EXCLUDE (...) command