Commit 65158f49 authored by Tom Lane's avatar Tom Lane

Remove small inefficiency in ExecARDeleteTriggers/ExecARUpdateTriggers.

Whilst poking at nodeModifyTable.c, I chanced to notice that while
its calls to ExecBR*Triggers and ExecIR*Triggers are protected by
tests to see if there are any relevant triggers to fire, its calls
to ExecAR*Triggers are not; the latter functions do the equivalent
tests themselves.  This seems possibly reasonable given the more
complex conditions involved, but what's less reasonable is that
the ExecAR* functions aren't careful to do no work when there is
no work to be done.  ExecARInsertTriggers gets this right, but the
other two will both force creation of a slot that the query may
have no use for.  ExecARUpdateTriggers additionally performed a
usually-useless ExecClearTuple() on that slot.  This is probably
all pretty microscopic in real workloads, but a cycle shaved is a
cycle earned.
parent 9ee7d533
...@@ -2546,11 +2546,12 @@ ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo, ...@@ -2546,11 +2546,12 @@ ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
TransitionCaptureState *transition_capture) TransitionCaptureState *transition_capture)
{ {
TriggerDesc *trigdesc = relinfo->ri_TrigDesc; TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
if ((trigdesc && trigdesc->trig_delete_after_row) || if ((trigdesc && trigdesc->trig_delete_after_row) ||
(transition_capture && transition_capture->tcs_delete_old_table)) (transition_capture && transition_capture->tcs_delete_old_table))
{ {
TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid)); Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid));
if (fdw_trigtuple == NULL) if (fdw_trigtuple == NULL)
GetTupleForTrigger(estate, GetTupleForTrigger(estate,
...@@ -2829,9 +2830,6 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, ...@@ -2829,9 +2830,6 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
TransitionCaptureState *transition_capture) TransitionCaptureState *transition_capture)
{ {
TriggerDesc *trigdesc = relinfo->ri_TrigDesc; TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
ExecClearTuple(oldslot);
if ((trigdesc && trigdesc->trig_update_after_row) || if ((trigdesc && trigdesc->trig_update_after_row) ||
(transition_capture && (transition_capture &&
...@@ -2844,6 +2842,8 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, ...@@ -2844,6 +2842,8 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
* separately for DELETE and INSERT to capture transition table rows. * separately for DELETE and INSERT to capture transition table rows.
* In such case, either old tuple or new tuple can be NULL. * In such case, either old tuple or new tuple can be NULL.
*/ */
TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
if (fdw_trigtuple == NULL && ItemPointerIsValid(tupleid)) if (fdw_trigtuple == NULL && ItemPointerIsValid(tupleid))
GetTupleForTrigger(estate, GetTupleForTrigger(estate,
NULL, NULL,
...@@ -2854,6 +2854,8 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, ...@@ -2854,6 +2854,8 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
NULL); NULL);
else if (fdw_trigtuple != NULL) else if (fdw_trigtuple != NULL)
ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false); ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false);
else
ExecClearTuple(oldslot);
AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE, AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE,
true, oldslot, newslot, recheckIndexes, true, oldslot, newslot, recheckIndexes,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment