On Sun, Sep 14, 2025 at  6:49 PM, Chao Li <[email protected]> wrote:
> This is a wrong example and (0,3) should NOT be updated. According to the 
> definition of “read committed”:
> https://www.postgresql.org/docs/current/transaction-iso.html#XACT-READ-COMMITTED
> “A query sees only data committed before the query began”.

You paraphrased the docs here but did so incorrectly: the actual quote is "a 
SELECT query (without a FOR UPDATE/SHARE clause) sees only data committed 
before the query began". We are not discussing the behavior of a plain SELECT 
query so this description is not relevant. For Update and LockRows, the 
expected EvalPlanQual behavior is that rows are checked against the predicate 
twice — once as of the statement snapshot and once as of locking time — and the 
rows that match both times are used.

In my example with ctid (0,3), the row matches the 'ctid = (0,1) OR ctid = 
(0,3)' predicate both times. The row is not newly created, so the newly-created 
row in your example is not analogous.

I continue to believe that my implementation of TidRecheck plainly satisfies 
the contract for what the scan recheck is meant to do; the fact that it matches 
the enable_tidscan=OFF behavior is further corroboration of that fact.

Sophie


Reply via email to