Skip to content

Commit 21946ac

Browse files
committed
Fix corner case where SELECT FOR UPDATE could return a row twice.
In READ COMMITTED mode, if a SELECT FOR UPDATE discovers it has to redo WHERE-clause checking on rows that have been updated since the SELECT's snapshot, it invokes EvalPlanQual processing to do that. If this first occurs within a non-first child table of an inheritance tree, the previous coding could accidentally re-return a matching row from an earlier, already-scanned child table. (And, to add insult to injury, I think this could make it miss returning a row that should have been returned, if the updated row that this happens on should still have passed the WHERE qual.) Per report from Kyotaro Horiguchi; the added isolation test is based on his test case. This has been broken for quite awhile, so back-patch to all supported branches.
1 parent 7292027 commit 21946ac

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

src/backend/executor/nodeLockRows.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,29 @@ ExecLockRows(LockRowsState *node)
160160
*/
161161
if (!epq_started)
162162
{
163+
ListCell *lc2;
164+
163165
EvalPlanQualBegin(&node->lr_epqstate, estate);
166+
167+
/*
168+
* Ensure that rels with already-visited rowmarks are told
169+
* not to return tuples during the first EPQ test. We can
170+
* exit this loop once it reaches the current rowmark;
171+
* rels appearing later in the list will be set up
172+
* correctly by the EvalPlanQualSetTuple call at the top
173+
* of the loop.
174+
*/
175+
foreach(lc2, node->lr_arowMarks)
176+
{
177+
ExecAuxRowMark *aerm2 = (ExecAuxRowMark *) lfirst(lc2);
178+
179+
if (lc2 == lc)
180+
break;
181+
EvalPlanQualSetTuple(&node->lr_epqstate,
182+
aerm2->rowmark->rti,
183+
NULL);
184+
}
185+
164186
epq_started = true;
165187
}
166188

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy