Index: src/backend/utils/adt/float.c
===================================================================
RCS file: /Users/neilc/local/cvs/pgsql/src/backend/utils/adt/float.c,v
retrieving revision 1.113
diff -c -r1.113 float.c
*** src/backend/utils/adt/float.c	11 Feb 2005 04:08:58 -0000	1.113
--- src/backend/utils/adt/float.c	6 Apr 2005 07:24:38 -0000
***************
*** 1902,1909 ****
  	float8		N,
  				sumX,
  				sumX2;
- 	Datum		transdatums[3];
- 	ArrayType  *result;
  
  	transvalues = check_float8_array(transarray, "float8_accum");
  	N = transvalues[0];
--- 1902,1907 ----
***************
*** 1914,1928 ****
  	sumX += newval;
  	sumX2 += newval * newval;
  
! 	transdatums[0] = Float8GetDatumFast(N);
! 	transdatums[1] = Float8GetDatumFast(sumX);
! 	transdatums[2] = Float8GetDatumFast(sumX2);
! 
! 	result = construct_array(transdatums, 3,
! 							 FLOAT8OID,
! 						 sizeof(float8), false /* float8 byval */ , 'd');
  
! 	PG_RETURN_ARRAYTYPE_P(result);
  }
  
  Datum
--- 1912,1946 ----
  	sumX += newval;
  	sumX2 += newval * newval;
  
! 	/*
! 	 * If we're invoked by nodeAgg, we can cheat and modify our first
! 	 * parameter in-place to reduce palloc overhead. Otherwise we
! 	 * construct a new array with the updated transition data and
! 	 * return it.
! 	 */
! 	if (fcinfo->context && IsA(fcinfo->context, AggState))
! 	{
! 		transvalues[0] = N;
! 		transvalues[1] = sumX;
! 		transvalues[2] = sumX2;
! 
! 		PG_RETURN_ARRAYTYPE_P(transarray);
! 	}
! 	else
! 	{
! 		Datum		transdatums[3];
! 		ArrayType  *result;
! 
! 		transdatums[0] = Float8GetDatumFast(N);
! 		transdatums[1] = Float8GetDatumFast(sumX);
! 		transdatums[2] = Float8GetDatumFast(sumX2);
! 
! 		result = construct_array(transdatums, 3,
! 								 FLOAT8OID,
! 								 sizeof(float8), false /* float8 byval */ , 'd');
  
! 		PG_RETURN_ARRAYTYPE_P(result);
! 	}
  }
  
  Datum
***************
*** 1935,1942 ****
  				sumX,
  				sumX2,
  				newval;
- 	Datum		transdatums[3];
- 	ArrayType  *result;
  
  	transvalues = check_float8_array(transarray, "float4_accum");
  	N = transvalues[0];
--- 1953,1958 ----
***************
*** 1950,1964 ****
  	sumX += newval;
  	sumX2 += newval * newval;
  
! 	transdatums[0] = Float8GetDatumFast(N);
! 	transdatums[1] = Float8GetDatumFast(sumX);
! 	transdatums[2] = Float8GetDatumFast(sumX2);
! 
! 	result = construct_array(transdatums, 3,
! 							 FLOAT8OID,
! 						 sizeof(float8), false /* float8 byval */ , 'd');
  
! 	PG_RETURN_ARRAYTYPE_P(result);
  }
  
  Datum
--- 1966,2000 ----
  	sumX += newval;
  	sumX2 += newval * newval;
  
! 	/*
! 	 * If we're invoked by nodeAgg, we can cheat and modify our first
! 	 * parameter in-place to reduce palloc overhead. Otherwise we
! 	 * construct a new array with the updated transition data and
! 	 * return it.
! 	 */
! 	if (fcinfo->context && IsA(fcinfo->context, AggState))
! 	{
! 		transvalues[0] = N;
! 		transvalues[1] = sumX;
! 		transvalues[2] = sumX2;
! 
! 		PG_RETURN_ARRAYTYPE_P(transarray);
! 	}
! 	else
! 	{
! 		Datum		transdatums[3];
! 		ArrayType  *result;
! 
! 		transdatums[0] = Float8GetDatumFast(N);
! 		transdatums[1] = Float8GetDatumFast(sumX);
! 		transdatums[2] = Float8GetDatumFast(sumX2);
! 
! 		result = construct_array(transdatums, 3,
! 								 FLOAT8OID,
! 								 sizeof(float8), false /* float8 byval */ , 'd');
  
! 		PG_RETURN_ARRAYTYPE_P(result);
! 	}
  }
  
  Datum
Index: src/backend/utils/adt/numeric.c
===================================================================
RCS file: /Users/neilc/local/cvs/pgsql/src/backend/utils/adt/numeric.c,v
retrieving revision 1.82
diff -c -r1.82 numeric.c
*** src/backend/utils/adt/numeric.c	4 Apr 2005 23:50:27 -0000	1.82
--- src/backend/utils/adt/numeric.c	6 Apr 2005 08:07:37 -0000
***************
*** 2357,2363 ****
  Datum
  int2_sum(PG_FUNCTION_ARGS)
  {
- 	int64		oldsum;
  	int64		newval;
  
  	if (PG_ARGISNULL(0))
--- 2357,2362 ----
***************
*** 2370,2391 ****
  		PG_RETURN_INT64(newval);
  	}
  
! 	oldsum = PG_GETARG_INT64(0);
  
! 	/* Leave sum unchanged if new input is null. */
! 	if (PG_ARGISNULL(1))
! 		PG_RETURN_INT64(oldsum);
  
! 	/* OK to do the addition. */
! 	newval = oldsum + (int64) PG_GETARG_INT16(1);
  
! 	PG_RETURN_INT64(newval);
  }
  
  Datum
  int4_sum(PG_FUNCTION_ARGS)
  {
- 	int64		oldsum;
  	int64		newval;
  
  	if (PG_ARGISNULL(0))
--- 2369,2407 ----
  		PG_RETURN_INT64(newval);
  	}
  
! 	/*
! 	 * If we're invoked by nodeAgg, we can cheat and modify out first
! 	 * parameter in-place to avoid palloc overhead. If not, we need to
! 	 * return the new value of the transition variable.
! 	 */
! 	if (fcinfo->context && IsA(fcinfo->context, AggState))
! 	{
! 		int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
  
! 		/* Leave the running sum unchanged in the new input is null */
! 		if (!PG_ARGISNULL(1))
! 			*oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
  
! 		PG_RETURN_POINTER(oldsum);
! 	}
! 	else
! 	{
! 		int64		oldsum = PG_GETARG_INT64(0);
! 
! 		/* Leave sum unchanged if new input is null. */
! 		if (PG_ARGISNULL(1))
! 			PG_RETURN_INT64(oldsum);
! 
! 		/* OK to do the addition. */
! 		newval = oldsum + (int64) PG_GETARG_INT16(1);
  
! 		PG_RETURN_INT64(newval);
! 	}
  }
  
  Datum
  int4_sum(PG_FUNCTION_ARGS)
  {
  	int64		newval;
  
  	if (PG_ARGISNULL(0))
***************
*** 2398,2413 ****
  		PG_RETURN_INT64(newval);
  	}
  
! 	oldsum = PG_GETARG_INT64(0);
  
! 	/* Leave sum unchanged if new input is null. */
! 	if (PG_ARGISNULL(1))
! 		PG_RETURN_INT64(oldsum);
  
! 	/* OK to do the addition. */
! 	newval = oldsum + (int64) PG_GETARG_INT32(1);
  
! 	PG_RETURN_INT64(newval);
  }
  
  Datum
--- 2414,2447 ----
  		PG_RETURN_INT64(newval);
  	}
  
! 	/*
! 	 * If we're invoked by nodeAgg, we can cheat and modify out first
! 	 * parameter in-place to avoid palloc overhead. If not, we need to
! 	 * return the new value of the transition variable.
! 	 */
! 	if (fcinfo->context && IsA(fcinfo->context, AggState))
! 	{
! 		int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
  
! 		/* Leave the running sum unchanged in the new input is null */
! 		if (!PG_ARGISNULL(1))
! 			*oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
  
! 		PG_RETURN_POINTER(oldsum);
! 	}
! 	else
! 	{
! 		int64		oldsum = PG_GETARG_INT64(0);
  
! 		/* Leave sum unchanged if new input is null. */
! 		if (PG_ARGISNULL(1))
! 			PG_RETURN_INT64(oldsum);
! 
! 		/* OK to do the addition. */
! 		newval = oldsum + (int64) PG_GETARG_INT32(1);
! 
! 		PG_RETURN_INT64(newval);
! 	}
  }
  
  Datum
***************
*** 2426,2431 ****
--- 2460,2471 ----
  		PG_RETURN_DATUM(newval);
  	}
  
+ 	/*
+ 	 * Note that we cannot special-case the nodeAgg case here, as we
+ 	 * do for int2_sum and int4_sum: numeric is of variable size, so
+ 	 * we cannot modify our first parameter in-place.
+ 	 */
+ 
  	oldsum = PG_GETARG_NUMERIC(0);
  
  	/* Leave sum unchanged if new input is null. */
