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

Commit76ce39e

Browse files
committed
Prevent ExecInsert() and ExecUpdate() from scribbling on the result tuple
slot of the topmost plan node when a trigger returns a modified tuple.These appear to be the only places where a plan node's caller did nottreat the result slot as read-only, which is an assumption that nodeUniquemakes as of 8.1. Fixes trigger-vs-DISTINCT bug reported by Frank van Vugt.
1 parent08ee64e commit76ce39e

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

‎src/backend/executor/execMain.c

Lines changed: 30 additions & 8 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.256 2005/10/15 02:49:16 momjian Exp $
29+
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.257 2005/11/14 17:42:54 tgl Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -582,7 +582,8 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
582582
* initialize the executor "tuple" table. We need slots for all the plan
583583
* nodes, plus possibly output slots for the junkfilter(s). At this point
584584
* we aren't sure if we need junkfilters, so just add slots for them
585-
* unconditionally.
585+
* unconditionally. Also, if it's not a SELECT, set up a slot for use
586+
* for trigger output tuples.
586587
*/
587588
{
588589
intnSlots=ExecCountSlotsNode(plan);
@@ -591,7 +592,14 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
591592
nSlots+=list_length(parseTree->resultRelations);
592593
else
593594
nSlots+=1;
595+
if (operation!=CMD_SELECT)
596+
nSlots++;
597+
594598
estate->es_tupleTable=ExecCreateTupleTable(nSlots);
599+
600+
if (operation!=CMD_SELECT)
601+
estate->es_trig_tuple_slot=
602+
ExecAllocTableSlot(estate->es_tupleTable);
595603
}
596604

597605
/* mark EvalPlanQual not active */
@@ -1399,12 +1407,19 @@ ExecInsert(TupleTableSlot *slot,
13991407
if (newtuple!=tuple)/* modified by Trigger(s) */
14001408
{
14011409
/*
1402-
*Insertmodified tuple intotuple tableslot, replacing the
1403-
*original. We assumethat it was allocated in per-tuple memory
1410+
*Put themodified tuple intoaslot for convenience of routines
1411+
*below. We assumethe tuple was allocated in per-tuple memory
14041412
* context, and therefore will go away by itself. The tuple table
14051413
* slot should not try to clear it.
14061414
*/
1407-
ExecStoreTuple(newtuple,slot,InvalidBuffer, false);
1415+
TupleTableSlot*newslot=estate->es_trig_tuple_slot;
1416+
1417+
if (newslot->tts_tupleDescriptor!=slot->tts_tupleDescriptor)
1418+
ExecSetSlotDescriptor(newslot,
1419+
slot->tts_tupleDescriptor,
1420+
false);
1421+
ExecStoreTuple(newtuple,newslot,InvalidBuffer, false);
1422+
slot=newslot;
14081423
tuple=newtuple;
14091424
}
14101425
}
@@ -1600,12 +1615,19 @@ ExecUpdate(TupleTableSlot *slot,
16001615
if (newtuple!=tuple)/* modified by Trigger(s) */
16011616
{
16021617
/*
1603-
*Insertmodified tuple intotuple tableslot, replacing the
1604-
*original. We assumethat it was allocated in per-tuple memory
1618+
*Put themodified tuple intoaslot for convenience of routines
1619+
*below. We assumethe tuple was allocated in per-tuple memory
16051620
* context, and therefore will go away by itself. The tuple table
16061621
* slot should not try to clear it.
16071622
*/
1608-
ExecStoreTuple(newtuple,slot,InvalidBuffer, false);
1623+
TupleTableSlot*newslot=estate->es_trig_tuple_slot;
1624+
1625+
if (newslot->tts_tupleDescriptor!=slot->tts_tupleDescriptor)
1626+
ExecSetSlotDescriptor(newslot,
1627+
slot->tts_tupleDescriptor,
1628+
false);
1629+
ExecStoreTuple(newtuple,newslot,InvalidBuffer, false);
1630+
slot=newslot;
16091631
tuple=newtuple;
16101632
}
16111633
}

‎src/backend/executor/execUtils.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.126 2005/10/15 02:49:16 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.127 2005/11/14 17:42:54 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -187,6 +187,8 @@ CreateExecutorState(void)
187187

188188
estate->es_junkFilter=NULL;
189189

190+
estate->es_trig_tuple_slot=NULL;
191+
190192
estate->es_into_relation_descriptor=NULL;
191193
estate->es_into_relation_use_wal= false;
192194

‎src/include/nodes/execnodes.h

Lines changed: 3 additions & 1 deletion
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/nodes/execnodes.h,v 1.139 2005/10/15 02:49:45 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.140 2005/11/14 17:42:55 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -304,6 +304,8 @@ typedef struct EState
304304
ResultRelInfo*es_result_relation_info;/* currently active array elt */
305305
JunkFilter*es_junkFilter;/* currently active junk filter */
306306

307+
TupleTableSlot*es_trig_tuple_slot;/* for trigger output tuples */
308+
307309
Relationes_into_relation_descriptor;/* for SELECT INTO */
308310
booles_into_relation_use_wal;
309311

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp