diff options
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
| -rw-r--r-- | src/backend/executor/nodeAgg.c | 15 |
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) |
