diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 229b408..e8294b6 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -2464,94 +2464,122 @@ numeric_float4(PG_FUNCTION_ARGS)
  *
  * Aggregate functions
  *
- * The transition datatype for all these aggregates is a 3-element array
- * of Numeric, holding the values N, sum(X), sum(X*X) in that order.
- *
- * We represent N as a numeric mainly to avoid having to build a special
- * datatype; it's unlikely it'd overflow an int4, but ...
+ * The transition datatype for all these aggregates is a pointer to 
+ * a struct NumericAggState allocated in the aggregate context.
  *
  * ----------------------------------------------------------------------
  */
 
-static ArrayType *
-do_numeric_accum(ArrayType *transarray, Numeric newval)
+typedef struct NumericAggState
+{
+	bool 			first;
+	bool 			isNaN;
+	uint64			N;
+	NumericVar 		sumX;
+	NumericVar 		sumX2;
+	bool 			calcSumX2;
+	MemoryContext 	agg_context;
+} NumericAggState;
+
+static NumericAggState *
+makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
 {
-	Datum	   *transdatums;
-	int			ndatums;
-	Datum		N,
-				sumX,
-				sumX2;
-	ArrayType  *result;
-
-	/* We assume the input is array of numeric */
-	deconstruct_array(transarray,
-					  NUMERICOID, -1, false, 'i',
-					  &transdatums, NULL, &ndatums);
-	if (ndatums != 3)
-		elog(ERROR, "expected 3-element numeric array");
-	N = transdatums[0];
-	sumX = transdatums[1];
-	sumX2 = transdatums[2];
-
-	N = DirectFunctionCall1(numeric_inc, N);
-	sumX = DirectFunctionCall2(numeric_add, sumX,
-							   NumericGetDatum(newval));
-	sumX2 = DirectFunctionCall2(numeric_add, sumX2,
-								DirectFunctionCall2(numeric_mul,
-													NumericGetDatum(newval),
-													NumericGetDatum(newval)));
-
-	transdatums[0] = N;
-	transdatums[1] = sumX;
-	transdatums[2] = sumX2;
-
-	result = construct_array(transdatums, 3,
-							 NUMERICOID, -1, false, 'i');
+	NumericAggState 	*state;
+	MemoryContext 		 agg_context;
+	MemoryContext 		 old_context;
 
-	return result;
+	if (!AggCheckCallContext(fcinfo, &agg_context))
+	{
+		elog(ERROR, "this is called in non-aggregate context");
+	}
+
+	old_context = MemoryContextSwitchTo(agg_context);
+
+	state = palloc0(sizeof(NumericAggState));
+	state->first = true;
+	state->calcSumX2 = calcSumX2;
+	state->agg_context = agg_context;
+
+	MemoryContextSwitchTo(old_context);
+
+	return state;
 }
 
-/*
- * Improve avg performance by not caclulating sum(X*X).
- */
-static ArrayType *
-do_numeric_avg_accum(ArrayType *transarray, Numeric newval)
+static void
+do_numeric_accum(NumericAggState *state, Numeric newval)
 {
-	Datum	   *transdatums;
-	int			ndatums;
-	Datum		N,
-				sumX;
-	ArrayType  *result;
-
-	/* We assume the input is array of numeric */
-	deconstruct_array(transarray,
-					  NUMERICOID, -1, false, 'i',
-					  &transdatums, NULL, &ndatums);
-	if (ndatums != 2)
-		elog(ERROR, "expected 2-element numeric array");
-	N = transdatums[0];
-	sumX = transdatums[1];
-
-	N = DirectFunctionCall1(numeric_inc, N);
-	sumX = DirectFunctionCall2(numeric_add, sumX,
-							   NumericGetDatum(newval));
-
-	transdatums[0] = N;
-	transdatums[1] = sumX;
-
-	result = construct_array(transdatums, 2,
-							 NUMERICOID, -1, false, 'i');
+	NumericVar 		X;
+	NumericVar 		X2;
+	MemoryContext 	old_context;
+	bool 			first;
+	
+	first = state->first;
+	state->first = false;
+	state->N++;
+
+	if (state->isNaN || NUMERIC_IS_NAN(newval))
+	{
+		state->isNaN = true;
+		return;
+	}
 
-	return result;
+	init_var_from_num(newval, &X);
+
+	if (state->calcSumX2)
+	{
+		init_var(&X2);
+		mul_var(&X, &X, &X2, X.dscale * 2);
+	}
+
+	old_context = MemoryContextSwitchTo(state->agg_context);
+
+	if (!first)
+	{
+		NumericVar preSumX;
+
+		memcpy(&preSumX, &(state->sumX), sizeof(NumericVar));
+		init_var(&(state->sumX));
+		add_var(&X, &preSumX, &(state->sumX));
+		free_var(&preSumX);
+
+		if (state->calcSumX2)
+		{
+			NumericVar preSumX2;
+
+			memcpy(&preSumX2, &(state->sumX2), sizeof(NumericVar));
+			init_var(&(state->sumX2));
+			add_var(&X2, &preSumX2, &(state->sumX2));
+			free_var(&preSumX2);
+		}
+	}
+	else
+	{
+		set_var_from_var(&X, &(state->sumX));
+
+		if (state->calcSumX2)
+			set_var_from_var(&X2, &(state->sumX2));
+	}
+
+	MemoryContextSwitchTo(old_context);
 }
 
 Datum
 numeric_accum(PG_FUNCTION_ARGS)
 {
-	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
-	Numeric		newval = PG_GETARG_NUMERIC(1);
+	NumericAggState *state;
+
+	state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
+
+	if (!PG_ARGISNULL(1))
+	{
+		/* On the first time through, create the state variable. */
+		if (state == NULL)
+			state = makeNumericAggState(fcinfo, true);
+		
+		do_numeric_accum(state, PG_GETARG_NUMERIC(1));
+	}
 
-	PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
+	PG_RETURN_POINTER(state);
 }
 
 /*
@@ -2560,10 +2588,20 @@ numeric_accum(PG_FUNCTION_ARGS)
 Datum
 numeric_avg_accum(PG_FUNCTION_ARGS)
 {
-	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
-	Numeric		newval = PG_GETARG_NUMERIC(1);
+	NumericAggState *state;
 
-	PG_RETURN_ARRAYTYPE_P(do_numeric_avg_accum(transarray, newval));
+	state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
+
+	if (!PG_ARGISNULL(1))
+	{
+		/* On the first time through, create the state variable. */
+		if (state == NULL)
+			state = makeNumericAggState(fcinfo, false);
+		
+		do_numeric_accum(state, PG_GETARG_NUMERIC(1));
+	}
+
+	PG_RETURN_POINTER(state);
 }
 
 /*
@@ -2578,37 +2616,70 @@ numeric_avg_accum(PG_FUNCTION_ARGS)
 Datum
 int2_accum(PG_FUNCTION_ARGS)
 {
-	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
-	Datum		newval2 = PG_GETARG_DATUM(1);
-	Numeric		newval;
+	NumericAggState *state;
 
-	newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric, newval2));
+	state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
+
+	if (!PG_ARGISNULL(1))
+	{
+		Datum		newval2 = PG_GETARG_DATUM(1);
+		Numeric		newval;
+
+		/* On the first time through, create the state variable. */
+		if (state == NULL)
+			state = makeNumericAggState(fcinfo, true);
+		
+		newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric, newval2));
+		do_numeric_accum(state, newval);
+	}
 
-	PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
+	PG_RETURN_POINTER(state);
 }
 
 Datum
 int4_accum(PG_FUNCTION_ARGS)
 {
-	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
-	Datum		newval4 = PG_GETARG_DATUM(1);
-	Numeric		newval;
+	NumericAggState *state;
+
+	state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
 
-	newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric, newval4));
+	if (!PG_ARGISNULL(1))
+	{
+		Datum		newval4 = PG_GETARG_DATUM(1);
+		Numeric		newval;
+
+		/* On the first time through, create the state variable. */
+		if (state == NULL)
+			state = makeNumericAggState(fcinfo, true);
+		
+		newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric, newval4));
+		do_numeric_accum(state, newval);
+	}
 
-	PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
+	PG_RETURN_POINTER(state);
 }
 
 Datum
 int8_accum(PG_FUNCTION_ARGS)
 {
-	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
-	Datum		newval8 = PG_GETARG_DATUM(1);
-	Numeric		newval;
+	NumericAggState *state;
 
-	newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8));
+	state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
 
-	PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
+	if (!PG_ARGISNULL(1))
+	{
+		Datum		newval8 = PG_GETARG_DATUM(1);
+		Numeric		newval;
+
+		/* On the first time through, create the state variable. */
+		if (state == NULL)
+			state = makeNumericAggState(fcinfo, true);
+		
+		newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8));
+		do_numeric_accum(state, newval);
+	}
+
+	PG_RETURN_POINTER(state);
 }
 
 /*
@@ -2617,48 +2688,61 @@ int8_accum(PG_FUNCTION_ARGS)
 Datum
 int8_avg_accum(PG_FUNCTION_ARGS)
 {
-	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
-	Datum		newval8 = PG_GETARG_DATUM(1);
-	Numeric		newval;
+	NumericAggState *state;
 
-	newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8));
+	state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
 
-	PG_RETURN_ARRAYTYPE_P(do_numeric_avg_accum(transarray, newval));
-}
+	if (!PG_ARGISNULL(1))
+	{
+		Datum		newval8 = PG_GETARG_DATUM(1);
+		Numeric		newval;
+
+		/* On the first time through, create the state variable. */
+		if (state == NULL)
+			state = makeNumericAggState(fcinfo, false);
+		
+		newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8));
+		do_numeric_accum(state, newval);
+	}
 
+	PG_RETURN_POINTER(state);
+}
 
 Datum
 numeric_avg(PG_FUNCTION_ARGS)
 {
-	ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
-	Datum	   *transdatums;
-	int			ndatums;
-	Numeric		N,
-				sumX;
-
-	/* We assume the input is array of numeric */
-	deconstruct_array(transarray,
-					  NUMERICOID, -1, false, 'i',
-					  &transdatums, NULL, &ndatums);
-	if (ndatums != 2)
-		elog(ERROR, "expected 2-element numeric array");
-	N = DatumGetNumeric(transdatums[0]);
-	sumX = DatumGetNumeric(transdatums[1]);
+	Datum 		 		N_datum;
+	Datum 				sumX_datum;
+	NumericAggState 	*state;
 
-	/* SQL92 defines AVG of no values to be NULL */
-	/* N is zero iff no digits (cf. numeric_uminus) */
-	if (NUMERIC_NDIGITS(N) == 0)
+	if (PG_ARGISNULL(0))
+		PG_RETURN_NULL();
+
+	state = (NumericAggState *) PG_GETARG_POINTER(0);
+
+	N_datum = DirectFunctionCall1(int8_numeric, Int64GetDatum(state->N));
+	sumX_datum = NumericGetDatum(make_result(&state->sumX));
+
+	PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
+}
+
+Datum
+numeric_sum(PG_FUNCTION_ARGS)
+{
+	NumericAggState 	*state;
+
+	if (PG_ARGISNULL(0))
 		PG_RETURN_NULL();
 
-	PG_RETURN_DATUM(DirectFunctionCall2(numeric_div,
-										NumericGetDatum(sumX),
-										NumericGetDatum(N)));
+	state = (NumericAggState *) PG_GETARG_POINTER(0);
+
+	PG_RETURN_NUMERIC(make_result(&(state->sumX)));
 }
 
 /*
  * Workhorse routine for the standard deviance and variance
- * aggregates. 'transarray' is the aggregate's transition
- * array. 'variance' specifies whether we should calculate the
+ * aggregates. 'state' is aggregate's transition state.
+ * 'variance' specifies whether we should calculate the
  * variance or the standard deviation. 'sample' indicates whether the
  * caller is interested in the sample or the population
  * variance/stddev.
@@ -2667,16 +2751,11 @@ numeric_avg(PG_FUNCTION_ARGS)
  * *is_null is set to true and NULL is returned.
  */
 static Numeric
-numeric_stddev_internal(ArrayType *transarray,
+numeric_stddev_internal(NumericAggState *state,
 						bool variance, bool sample,
 						bool *is_null)
 {
-	Datum	   *transdatums;
-	int			ndatums;
-	Numeric		N,
-				sumX,
-				sumX2,
-				res;
+	Numeric		res;
 	NumericVar	vN,
 				vsumX,
 				vsumX2,
@@ -2684,22 +2763,24 @@ numeric_stddev_internal(ArrayType *transarray,
 	NumericVar *comp;
 	int			rscale;
 
+	if (state == NULL)
+	{
+		*is_null = true;
+		return NULL;
+	}
+
 	*is_null = false;
 
-	/* We assume the input is array of numeric */
-	deconstruct_array(transarray,
-					  NUMERICOID, -1, false, 'i',
-					  &transdatums, NULL, &ndatums);
-	if (ndatums != 3)
-		elog(ERROR, "expected 3-element numeric array");
-	N = DatumGetNumeric(transdatums[0]);
-	sumX = DatumGetNumeric(transdatums[1]);
-	sumX2 = DatumGetNumeric(transdatums[2]);
-
-	if (NUMERIC_IS_NAN(N) || NUMERIC_IS_NAN(sumX) || NUMERIC_IS_NAN(sumX2))
+	if (state->isNaN)
 		return make_result(&const_nan);
 
-	init_var_from_num(N, &vN);
+	init_var(&vN);
+	init_var(&vsumX);
+	init_var(&vsumX2);
+
+	int8_to_numericvar(state->N, &vN);
+	set_var_from_var(&(state->sumX), &vsumX);
+	set_var_from_var(&(state->sumX2), &vsumX2);
 
 	/*
 	 * Sample stddev and variance are undefined when N <= 1; population stddev
@@ -2719,8 +2800,8 @@ numeric_stddev_internal(ArrayType *transarray,
 	init_var(&vNminus1);
 	sub_var(&vN, &const_one, &vNminus1);
 
-	init_var_from_num(sumX, &vsumX);
-	init_var_from_num(sumX2, &vsumX2);
+	set_var_from_var(&(state->sumX), &vsumX);
+	set_var_from_var(&(state->sumX2), &vsumX2);
 
 	/* compute rscale for mul_var calls */
 	rscale = vsumX.dscale * 2;
@@ -2761,7 +2842,7 @@ numeric_var_samp(PG_FUNCTION_ARGS)
 	Numeric		res;
 	bool		is_null;
 
-	res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
+	res = numeric_stddev_internal((NumericAggState *) PG_GETARG_POINTER(0),
 								  true, true, &is_null);
 
 	if (is_null)
@@ -2776,7 +2857,7 @@ numeric_stddev_samp(PG_FUNCTION_ARGS)
 	Numeric		res;
 	bool		is_null;
 
-	res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
+	res = numeric_stddev_internal((NumericAggState *) PG_GETARG_POINTER(0),
 								  false, true, &is_null);
 
 	if (is_null)
@@ -2791,7 +2872,7 @@ numeric_var_pop(PG_FUNCTION_ARGS)
 	Numeric		res;
 	bool		is_null;
 
-	res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
+	res = numeric_stddev_internal((NumericAggState *) PG_GETARG_POINTER(0),
 								  true, false, &is_null);
 
 	if (is_null)
@@ -2806,7 +2887,7 @@ numeric_stddev_pop(PG_FUNCTION_ARGS)
 	Numeric		res;
 	bool		is_null;
 
-	res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
+	res = numeric_stddev_internal((NumericAggState *) PG_GETARG_POINTER(0),
 								  false, false, &is_null);
 
 	if (is_null)
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 6fb10a9..6f4090e 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -77,23 +77,23 @@ typedef FormData_pg_aggregate *Form_pg_aggregate;
  */
 
 /* avg */
-DATA(insert ( 2100	int8_avg_accum	numeric_avg		0	1231	"{0,0}" ));
+DATA(insert ( 2100	int8_avg_accum	numeric_avg		0	2281	_null_ ));
 DATA(insert ( 2101	int4_avg_accum	int8_avg		0	1016	"{0,0}" ));
 DATA(insert ( 2102	int2_avg_accum	int8_avg		0	1016	"{0,0}" ));
-DATA(insert ( 2103	numeric_avg_accum	numeric_avg		0	1231	"{0,0}" ));
+DATA(insert ( 2103	numeric_avg_accum	numeric_avg		0	2281	_null_ ));
 DATA(insert ( 2104	float4_accum	float8_avg		0	1022	"{0,0,0}" ));
 DATA(insert ( 2105	float8_accum	float8_avg		0	1022	"{0,0,0}" ));
 DATA(insert ( 2106	interval_accum	interval_avg	0	1187	"{0 second,0 second}" ));
 
 /* sum */
-DATA(insert ( 2107	int8_sum		-				0	1700	_null_ ));
+DATA(insert ( 2107	int8_avg_accum	numeric_sum		0	2281	_null_ ));
 DATA(insert ( 2108	int4_sum		-				0	20		_null_ ));
 DATA(insert ( 2109	int2_sum		-				0	20		_null_ ));
 DATA(insert ( 2110	float4pl		-				0	700		_null_ ));
 DATA(insert ( 2111	float8pl		-				0	701		_null_ ));
 DATA(insert ( 2112	cash_pl			-				0	790		_null_ ));
 DATA(insert ( 2113	interval_pl		-				0	1186	_null_ ));
-DATA(insert ( 2114	numeric_add		-				0	1700	_null_ ));
+DATA(insert ( 2114	numeric_avg_accum	numeric_sum	0	2281	_null_ ));
 
 /* max */
 DATA(insert ( 2115	int8larger		-				413		20		_null_ ));
@@ -144,52 +144,52 @@ DATA(insert ( 2147	int8inc_any		-				0		20		"0" ));
 DATA(insert ( 2803	int8inc			-				0		20		"0" ));
 
 /* var_pop */
-DATA(insert ( 2718	int8_accum	numeric_var_pop 0	1231	"{0,0,0}" ));
-DATA(insert ( 2719	int4_accum	numeric_var_pop 0	1231	"{0,0,0}" ));
-DATA(insert ( 2720	int2_accum	numeric_var_pop 0	1231	"{0,0,0}" ));
+DATA(insert ( 2718	int8_accum	numeric_var_pop 0	2281	_null_ ));
+DATA(insert ( 2719	int4_accum	numeric_var_pop 0	2281	_null_ ));
+DATA(insert ( 2720	int2_accum	numeric_var_pop 0	2281	_null_ ));
 DATA(insert ( 2721	float4_accum	float8_var_pop 0	1022	"{0,0,0}" ));
 DATA(insert ( 2722	float8_accum	float8_var_pop 0	1022	"{0,0,0}" ));
-DATA(insert ( 2723	numeric_accum  numeric_var_pop 0	1231	"{0,0,0}" ));
+DATA(insert ( 2723	numeric_accum  numeric_var_pop 0	2281	_null_ ));
 
 /* var_samp */
-DATA(insert ( 2641	int8_accum	numeric_var_samp	0	1231	"{0,0,0}" ));
-DATA(insert ( 2642	int4_accum	numeric_var_samp	0	1231	"{0,0,0}" ));
-DATA(insert ( 2643	int2_accum	numeric_var_samp	0	1231	"{0,0,0}" ));
+DATA(insert ( 2641	int8_accum	numeric_var_samp	0	2281	_null_ ));
+DATA(insert ( 2642	int4_accum	numeric_var_samp	0	2281	_null_ ));
+DATA(insert ( 2643	int2_accum	numeric_var_samp	0	2281	_null_ ));
 DATA(insert ( 2644	float4_accum	float8_var_samp 0	1022	"{0,0,0}" ));
 DATA(insert ( 2645	float8_accum	float8_var_samp 0	1022	"{0,0,0}" ));
-DATA(insert ( 2646	numeric_accum  numeric_var_samp 0	1231	"{0,0,0}" ));
+DATA(insert ( 2646	numeric_accum  numeric_var_samp 0	2281	_null_ ));
 
 /* variance: historical Postgres syntax for var_samp */
-DATA(insert ( 2148	int8_accum	numeric_var_samp	0	1231	"{0,0,0}" ));
-DATA(insert ( 2149	int4_accum	numeric_var_samp	0	1231	"{0,0,0}" ));
-DATA(insert ( 2150	int2_accum	numeric_var_samp	0	1231	"{0,0,0}" ));
+DATA(insert ( 2148	int8_accum	numeric_var_samp	0	2281	_null_ ));
+DATA(insert ( 2149	int4_accum	numeric_var_samp	0	2281	_null_ ));
+DATA(insert ( 2150	int2_accum	numeric_var_samp	0	2281	_null_ ));
 DATA(insert ( 2151	float4_accum	float8_var_samp 0	1022	"{0,0,0}" ));
 DATA(insert ( 2152	float8_accum	float8_var_samp 0	1022	"{0,0,0}" ));
-DATA(insert ( 2153	numeric_accum  numeric_var_samp 0	1231	"{0,0,0}" ));
+DATA(insert ( 2153	numeric_accum  numeric_var_samp 0	2281	_null_ ));
 
 /* stddev_pop */
-DATA(insert ( 2724	int8_accum	numeric_stddev_pop		0	1231	"{0,0,0}" ));
-DATA(insert ( 2725	int4_accum	numeric_stddev_pop		0	1231	"{0,0,0}" ));
-DATA(insert ( 2726	int2_accum	numeric_stddev_pop		0	1231	"{0,0,0}" ));
+DATA(insert ( 2724	int8_accum	numeric_stddev_pop		0	2281	_null_ ));
+DATA(insert ( 2725	int4_accum	numeric_stddev_pop		0	2281	_null_ ));
+DATA(insert ( 2726	int2_accum	numeric_stddev_pop		0	2281	_null_ ));
 DATA(insert ( 2727	float4_accum	float8_stddev_pop	0	1022	"{0,0,0}" ));
 DATA(insert ( 2728	float8_accum	float8_stddev_pop	0	1022	"{0,0,0}" ));
-DATA(insert ( 2729	numeric_accum	numeric_stddev_pop	0	1231	"{0,0,0}" ));
+DATA(insert ( 2729	numeric_accum	numeric_stddev_pop	0	2281	_null_ ));
 
 /* stddev_samp */
-DATA(insert ( 2712	int8_accum	numeric_stddev_samp		0	1231	"{0,0,0}" ));
-DATA(insert ( 2713	int4_accum	numeric_stddev_samp		0	1231	"{0,0,0}" ));
-DATA(insert ( 2714	int2_accum	numeric_stddev_samp		0	1231	"{0,0,0}" ));
+DATA(insert ( 2712	int8_accum	numeric_stddev_samp		0	2281	_null_ ));
+DATA(insert ( 2713	int4_accum	numeric_stddev_samp		0	2281	_null_ ));
+DATA(insert ( 2714	int2_accum	numeric_stddev_samp		0	2281	_null_ ));
 DATA(insert ( 2715	float4_accum	float8_stddev_samp	0	1022	"{0,0,0}" ));
 DATA(insert ( 2716	float8_accum	float8_stddev_samp	0	1022	"{0,0,0}" ));
-DATA(insert ( 2717	numeric_accum	numeric_stddev_samp 0	1231	"{0,0,0}" ));
+DATA(insert ( 2717	numeric_accum	numeric_stddev_samp 0	2281	_null_ ));
 
 /* stddev: historical Postgres syntax for stddev_samp */
-DATA(insert ( 2154	int8_accum	numeric_stddev_samp		0	1231	"{0,0,0}" ));
-DATA(insert ( 2155	int4_accum	numeric_stddev_samp		0	1231	"{0,0,0}" ));
-DATA(insert ( 2156	int2_accum	numeric_stddev_samp		0	1231	"{0,0,0}" ));
+DATA(insert ( 2154	int8_accum	numeric_stddev_samp		0	2281	_null_ ));
+DATA(insert ( 2155	int4_accum	numeric_stddev_samp		0	2281	_null_ ));
+DATA(insert ( 2156	int2_accum	numeric_stddev_samp		0	2281	_null_ ));
 DATA(insert ( 2157	float4_accum	float8_stddev_samp	0	1022	"{0,0,0}" ));
 DATA(insert ( 2158	float8_accum	float8_stddev_samp	0	1022	"{0,0,0}" ));
-DATA(insert ( 2159	numeric_accum	numeric_stddev_samp 0	1231	"{0,0,0}" ));
+DATA(insert ( 2159	numeric_accum	numeric_stddev_samp 0	2281	_null_ ));
 
 /* SQL2003 binary regression aggregates */
 DATA(insert ( 2818	int8inc_float8_float8		-				0	20		"0" ));
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index c97056e..8541112 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -2383,27 +2383,29 @@ DATA(insert OID = 2513 (  float8_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f t f i
 DESCR("aggregate final function");
 DATA(insert OID = 1832 (  float8_stddev_samp	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "1022" _null_ _null_ _null_ _null_ float8_stddev_samp _null_ _null_ _null_ ));
 DESCR("aggregate final function");
-DATA(insert OID = 1833 (  numeric_accum    PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1700" _null_ _null_ _null_ _null_ numeric_accum _null_ _null_ _null_ ));
+DATA(insert OID = 1833 (  numeric_accum    PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 1700" _null_ _null_ _null_ _null_ numeric_accum _null_ _null_ _null_ ));
 DESCR("aggregate transition function");
-DATA(insert OID = 2858 (  numeric_avg_accum    PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1700" _null_ _null_ _null_ _null_ numeric_avg_accum _null_ _null_ _null_ ));
+DATA(insert OID = 2858 (  numeric_avg_accum    PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 1700" _null_ _null_ _null_ _null_ numeric_avg_accum _null_ _null_ _null_ ));
 DESCR("aggregate transition function");
-DATA(insert OID = 1834 (  int2_accum	   PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 21" _null_ _null_ _null_ _null_ int2_accum _null_ _null_ _null_ ));
+DATA(insert OID = 1834 (  int2_accum	   PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 21" _null_ _null_ _null_ _null_ int2_accum _null_ _null_ _null_ ));
 DESCR("aggregate transition function");
-DATA(insert OID = 1835 (  int4_accum	   PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 23" _null_ _null_ _null_ _null_ int4_accum _null_ _null_ _null_ ));
+DATA(insert OID = 1835 (  int4_accum	   PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 23" _null_ _null_ _null_ _null_ int4_accum _null_ _null_ _null_ ));
 DESCR("aggregate transition function");
-DATA(insert OID = 1836 (  int8_accum	   PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 20" _null_ _null_ _null_ _null_ int8_accum _null_ _null_ _null_ ));
+DATA(insert OID = 1836 (  int8_accum	   PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 20" _null_ _null_ _null_ _null_ int8_accum _null_ _null_ _null_ ));
 DESCR("aggregate transition function");
-DATA(insert OID = 2746 (  int8_avg_accum	   PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 20" _null_ _null_ _null_ _null_ int8_avg_accum _null_ _null_ _null_ ));
+DATA(insert OID = 2746 (  int8_avg_accum	   PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 20" _null_ _null_ _null_ _null_ int8_avg_accum _null_ _null_ _null_ ));
 DESCR("aggregate transition function");
-DATA(insert OID = 1837 (  numeric_avg	   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_avg _null_ _null_ _null_ ));
+DATA(insert OID = 1837 (  numeric_avg	   PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_avg _null_ _null_ _null_ ));
 DESCR("aggregate final function");
-DATA(insert OID = 2514 (  numeric_var_pop  PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_var_pop _null_ _null_ _null_ ));
+DATA(insert OID = 3179 (  numeric_sum	   PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_sum _null_ _null_ _null_ ));
 DESCR("aggregate final function");
-DATA(insert OID = 1838 (  numeric_var_samp PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_var_samp _null_ _null_ _null_ ));
+DATA(insert OID = 2514 (  numeric_var_pop  PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_var_pop _null_ _null_ _null_ ));
 DESCR("aggregate final function");
-DATA(insert OID = 2596 (  numeric_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_	numeric_stddev_pop _null_ _null_ _null_ ));
+DATA(insert OID = 1838 (  numeric_var_samp PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_var_samp _null_ _null_ _null_ ));
 DESCR("aggregate final function");
-DATA(insert OID = 1839 (  numeric_stddev_samp	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_stddev_samp _null_ _null_ _null_ ));
+DATA(insert OID = 2596 (  numeric_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_	numeric_stddev_pop _null_ _null_ _null_ ));
+DESCR("aggregate final function");
+DATA(insert OID = 1839 (  numeric_stddev_samp	PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_stddev_samp _null_ _null_ _null_ ));
 DESCR("aggregate final function");
 DATA(insert OID = 1840 (  int2_sum		   PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 20 "20 21" _null_ _null_ _null_ _null_ int2_sum _null_ _null_ _null_ ));
 DESCR("aggregate transition function");
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index c0debe4..fb8880f 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -980,6 +980,7 @@ extern Datum int4_accum(PG_FUNCTION_ARGS);
 extern Datum int8_accum(PG_FUNCTION_ARGS);
 extern Datum int8_avg_accum(PG_FUNCTION_ARGS);
 extern Datum numeric_avg(PG_FUNCTION_ARGS);
+extern Datum numeric_sum(PG_FUNCTION_ARGS);
 extern Datum numeric_var_pop(PG_FUNCTION_ARGS);
 extern Datum numeric_var_samp(PG_FUNCTION_ARGS);
 extern Datum numeric_stddev_pop(PG_FUNCTION_ARGS);
