summaryrefslogtreecommitdiff
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.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index f49114abe3..a2c29c450d 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -756,11 +756,18 @@ advance_transition_function(AggState *aggstate,
aggstate->curpertrans = NULL;
/*
- * If pass-by-ref datatype, must copy the new value into aggcontext and
- * pfree the prior transValue. But if transfn returned a pointer to its
- * first input, we don't need to do anything.
+ * If we got a R/W pointer to an expanded object, we can just take over
+ * control of the object. Any other pass-by-ref value must be copied into
+ * aggcontext and the prior value freed; with the exception that if transfn
+ * returned a pointer to its first input, we don't need to do anything.
*/
- if (!pertrans->transtypeByVal &&
+ if (DatumIsReadWriteExpandedObject(newVal, fcinfo->isnull,
+ pertrans->transtypeLen))
+ {
+ newVal = TransferExpandedObject(newVal,
+ aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
+ }
+ else if (!pertrans->transtypeByVal &&
DatumGetPointer(newVal) != DatumGetPointer(pergroupstate->transValue))
{
if (!fcinfo->isnull)