aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/numeric.c
diff options
context:
space:
mode:
authorNeil Conway <neilc@samurai.com>2005-04-06 23:56:07 +0000
committerNeil Conway <neilc@samurai.com>2005-04-06 23:56:07 +0000
commitbe2f825d51176bd21a627a529476f94de5bad4c2 (patch)
tree72f9ceb6d1da0fbb10dcfd7355e70b5797ce4b28 /src/backend/utils/adt/numeric.c
parenta6bbfedcf7a899c91182f373f93f15f5af247647 (diff)
downloadpostgresql-be2f825d51176bd21a627a529476f94de5bad4c2.tar.gz
postgresql-be2f825d51176bd21a627a529476f94de5bad4c2.zip
Apply the "nodeAgg" optimization to more of the builtin transition
functions. This patch optimizes int2_sum(), int4_sum(), float4_accum() and float8_accum() to avoid needing to copy the transition function's state for each input tuple of the aggregate. In an extreme case (e.g. SELECT sum(int2_col) FROM table where table has a single column), it improves performance by about 20%. For more complex queries or tables with wider rows, the relative performance improvement will not be as significant.
Diffstat (limited to 'src/backend/utils/adt/numeric.c')
-rw-r--r--src/backend/utils/adt/numeric.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index a459ca2d6e4..214f9ff7a34 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -14,7 +14,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -2357,7 +2357,6 @@ numeric_stddev(PG_FUNCTION_ARGS)
Datum
int2_sum(PG_FUNCTION_ARGS)
{
- int64 oldsum;
int64 newval;
if (PG_ARGISNULL(0))
@@ -2370,22 +2369,39 @@ int2_sum(PG_FUNCTION_ARGS)
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))
@@ -2398,16 +2414,34 @@ int4_sum(PG_FUNCTION_ARGS)
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
@@ -2426,6 +2460,12 @@ int8_sum(PG_FUNCTION_ARGS)
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. */