diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index b06e1c1..8c74781 100644
*** a/src/backend/executor/nodeAgg.c
--- b/src/backend/executor/nodeAgg.c
***************
*** 164,169 ****
--- 164,170 ----
  #include "parser/parse_coerce.h"
  #include "utils/acl.h"
  #include "utils/builtins.h"
+ #include "utils/fmgroids.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
  #include "utils/syscache.h"
*************** typedef struct AggStatePerTransData
*** 288,293 ****
--- 289,300 ----
  				transtypeByVal;
  
  	/*
+ 	 * This flag says whether we trust the transfn with a read-write pointer
+ 	 * to a transition value that is an expanded object.
+ 	 */
+ 	bool		transfnAllowRW;
+ 
+ 	/*
  	 * Stuff for evaluation of inputs.  We used to just use ExecEvalExpr, but
  	 * with the addition of ORDER BY we now need at least a slot for passing
  	 * data to the sort object, which requires a tupledesc, so we might as
*************** advance_transition_function(AggState *ag
*** 752,760 ****
  			 */
  			oldContext = MemoryContextSwitchTo(
  											   aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
! 			pergroupstate->transValue = datumCopy(fcinfo->arg[1],
! 												  pertrans->transtypeByVal,
! 												  pertrans->transtypeLen);
  			pergroupstate->transValueIsNull = false;
  			pergroupstate->noTransValue = false;
  			MemoryContextSwitchTo(oldContext);
--- 759,767 ----
  			 */
  			oldContext = MemoryContextSwitchTo(
  											   aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
! 			pergroupstate->transValue = datumTransfer(fcinfo->arg[1],
! 													pertrans->transtypeByVal,
! 													  pertrans->transtypeLen);
  			pergroupstate->transValueIsNull = false;
  			pergroupstate->noTransValue = false;
  			MemoryContextSwitchTo(oldContext);
*************** advance_transition_function(AggState *ag
*** 781,787 ****
  	/*
  	 * OK to call the transition function
  	 */
! 	fcinfo->arg[0] = pergroupstate->transValue;
  	fcinfo->argnull[0] = pergroupstate->transValueIsNull;
  	fcinfo->isnull = false;		/* just in case transfn doesn't set it */
  
--- 788,799 ----
  	/*
  	 * OK to call the transition function
  	 */
! 	if (pertrans->transfnAllowRW)
! 		fcinfo->arg[0] = pergroupstate->transValue;
! 	else
! 		fcinfo->arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
! 											 pergroupstate->transValueIsNull,
! 													pertrans->transtypeLen);
  	fcinfo->argnull[0] = pergroupstate->transValueIsNull;
  	fcinfo->isnull = false;		/* just in case transfn doesn't set it */
  
*************** advance_transition_function(AggState *ag
*** 800,811 ****
  		if (!fcinfo->isnull)
  		{
  			MemoryContextSwitchTo(aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
! 			newVal = datumCopy(newVal,
! 							   pertrans->transtypeByVal,
! 							   pertrans->transtypeLen);
  		}
  		if (!pergroupstate->transValueIsNull)
! 			pfree(DatumGetPointer(pergroupstate->transValue));
  	}
  
  	pergroupstate->transValue = newVal;
--- 812,830 ----
  		if (!fcinfo->isnull)
  		{
  			MemoryContextSwitchTo(aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
! 			newVal = datumTransfer(newVal,
! 								   pertrans->transtypeByVal,
! 								   pertrans->transtypeLen);
  		}
  		if (!pergroupstate->transValueIsNull)
! 		{
! 			if (DatumIsReadWriteExpandedObject(pergroupstate->transValue,
! 											   false,
! 											   pertrans->transtypeLen))
! 				DeleteExpandedObject(pergroupstate->transValue);
! 			else
! 				pfree(DatumGetPointer(pergroupstate->transValue));
! 		}
  	}
  
  	pergroupstate->transValue = newVal;
*************** advance_combine_function(AggState *aggst
*** 1020,1028 ****
  			{
  				oldContext = MemoryContextSwitchTo(
  												   aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
! 				pergroupstate->transValue = datumCopy(fcinfo->arg[1],
  													pertrans->transtypeByVal,
! 													  pertrans->transtypeLen);
  				MemoryContextSwitchTo(oldContext);
  			}
  			else
--- 1039,1047 ----
  			{
  				oldContext = MemoryContextSwitchTo(
  												   aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
! 				pergroupstate->transValue = datumTransfer(fcinfo->arg[1],
  													pertrans->transtypeByVal,
! 													 pertrans->transtypeLen);
  				MemoryContextSwitchTo(oldContext);
  			}
  			else
*************** advance_combine_function(AggState *aggst
*** 1043,1049 ****
  	/*
  	 * OK to call the combine function
  	 */
! 	fcinfo->arg[0] = pergroupstate->transValue;
  	fcinfo->argnull[0] = pergroupstate->transValueIsNull;
  	fcinfo->isnull = false;		/* just in case combine func doesn't set it */
  
--- 1062,1073 ----
  	/*
  	 * OK to call the combine function
  	 */
! 	if (pertrans->transfnAllowRW)
! 		fcinfo->arg[0] = pergroupstate->transValue;
! 	else
! 		fcinfo->arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
! 											 pergroupstate->transValueIsNull,
! 													pertrans->transtypeLen);
  	fcinfo->argnull[0] = pergroupstate->transValueIsNull;
  	fcinfo->isnull = false;		/* just in case combine func doesn't set it */
  
*************** advance_combine_function(AggState *aggst
*** 1062,1073 ****
  		if (!fcinfo->isnull)
  		{
  			MemoryContextSwitchTo(aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
! 			newVal = datumCopy(newVal,
! 							   pertrans->transtypeByVal,
! 							   pertrans->transtypeLen);
  		}
  		if (!pergroupstate->transValueIsNull)
! 			pfree(DatumGetPointer(pergroupstate->transValue));
  	}
  
  	pergroupstate->transValue = newVal;
--- 1086,1104 ----
  		if (!fcinfo->isnull)
  		{
  			MemoryContextSwitchTo(aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory);
! 			newVal = datumTransfer(newVal,
! 								   pertrans->transtypeByVal,
! 								   pertrans->transtypeLen);
  		}
  		if (!pergroupstate->transValueIsNull)
! 		{
! 			if (DatumIsReadWriteExpandedObject(pergroupstate->transValue,
! 											   false,
! 											   pertrans->transtypeLen))
! 				DeleteExpandedObject(pergroupstate->transValue);
! 			else
! 				pfree(DatumGetPointer(pergroupstate->transValue));
! 		}
  	}
  
  	pergroupstate->transValue = newVal;
*************** finalize_aggregate(AggState *aggstate,
*** 1333,1339 ****
  								 (void *) aggstate, NULL);
  
  		/* Fill in the transition state value */
! 		fcinfo.arg[0] = pergroupstate->transValue;
  		fcinfo.argnull[0] = pergroupstate->transValueIsNull;
  		anynull |= pergroupstate->transValueIsNull;
  
--- 1364,1372 ----
  								 (void *) aggstate, NULL);
  
  		/* Fill in the transition state value */
! 		fcinfo.arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
! 											 pergroupstate->transValueIsNull,
! 												   pertrans->transtypeLen);
  		fcinfo.argnull[0] = pergroupstate->transValueIsNull;
  		anynull |= pergroupstate->transValueIsNull;
  
*************** finalize_aggregate(AggState *aggstate,
*** 1360,1366 ****
  	}
  	else
  	{
! 		*resultVal = pergroupstate->transValue;
  		*resultIsNull = pergroupstate->transValueIsNull;
  	}
  
--- 1393,1401 ----
  	}
  	else
  	{
! 		*resultVal = MakeExpandedObjectReadOnly(pergroupstate->transValue,
! 											 pergroupstate->transValueIsNull,
! 												pertrans->transtypeLen);
  		*resultIsNull = pergroupstate->transValueIsNull;
  	}
  
*************** finalize_partialaggregate(AggState *aggs
*** 1410,1416 ****
  		{
  			FunctionCallInfo fcinfo = &pertrans->serialfn_fcinfo;
  
! 			fcinfo->arg[0] = pergroupstate->transValue;
  			fcinfo->argnull[0] = pergroupstate->transValueIsNull;
  
  			*resultVal = FunctionCallInvoke(fcinfo);
--- 1445,1453 ----
  		{
  			FunctionCallInfo fcinfo = &pertrans->serialfn_fcinfo;
  
! 			fcinfo->arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
! 											 pergroupstate->transValueIsNull,
! 													 pertrans->transtypeLen);
  			fcinfo->argnull[0] = pergroupstate->transValueIsNull;
  
  			*resultVal = FunctionCallInvoke(fcinfo);
*************** finalize_partialaggregate(AggState *aggs
*** 1419,1425 ****
  	}
  	else
  	{
! 		*resultVal = pergroupstate->transValue;
  		*resultIsNull = pergroupstate->transValueIsNull;
  	}
  
--- 1456,1464 ----
  	}
  	else
  	{
! 		*resultVal = MakeExpandedObjectReadOnly(pergroupstate->transValue,
! 											 pergroupstate->transValueIsNull,
! 												pertrans->transtypeLen);
  		*resultIsNull = pergroupstate->transValueIsNull;
  	}
  
*************** build_pertrans_for_aggref(AggStatePerTra
*** 3029,3034 ****
--- 3068,3077 ----
  					&pertrans->transtypeLen,
  					&pertrans->transtypeByVal);
  
+ 	/* detect whether we'd like to pass read/write expanded pointers */
+ 	pertrans->transfnAllowRW = (aggtransfn == F_ARRAY_APPEND ||
+ 								aggtransfn == F_ARRAY_PREPEND);
+ 
  	if (OidIsValid(aggserialfn))
  	{
  		build_aggregate_serialfn_expr(aggserialfn,
