*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.113 2005/02/11 04:08:58 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.114 2005/04/06 23:56:07 neilc Exp $
*
*-------------------------------------------------------------------------
*/
float8 N,
sumX,
sumX2;
- Datum transdatums[3];
- ArrayType *result;
transvalues = check_float8_array(transarray, "float8_accum");
N = transvalues[0];
sumX += newval;
sumX2 += newval * newval;
- transdatums[0] = Float8GetDatumFast(N);
- transdatums[1] = Float8GetDatumFast(sumX);
- transdatums[2] = Float8GetDatumFast(sumX2);
+ /*
+ * 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;
- result = construct_array(transdatums, 3,
- FLOAT8OID,
- sizeof(float8), false /* float8 byval */ , 'd');
+ PG_RETURN_ARRAYTYPE_P(transarray);
+ }
+ else
+ {
+ Datum transdatums[3];
+ ArrayType *result;
+
+ transdatums[0] = Float8GetDatumFast(N);
+ transdatums[1] = Float8GetDatumFast(sumX);
+ transdatums[2] = Float8GetDatumFast(sumX2);
- PG_RETURN_ARRAYTYPE_P(result);
+ result = construct_array(transdatums, 3,
+ FLOAT8OID,
+ sizeof(float8), false /* float8 byval */ , 'd');
+
+ PG_RETURN_ARRAYTYPE_P(result);
+ }
}
Datum
sumX,
sumX2,
newval;
- Datum transdatums[3];
- ArrayType *result;
transvalues = check_float8_array(transarray, "float4_accum");
N = transvalues[0];
sumX += newval;
sumX2 += newval * newval;
- transdatums[0] = Float8GetDatumFast(N);
- transdatums[1] = Float8GetDatumFast(sumX);
- transdatums[2] = Float8GetDatumFast(sumX2);
+ /*
+ * 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;
- result = construct_array(transdatums, 3,
- FLOAT8OID,
- sizeof(float8), false /* float8 byval */ , 'd');
+ PG_RETURN_ARRAYTYPE_P(transarray);
+ }
+ else
+ {
+ Datum transdatums[3];
+ ArrayType *result;
+
+ transdatums[0] = Float8GetDatumFast(N);
+ transdatums[1] = Float8GetDatumFast(sumX);
+ transdatums[2] = Float8GetDatumFast(sumX2);
- PG_RETURN_ARRAYTYPE_P(result);
+ result = construct_array(transdatums, 3,
+ FLOAT8OID,
+ sizeof(float8), false /* float8 byval */ , 'd');
+
+ PG_RETURN_ARRAYTYPE_P(result);
+ }
}
Datum
* Copyright (c) 1998-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.82 2005/04/04 23:50:27 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.83 2005/04/06 23:56:07 neilc Exp $
*
*-------------------------------------------------------------------------
*/
Datum
int2_sum(PG_FUNCTION_ARGS)
{
- int64 oldsum;
int64 newval;
if (PG_ARGISNULL(0))
PG_RETURN_INT64(newval);
}
- oldsum = PG_GETARG_INT64(0);
+ /*
+ * 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 sum unchanged if new input is null. */
- if (PG_ARGISNULL(1))
- PG_RETURN_INT64(oldsum);
+ /* Leave the running sum unchanged in the new input is null */
+ if (!PG_ARGISNULL(1))
+ *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
- /* OK to do the addition. */
- newval = 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);
+ PG_RETURN_INT64(newval);
+ }
}
Datum
int4_sum(PG_FUNCTION_ARGS)
{
- int64 oldsum;
int64 newval;
if (PG_ARGISNULL(0))
PG_RETURN_INT64(newval);
}
- oldsum = PG_GETARG_INT64(0);
+ /*
+ * 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 sum unchanged if new input is null. */
- if (PG_ARGISNULL(1))
- PG_RETURN_INT64(oldsum);
+ /* Leave the running sum unchanged in the new input is null */
+ if (!PG_ARGISNULL(1))
+ *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
- /* OK to do the addition. */
- newval = oldsum + (int64) PG_GETARG_INT32(1);
+ PG_RETURN_POINTER(oldsum);
+ }
+ else
+ {
+ int64 oldsum = PG_GETARG_INT64(0);
- PG_RETURN_INT64(newval);
+ /* 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
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. */