Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit25b9b1b

Browse files
committed
Repair "Halloween problem" in EvalPlanQual: a tuple that's been inserted by
our own command (or more generally, xmin = our xact and cmin >= currentcommand ID) should not be seen as good. Else we may try to update rowswe already updated. This error was inserted last August while fixing theeven bigger problem that the old coding wouldn't see *any* tuples insertedby our own transaction as good. Per report from Euler Taveira de Oliveira.
1 parentdb0558c commit25b9b1b

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

‎src/backend/commands/trigger.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.198 2006/01/05 10:07:45 petere Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.199 2006/01/12 21:48:52 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1736,7 +1736,8 @@ ltrmark:;
17361736
epqslot=EvalPlanQual(estate,
17371737
relinfo->ri_RangeTableIndex,
17381738
&update_ctid,
1739-
update_xmax);
1739+
update_xmax,
1740+
cid);
17401741
if (!TupIsNull(epqslot))
17411742
{
17421743
*tid=update_ctid;

‎src/backend/executor/execMain.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
*
2828
* IDENTIFICATION
29-
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.264 2006/01/11 08:43:12 neilc Exp $
29+
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.265 2006/01/12 21:48:53 tgl Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -1213,7 +1213,8 @@ lnext:;
12131213
newSlot=EvalPlanQual(estate,
12141214
erm->rti,
12151215
&update_ctid,
1216-
update_xmax);
1216+
update_xmax,
1217+
estate->es_snapshot->curcid);
12171218
if (!TupIsNull(newSlot))
12181219
{
12191220
slot=newSlot;
@@ -1521,7 +1522,8 @@ ldelete:;
15211522
epqslot=EvalPlanQual(estate,
15221523
resultRelInfo->ri_RangeTableIndex,
15231524
&update_ctid,
1524-
update_xmax);
1525+
update_xmax,
1526+
estate->es_snapshot->curcid);
15251527
if (!TupIsNull(epqslot))
15261528
{
15271529
*tupleid=update_ctid;
@@ -1673,7 +1675,8 @@ lreplace:;
16731675
epqslot=EvalPlanQual(estate,
16741676
resultRelInfo->ri_RangeTableIndex,
16751677
&update_ctid,
1676-
update_xmax);
1678+
update_xmax,
1679+
estate->es_snapshot->curcid);
16771680
if (!TupIsNull(epqslot))
16781681
{
16791682
*tupleid=update_ctid;
@@ -1820,6 +1823,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
18201823
*rti - rangetable index of table containing tuple
18211824
**tid - t_ctid from the outdated tuple (ie, next updated version)
18221825
*priorXmax - t_xmax from the outdated tuple
1826+
*curCid - command ID of current command of my transaction
18231827
*
18241828
* *tid is also an output parameter: it's modified to hold the TID of the
18251829
* latest version of the tuple (note this may be changed even on failure)
@@ -1829,7 +1833,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
18291833
*/
18301834
TupleTableSlot*
18311835
EvalPlanQual(EState*estate,Indexrti,
1832-
ItemPointertid,TransactionIdpriorXmax)
1836+
ItemPointertid,TransactionIdpriorXmax,CommandIdcurCid)
18331837
{
18341838
evalPlanQual*epq;
18351839
EState*epqstate;
@@ -1905,6 +1909,24 @@ EvalPlanQual(EState *estate, Index rti,
19051909
continue;/* loop back to repeat heap_fetch */
19061910
}
19071911

1912+
/*
1913+
* If tuple was inserted by our own transaction, we have to check
1914+
* cmin against curCid: cmin >= curCid means our command cannot
1915+
* see the tuple, so we should ignore it. Without this we are
1916+
* open to the "Halloween problem" of indefinitely re-updating
1917+
* the same tuple. (We need not check cmax because
1918+
* HeapTupleSatisfiesDirty will consider a tuple deleted by
1919+
* our transaction dead, regardless of cmax.) We just checked
1920+
* that priorXmax == xmin, so we can test that variable instead
1921+
* of doing HeapTupleHeaderGetXmin again.
1922+
*/
1923+
if (TransactionIdIsCurrentTransactionId(priorXmax)&&
1924+
HeapTupleHeaderGetCmin(tuple.t_data) >=curCid)
1925+
{
1926+
ReleaseBuffer(buffer);
1927+
returnNULL;
1928+
}
1929+
19081930
/*
19091931
* We got tuple - now copy it for use by recheck query.
19101932
*/

‎src/include/executor/executor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.123 2005/12/03 05:51:03 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.124 2006/01/12 21:48:53 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -98,7 +98,7 @@ extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
9898
externvoidExecConstraints(ResultRelInfo*resultRelInfo,
9999
TupleTableSlot*slot,EState*estate);
100100
externTupleTableSlot*EvalPlanQual(EState*estate,Indexrti,
101-
ItemPointertid,TransactionIdpriorXmax);
101+
ItemPointertid,TransactionIdpriorXmax,CommandIdcurCid);
102102

103103
/*
104104
* prototypes from functions in execProcnode.c

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp