@ -2517,7 +2517,8 @@ ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
TupleTableSlot * slot )
TupleTableSlot * slot )
{
{
TriggerDesc * trigdesc = relinfo - > ri_TrigDesc ;
TriggerDesc * trigdesc = relinfo - > ri_TrigDesc ;
HeapTuple slottuple = ExecMaterializeSlot ( slot ) ;
bool should_free ;
HeapTuple slottuple = ExecFetchSlotHeapTuple ( slot , true , & should_free ) ;
HeapTuple newtuple = slottuple ;
HeapTuple newtuple = slottuple ;
HeapTuple oldtuple ;
HeapTuple oldtuple ;
TriggerData LocTriggerData ;
TriggerData LocTriggerData ;
@ -2556,8 +2557,12 @@ ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
if ( oldtuple ! = newtuple & & oldtuple ! = slottuple )
if ( oldtuple ! = newtuple & & oldtuple ! = slottuple )
heap_freetuple ( oldtuple ) ;
heap_freetuple ( oldtuple ) ;
if ( newtuple = = NULL )
if ( newtuple = = NULL )
{
if ( should_free )
heap_freetuple ( slottuple ) ;
return NULL ; /* "do nothing" */
return NULL ; /* "do nothing" */
}
}
}
if ( newtuple ! = slottuple )
if ( newtuple ! = slottuple )
{
{
@ -2575,6 +2580,9 @@ ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
ExecStoreHeapTuple ( newtuple , newslot , false ) ;
ExecStoreHeapTuple ( newtuple , newslot , false ) ;
slot = newslot ;
slot = newslot ;
}
}
if ( should_free )
heap_freetuple ( slottuple ) ;
return slot ;
return slot ;
}
}
@ -2598,7 +2606,8 @@ ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
TupleTableSlot * slot )
TupleTableSlot * slot )
{
{
TriggerDesc * trigdesc = relinfo - > ri_TrigDesc ;
TriggerDesc * trigdesc = relinfo - > ri_TrigDesc ;
HeapTuple slottuple = ExecMaterializeSlot ( slot ) ;
bool should_free ;
HeapTuple slottuple = ExecFetchSlotHeapTuple ( slot , true , & should_free ) ;
HeapTuple newtuple = slottuple ;
HeapTuple newtuple = slottuple ;
HeapTuple oldtuple ;
HeapTuple oldtuple ;
TriggerData LocTriggerData ;
TriggerData LocTriggerData ;
@ -2637,8 +2646,12 @@ ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
if ( oldtuple ! = newtuple & & oldtuple ! = slottuple )
if ( oldtuple ! = newtuple & & oldtuple ! = slottuple )
heap_freetuple ( oldtuple ) ;
heap_freetuple ( oldtuple ) ;
if ( newtuple = = NULL )
if ( newtuple = = NULL )
{
if ( should_free )
heap_freetuple ( slottuple ) ;
return NULL ; /* "do nothing" */
return NULL ; /* "do nothing" */
}
}
}
if ( newtuple ! = slottuple )
if ( newtuple ! = slottuple )
{
{
@ -2656,6 +2669,9 @@ ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
ExecStoreHeapTuple ( newtuple , newslot , false ) ;
ExecStoreHeapTuple ( newtuple , newslot , false ) ;
slot = newslot ;
slot = newslot ;
}
}
if ( should_free )
heap_freetuple ( slottuple ) ;
return slot ;
return slot ;
}
}
@ -2976,7 +2992,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
TupleTableSlot * slot )
TupleTableSlot * slot )
{
{
TriggerDesc * trigdesc = relinfo - > ri_TrigDesc ;
TriggerDesc * trigdesc = relinfo - > ri_TrigDesc ;
HeapTuple slottuple = ExecMaterializeSlot ( slot ) ;
HeapTuple slottuple = ExecFetchSlotHeapTuple ( slot , true , NULL ) ;
HeapTuple newtuple = slottuple ;
HeapTuple newtuple = slottuple ;
TriggerData LocTriggerData ;
TriggerData LocTriggerData ;
HeapTuple trigtuple ;
HeapTuple trigtuple ;
@ -3018,7 +3034,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
if ( newSlot ! = NULL )
if ( newSlot ! = NULL )
{
{
slot = ExecFilterJunk ( relinfo - > ri_junkFilter , newSlot ) ;
slot = ExecFilterJunk ( relinfo - > ri_junkFilter , newSlot ) ;
slottuple = ExecMaterializeSlot ( slot ) ;
slottuple = ExecFetchSlotHeapTuple ( slot , true , NULL ) ;
newtuple = slottuple ;
newtuple = slottuple ;
}
}
@ -3132,7 +3148,7 @@ ExecIRUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
HeapTuple trigtuple , TupleTableSlot * slot )
HeapTuple trigtuple , TupleTableSlot * slot )
{
{
TriggerDesc * trigdesc = relinfo - > ri_TrigDesc ;
TriggerDesc * trigdesc = relinfo - > ri_TrigDesc ;
HeapTuple slottuple = ExecMaterializeSlot ( slot ) ;
HeapTuple slottuple = ExecFetchSlotHeapTuple ( slot , true , NULL ) ;
HeapTuple newtuple = slottuple ;
HeapTuple newtuple = slottuple ;
TriggerData LocTriggerData ;
TriggerData LocTriggerData ;
HeapTuple oldtuple ;
HeapTuple oldtuple ;
@ -4262,22 +4278,22 @@ AfterTriggerExecute(AfterTriggerEvent event,
case AFTER_TRIGGER_FDW_REUSE :
case AFTER_TRIGGER_FDW_REUSE :
/*
/*
* Using ExecMaterializeSlot ( ) rather than ExecFetchSlotTuple ( )
* Materialize tuple in the slot so that tg_trigtuple does not
* ensures that tg_trigtuple does not reference tuplestore memory .
* reference tuplestore memory . ( It is formally possible for the
* ( It is formally possible for the trigger function to queu e
* trigger function to queue trigger events that add to the sam e
* trigger events that add to the same tuplestore , which can push
* tuplestore , which can push other tuples out of memory . ) The
* other tuples out of memory . ) The distinction is academic ,
* distinction is academic , because we start with a minimal tuple
* because we start with a minimal tuple that ExecFetchSlotTuple ( )
* that is stored as a heap tuple , constructed in different memory
* must materialize anyway .
* context , in the slot anyway .
*/
*/
LocTriggerData . tg_trigtuple =
LocTriggerData . tg_trigtuple = ExecFetchSlotHeapTuple ( trig_tuple_slot1 ,
ExecMaterializeSlot ( trig_tuple_slot1 ) ;
true , NULL ) ;
LocTriggerData . tg_trigtuplebuf = InvalidBuffer ;
LocTriggerData . tg_trigtuplebuf = InvalidBuffer ;
LocTriggerData . tg_newtuple =
LocTriggerData . tg_newtuple =
( ( evtshared - > ats_event & TRIGGER_EVENT_OPMASK ) = =
( ( evtshared - > ats_event & TRIGGER_EVENT_OPMASK ) = =
TRIGGER_EVENT_UPDATE ) ?
TRIGGER_EVENT_UPDATE ) ?
ExecMaterializeSlot ( trig_tuple_slot2 ) : NULL ;
ExecFetchSlotHeapTuple ( trig_tuple_slot2 , true , NULL ) : NULL ;
LocTriggerData . tg_newtuplebuf = InvalidBuffer ;
LocTriggerData . tg_newtuplebuf = InvalidBuffer ;
break ;
break ;