Re: Fix missing EvalPlanQual recheck for TID scans
Sophie Alpert <pg@sophiebits.com>
From: "Sophie Alpert" <pg@sophiebits.com>
To: "Chao Li" <li.evan.chao@gmail.com>, "David Rowley" <dgrowleyml@gmail.com>
Cc: pgsql-hackers@lists.postgresql.org
Date: 2025-09-09T18:20:47Z
Lists: pgsql-hackers
Hi Chao, Thanks for taking a look. On Tue, Sep 9, 2025 at 12:52 AM, Chao Li <li.evan.chao@gmail.com> wrote: > However, I noticed that, when “TidRecheck()” is called, it is actually passed with “epqstate->recheckplanstate” that is always newly created, which means we repeatedly call “TidListEval(node)” and run “bsearch()” when there are multiple row involved in the update. If update qual is just “ctid = <a single ctid>”, that should fine. But if we do “update .. where ctid in (a list of ctid)”, then duplicately call “TidListEval()” might not be a good thing. Based on my current understanding, the EPQ PlanState is shared across all EPQ checks for a given plan and that ReScan is called at similar times as it is for the initial access path with, ExecScanFetch delegating to the appropriate *Next or *Recheck method as each row is processed. Therefore, my patch does not recompute the TidList for every row. > As “TidRecheck(TidScanState *node, TupleTableSlot *slot)” gets the second parameter “slot” with the updated slot, so I am thinking the other solution could be that, we just check if the updated slot is visible to current transaction. So I made a local change like this: > > ... > tuple = ExecCopySlotHeapTuple(slot); > visible = HeapTupleSatisfiesVisibility(tuple, GetActiveSnapshot(), slot->tts_tableOid); This is semantically different from the patch I've proposed. My test `permutation tid1 tidsucceed2 c1 c2 read` fails against your code, despite passing with the `SET enable_tidscan = OFF;` flag that I understand we want to match the behavior of. (In addition, I understand HeapTupleSatisfiesVisibility is specific to the heap access method and can't be used here, though perhaps tuple_fetch_row_version could be used instead.) Sophie
Commits
-
Add missing EPQ recheck for TID Range Scan
- f78a69034740 14.20 landed
- f00ad440a5b6 15.15 landed
- ba0203880a8f 16.11 landed
- 0fb06e893331 17.7 landed
- 78e6047dcea5 18.0 landed
- ac06ea8f7b6c 19 (unreleased) landed
-
Add missing EPQ recheck for TID Scan
- 940f3cd5df57 13.23 landed
- 2eb7ea97d8af 14.20 landed
- 005770203889 15.15 landed
- d6539f88b7c5 16.11 landed
- 3d939a9b1c72 17.7 landed
- bae6c74ba4e4 18.0 landed
- dee21ea6d617 19 (unreleased) landed
-
Repair problems with EvalPlanQual where target table is scanned as
- 6799a6ca21e5 7.2.1 cited
-
Tid access method feature from Hiroshi Inoue, Inoue@tpf.co.jp
- 6f9ff92cc0ff 7.1.1 cited