On Sun, Sep 14, 2025 at 6:49 PM, Chao Li <li.evan.chao@gmail.com> 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
thisdescription is not relevant. For Update and LockRows, the expected EvalPlanQual behavior is that rows are checked
againstthe predicate twice — once as of the statement snapshot and once as of locking time — and the rows that match
bothtimes 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
newlycreated, 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
meantto do; the fact that it matches the enable_tidscan=OFF behavior is further corroboration of that fact.
Sophie