aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r--src/backend/executor/nodeAgg.c38
1 files changed, 14 insertions, 24 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index c4a5588113f..eef0e8437de 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -221,6 +221,7 @@
#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
+#include "executor/execExpr.h"
#include "executor/executor.h"
#include "executor/nodeAgg.h"
#include "miscadmin.h"
@@ -626,33 +627,22 @@ advance_transition_function(AggState *aggstate,
* first input, we don't need to do anything. Also, if transfn returned a
* pointer to a R/W expanded object that is already a child of the
* aggcontext, assume we can adopt that value without copying it.
+ *
+ * It's safe to compare newVal with pergroup->transValue without
+ * regard for either being NULL, because ExecAggTransReparent()
+ * takes care to set transValue to 0 when NULL. Otherwise we could
+ * end up accidentally not reparenting, when the transValue has
+ * the same numerical value as newValue, despite being NULL. This
+ * is a somewhat hot path, making it undesirable to instead solve
+ * this with another branch for the common case of the transition
+ * function returning its (modified) input argument.
*/
if (!pertrans->transtypeByVal &&
DatumGetPointer(newVal) != DatumGetPointer(pergroupstate->transValue))
- {
- if (!fcinfo->isnull)
- {
- MemoryContextSwitchTo(aggstate->curaggcontext->ecxt_per_tuple_memory);
- if (DatumIsReadWriteExpandedObject(newVal,
- false,
- pertrans->transtypeLen) &&
- MemoryContextGetParent(DatumGetEOHP(newVal)->eoh_context) == CurrentMemoryContext)
- /* do nothing */ ;
- else
- newVal = datumCopy(newVal,
- pertrans->transtypeByVal,
- pertrans->transtypeLen);
- }
- if (!pergroupstate->transValueIsNull)
- {
- if (DatumIsReadWriteExpandedObject(pergroupstate->transValue,
- false,
- pertrans->transtypeLen))
- DeleteExpandedObject(pergroupstate->transValue);
- else
- pfree(DatumGetPointer(pergroupstate->transValue));
- }
- }
+ newVal = ExecAggTransReparent(aggstate, pertrans,
+ newVal, fcinfo->isnull,
+ pergroupstate->transValue,
+ pergroupstate->transValueIsNull);
pergroupstate->transValue = newVal;
pergroupstate->transValueIsNull = fcinfo->isnull;