On 03/18/2015 11:59 PM, Peter Geoghegan wrote:
Okay. Attached revision has a few tweaks that reflect the status of
int128/uint128 as specialized types that are basically only useful for
this optimization, or other similar optimizations on compilers that
either are GCC, or aim to be compatible with it. I don't think
Andreas' V9 reflected that sufficiently.
Also, I now always use PolyNumAggState (the typedef), even for #define
HAVE_INT128 code, which I think is a bit clearer. Note that I have
generated a minimal diff, without the machine generated changes that
are ordinarily included in the final commit when autoconf tests are
added, mostly because I do not have the exact version of autoconf on
my development machine required to do this without creating irrelevant
Thanks,
I have attached a patch where I have ran autoconf.
--
Andreas Karlsson
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 509f961..2db04ab 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -125,6 +125,43 @@ undefine([Ac_cachevar])dnl
])# PGAC_TYPE_64BIT_INT
+# PGAC_HAVE_GCC__INT128
+# ---------------------
+# Check if __int128 is a working 128 bit integer type, and if so define
+# HAVE_GCC__INT128. This is a GCC extension, unlike the other integer types,
+# which C99 defines.
+AC_DEFUN([PGAC_HAVE_GCC__INT128],
+[AC_CACHE_CHECK(for __int128, pgac_cv_have_gcc__int128,
+[AC_TRY_RUN([
+__int128 a = 200000000001;
+__int128 b = 400000000005;
+
+int does__int128_work()
+{
+ __int128 c,d;
+
+ c = a * b;
+ d = (c + b) / b;
+ if (d != a+1)
+ return 0;
+ return 1;
+}
+
+main() {
+ exit(! does__int128_work());
+}],
+[pgac_cv_have_gcc__int128=yes],
+[pgac_cv_have_gcc__int128=no],
+[# If cross-compiling, check the size reported by the compiler and
+# trust that the arithmetic works.
+AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [sizeof(__int128) == 16])],
+ pgac_cv_have_gcc__int128=yes,
+ pgac_cv_have_gcc__int128=no)])])
+
+if test x"$pgac_cv_have_gcc__int128" = xyes ; then
+ AC_DEFINE(HAVE_GCC__INT128, 1, [Define to 1 if the system has the type `__int128'.])
+fi])# PGAC_HAVE_GCC__INT128
+
# PGAC_C_FUNCNAME_SUPPORT
# -----------------------
diff --git a/configure b/configure
index 379dab1..f61d980 100755
--- a/configure
+++ b/configure
@@ -13803,6 +13803,77 @@ _ACEOF
fi
+# Check for extension offering the integer scalar type __int128. This is
+# supported for targets which have an integer mode wide enough to hold 128 bits.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128" >&5
+$as_echo_n "checking for __int128... " >&6; }
+if ${pgac_cv_have_gcc__int128+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ # If cross-compiling, check the size reported by the compiler and
+# trust that the arithmetic works.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof(__int128) == 16)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ pgac_cv_have_gcc__int128=yes
+else
+ pgac_cv_have_gcc__int128=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+__int128 a = 200000000001;
+__int128 b = 400000000005;
+
+int does__int128_work()
+{
+ __int128 c,d;
+
+ c = a * b;
+ d = (c + b) / b;
+ if (d != a+1)
+ return 0;
+ return 1;
+}
+
+main() {
+ exit(! does__int128_work());
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ pgac_cv_have_gcc__int128=yes
+else
+ pgac_cv_have_gcc__int128=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_have_gcc__int128" >&5
+$as_echo "$pgac_cv_have_gcc__int128" >&6; }
+
+if test x"$pgac_cv_have_gcc__int128" = xyes ; then
+
+$as_echo "#define HAVE_GCC__INT128 1" >>confdefs.h
+
+fi
+
# Check for various atomic operations now that we have checked how to declare
# 64bit integers.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for builtin __sync char locking functions" >&5
diff --git a/configure.in b/configure.in
index ca29e93..6b1c251 100644
--- a/configure.in
+++ b/configure.in
@@ -1771,6 +1771,10 @@ AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [],
# C, but is missing on some old platforms.
AC_CHECK_TYPES(sig_atomic_t, [], [], [#include <signal.h>])
+# Check for extension offering the integer scalar type __int128. This is
+# supported for targets which have an integer mode wide enough to hold 128 bits.
+PGAC_HAVE_GCC__INT128
+
# Check for various atomic operations now that we have checked how to declare
# 64bit integers.
PGAC_HAVE_GCC__SYNC_CHAR_TAS
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 715917b..b925d29 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -402,7 +402,10 @@ static void apply_typmod(NumericVar *var, int32 typmod);
static int32 numericvar_to_int4(NumericVar *var);
static bool numericvar_to_int8(NumericVar *var, int64 *result);
-static void int8_to_numericvar(int64 val, NumericVar *var);
+static void int64_to_numericvar(int64 val, NumericVar *var);
+#ifdef HAVE_INT128
+static void int128_to_numericvar(int128 val, NumericVar *var);
+#endif
static double numeric_to_double_no_overflow(Numeric num);
static double numericvar_to_double_no_overflow(NumericVar *var);
@@ -1414,7 +1417,7 @@ width_bucket_numeric(PG_FUNCTION_ARGS)
init_var(&count_var);
/* Convert 'count' to a numeric, for ease of use later */
- int8_to_numericvar((int64) count, &count_var);
+ int64_to_numericvar((int64) count, &count_var);
switch (cmp_numerics(bound1, bound2))
{
@@ -2083,14 +2086,14 @@ numeric_fac(PG_FUNCTION_ARGS)
init_var(&fact);
init_var(&result);
- int8_to_numericvar(num, &result);
+ int64_to_numericvar(num, &result);
for (num = num - 1; num > 1; num--)
{
/* this loop can take awhile, so allow it to be interrupted */
CHECK_FOR_INTERRUPTS();
- int8_to_numericvar(num, &fact);
+ int64_to_numericvar(num, &fact);
mul_var(&result, &fact, &result, 0);
}
@@ -2388,7 +2391,7 @@ int4_numeric(PG_FUNCTION_ARGS)
init_var(&result);
- int8_to_numericvar((int64) val, &result);
+ int64_to_numericvar((int64) val, &result);
res = make_result(&result);
@@ -2454,7 +2457,7 @@ int8_numeric(PG_FUNCTION_ARGS)
init_var(&result);
- int8_to_numericvar(val, &result);
+ int64_to_numericvar(val, &result);
res = make_result(&result);
@@ -2498,7 +2501,7 @@ int2_numeric(PG_FUNCTION_ARGS)
init_var(&result);
- int8_to_numericvar((int64) val, &result);
+ int64_to_numericvar((int64) val, &result);
res = make_result(&result);
@@ -2660,6 +2663,9 @@ numeric_float4(PG_FUNCTION_ARGS)
* Actually, it's a pointer to a NumericAggState allocated in the aggregate
* context. The digit buffers for the NumericVars will be there too.
*
+ * On platforms which support 128-bit integers some aggregates instead use a
+ * 128-bit integer based transition datatype to speed up calculations.
+ *
* ----------------------------------------------------------------------
*/
@@ -2920,32 +2926,107 @@ numeric_accum_inv(PG_FUNCTION_ARGS)
/*
- * Integer data types all use Numeric accumulators to share code and
- * avoid risk of overflow. For int2 and int4 inputs, Numeric accumulation
- * is overkill for the N and sum(X) values, but definitely not overkill
- * for the sum(X*X) value. Hence, we use int2_accum and int4_accum only
- * for stddev/variance --- there are faster special-purpose accumulator
- * routines for SUM and AVG of these datatypes.
+ * Integer data types in general use Numeric accumulators to share code
+ * and avoid risk of overflow.
+ *
+ * However for performance reasons optimized special-purpose accumulator
+ * routines are used when possible.
+ *
+ * On platforms with 128-bit integer support, the 128-bit routines will be
+ * used when sum(X) or sum(X*X) fit into 128-bit.
+ *
+ * For int2 and int4 inputs, the N and sum(X) fit into 64-bit so the 64-bit
+ * accumulators will be used for SUM and AVG of these data types.
+ */
+
+#ifdef HAVE_INT128
+typedef struct Int128AggState
+{
+ bool calcSumX2; /* if true, calculate sumX2 */
+ int64 N; /* count of processed numbers */
+ int128 sumX; /* sum of processed numbers */
+ int128 sumX2; /* sum of squares of processed numbers */
+} Int128AggState;
+
+/*
+ * Prepare state data for a 128-bit aggregate function that needs to compute
+ * sum, count and optionally sum of squares of the input.
+ */
+static Int128AggState *
+makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
+{
+ Int128AggState *state;
+ MemoryContext agg_context;
+ MemoryContext old_context;
+
+ if (!AggCheckCallContext(fcinfo, &agg_context))
+ elog(ERROR, "aggregate function called in non-aggregate context");
+
+ old_context = MemoryContextSwitchTo(agg_context);
+
+ state = (Int128AggState *) palloc0(sizeof(Int128AggState));
+ state->calcSumX2 = calcSumX2;
+
+ MemoryContextSwitchTo(old_context);
+
+ return state;
+}
+
+/*
+ * Accumulate a new input value for 128-bit aggregate functions.
+ */
+static void
+do_int128_accum(Int128AggState *state, int128 newval)
+{
+ if (state->calcSumX2)
+ state->sumX2 += newval * newval;
+
+ state->sumX += newval;
+ state->N++;
+}
+
+/*
+ * Remove an input value from the aggregated state.
*/
+static void
+do_int128_discard(Int128AggState *state, int128 newval)
+{
+ if (state->calcSumX2)
+ state->sumX2 -= newval * newval;
+
+ state->sumX -= newval;
+ state->N--;
+}
+
+typedef Int128AggState PolyNumAggState;
+#define makePolyNumAggState makeInt128AggState
+#else
+typedef NumericAggState PolyNumAggState;
+#define makePolyNumAggState makeNumericAggState
+#endif
Datum
int2_accum(PG_FUNCTION_ARGS)
{
- NumericAggState *state;
+ PolyNumAggState *state;
- state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
/* Create the state data on the first call */
if (state == NULL)
- state = makeNumericAggState(fcinfo, true);
+ state = makePolyNumAggState(fcinfo, true);
if (!PG_ARGISNULL(1))
{
+#ifdef HAVE_INT128
+ do_int128_accum(state, (int128) PG_GETARG_INT32(1));
+#else
Numeric newval;
newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric,
PG_GETARG_DATUM(1)));
do_numeric_accum(state, newval);
+#endif
}
PG_RETURN_POINTER(state);
@@ -2954,21 +3035,25 @@ int2_accum(PG_FUNCTION_ARGS)
Datum
int4_accum(PG_FUNCTION_ARGS)
{
- NumericAggState *state;
+ PolyNumAggState *state;
- state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
/* Create the state data on the first call */
if (state == NULL)
- state = makeNumericAggState(fcinfo, true);
+ state = makePolyNumAggState(fcinfo, true);
if (!PG_ARGISNULL(1))
{
+#ifdef HAVE_INT128
+ do_int128_accum(state, (int128) PG_GETARG_INT32(1));
+#else
Numeric newval;
newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
PG_GETARG_DATUM(1)));
do_numeric_accum(state, newval);
+#endif
}
PG_RETURN_POINTER(state);
@@ -3003,21 +3088,25 @@ int8_accum(PG_FUNCTION_ARGS)
Datum
int8_avg_accum(PG_FUNCTION_ARGS)
{
- NumericAggState *state;
+ PolyNumAggState *state;
- state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
/* Create the state data on the first call */
if (state == NULL)
- state = makeNumericAggState(fcinfo, false);
+ state = makePolyNumAggState(fcinfo, false);
if (!PG_ARGISNULL(1))
{
+#ifdef HAVE_INT128
+ do_int128_accum(state, (int128) PG_GETARG_INT64(1));
+#else
Numeric newval;
newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric,
PG_GETARG_DATUM(1)));
do_numeric_accum(state, newval);
+#endif
}
PG_RETURN_POINTER(state);
@@ -3031,9 +3120,9 @@ int8_avg_accum(PG_FUNCTION_ARGS)
Datum
int2_accum_inv(PG_FUNCTION_ARGS)
{
- NumericAggState *state;
+ PolyNumAggState *state;
- state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
/* Should not get here with no state */
if (state == NULL)
@@ -3041,6 +3130,9 @@ int2_accum_inv(PG_FUNCTION_ARGS)
if (!PG_ARGISNULL(1))
{
+#ifdef HAVE_INT128
+ do_int128_discard(state, (int128) PG_GETARG_INT16(1));
+#else
Numeric newval;
newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric,
@@ -3049,6 +3141,7 @@ int2_accum_inv(PG_FUNCTION_ARGS)
/* Should never fail, all inputs have dscale 0 */
if (!do_numeric_discard(state, newval))
elog(ERROR, "do_numeric_discard failed unexpectedly");
+#endif
}
PG_RETURN_POINTER(state);
@@ -3057,9 +3150,9 @@ int2_accum_inv(PG_FUNCTION_ARGS)
Datum
int4_accum_inv(PG_FUNCTION_ARGS)
{
- NumericAggState *state;
+ PolyNumAggState *state;
- state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
/* Should not get here with no state */
if (state == NULL)
@@ -3067,6 +3160,9 @@ int4_accum_inv(PG_FUNCTION_ARGS)
if (!PG_ARGISNULL(1))
{
+#ifdef HAVE_INT128
+ do_int128_discard(state, (int128) PG_GETARG_INT32(1));
+#else
Numeric newval;
newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
@@ -3075,6 +3171,7 @@ int4_accum_inv(PG_FUNCTION_ARGS)
/* Should never fail, all inputs have dscale 0 */
if (!do_numeric_discard(state, newval))
elog(ERROR, "do_numeric_discard failed unexpectedly");
+#endif
}
PG_RETURN_POINTER(state);
@@ -3107,6 +3204,94 @@ int8_accum_inv(PG_FUNCTION_ARGS)
}
Datum
+int8_avg_accum_inv(PG_FUNCTION_ARGS)
+{
+ PolyNumAggState *state;
+
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
+
+ /* Should not get here with no state */
+ if (state == NULL)
+ elog(ERROR, "int8_avg_accum_inv called with NULL state");
+
+ if (!PG_ARGISNULL(1))
+ {
+#ifdef HAVE_INT128
+ do_int128_discard(state, (int128) PG_GETARG_INT64(1));
+#else
+ Numeric newval;
+
+ newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric,
+ PG_GETARG_DATUM(1)));
+
+ /* Should never fail, all inputs have dscale 0 */
+ if (!do_numeric_discard(state, newval))
+ elog(ERROR, "do_numeric_discard failed unexpectedly");
+#endif
+ }
+
+ PG_RETURN_POINTER(state);
+}
+
+Datum
+numeric_poly_sum(PG_FUNCTION_ARGS)
+{
+#ifdef HAVE_INT128
+ PolyNumAggState *state;
+ Numeric res;
+ NumericVar result;
+
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
+
+ /* If there were no non-null inputs, return NULL */
+ if (state == NULL || state->N == 0)
+ PG_RETURN_NULL();
+
+ init_var(&result);
+
+ int128_to_numericvar(state->sumX, &result);
+
+ res = make_result(&result);
+
+ free_var(&result);
+
+ PG_RETURN_NUMERIC(res);
+#else
+ return numeric_sum(fcinfo);
+#endif
+}
+
+Datum
+numeric_poly_avg(PG_FUNCTION_ARGS)
+{
+#ifdef HAVE_INT128
+ PolyNumAggState *state;
+ NumericVar result;
+ Datum countd, sumd;
+
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
+
+ /* If there were no non-null inputs, return NULL */
+ if (state == NULL || state->N == 0)
+ PG_RETURN_NULL();
+
+ init_var(&result);
+
+ int128_to_numericvar(state->sumX, &result);
+
+ countd = DirectFunctionCall1(int8_numeric,
+ Int64GetDatumFast(state->N));
+ sumd = NumericGetDatum(make_result(&result));
+
+ free_var(&result);
+
+ PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
+#else
+ return numeric_avg(fcinfo);
+#endif
+}
+
+Datum
numeric_avg(PG_FUNCTION_ARGS)
{
NumericAggState *state;
@@ -3185,7 +3370,7 @@ numeric_stddev_internal(NumericAggState *state,
init_var(&vsumX);
init_var(&vsumX2);
- int8_to_numericvar(state->N, &vN);
+ int64_to_numericvar(state->N, &vN);
set_var_from_var(&(state->sumX), &vsumX);
set_var_from_var(&(state->sumX2), &vsumX2);
@@ -3308,6 +3493,124 @@ numeric_stddev_pop(PG_FUNCTION_ARGS)
PG_RETURN_NUMERIC(res);
}
+#ifdef HAVE_INT128
+static Numeric
+numeric_poly_stddev_internal(Int128AggState *state,
+ bool variance, bool sample,
+ bool *is_null)
+{
+ NumericAggState numstate;
+ Numeric res;
+
+ init_var(&numstate.sumX);
+ init_var(&numstate.sumX2);
+ numstate.NaNcount = 0;
+ numstate.agg_context = NULL;
+
+ if (state)
+ {
+ numstate.N = state->N;
+ int128_to_numericvar(state->sumX, &numstate.sumX);
+ int128_to_numericvar(state->sumX2, &numstate.sumX2);
+ }
+ else
+ {
+ numstate.N = 0;
+ }
+
+ res = numeric_stddev_internal(&numstate, variance, sample, is_null);
+
+ free_var(&numstate.sumX);
+ free_var(&numstate.sumX2);
+
+ return res;
+}
+#endif
+
+Datum
+numeric_poly_var_samp(PG_FUNCTION_ARGS)
+{
+#ifdef HAVE_INT128
+ PolyNumAggState *state;
+ Numeric res;
+ bool is_null;
+
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
+
+ res = numeric_poly_stddev_internal(state, true, true, &is_null);
+
+ if (is_null)
+ PG_RETURN_NULL();
+ else
+ PG_RETURN_NUMERIC(res);
+#else
+ return numeric_var_samp(fcinfo);
+#endif
+}
+
+Datum
+numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
+{
+#ifdef HAVE_INT128
+ PolyNumAggState *state;
+ Numeric res;
+ bool is_null;
+
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
+
+ res = numeric_poly_stddev_internal(state, false, true, &is_null);
+
+ if (is_null)
+ PG_RETURN_NULL();
+ else
+ PG_RETURN_NUMERIC(res);
+#else
+ return numeric_stddev_samp(fcinfo);
+#endif
+}
+
+Datum
+numeric_poly_var_pop(PG_FUNCTION_ARGS)
+{
+#ifdef HAVE_INT128
+ PolyNumAggState *state;
+ Numeric res;
+ bool is_null;
+
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
+
+ res = numeric_poly_stddev_internal(state, true, false, &is_null);
+
+ if (is_null)
+ PG_RETURN_NULL();
+ else
+ PG_RETURN_NUMERIC(res);
+#else
+ return numeric_var_pop(fcinfo);
+#endif
+}
+
+Datum
+numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
+{
+#ifdef HAVE_INT128
+ PolyNumAggState *state;
+ Numeric res;
+ bool is_null;
+
+ state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
+
+ res = numeric_poly_stddev_internal(state, false, false, &is_null);
+
+ if (is_null)
+ PG_RETURN_NULL();
+ else
+ PG_RETURN_NUMERIC(res);
+#else
+ return numeric_stddev_pop(fcinfo);
+#endif
+}
+
/*
* SUM transition functions for integer datatypes.
*
@@ -4489,14 +4792,14 @@ numericvar_to_int8(NumericVar *var, int64 *result)
* Convert int8 value to numeric.
*/
static void
-int8_to_numericvar(int64 val, NumericVar *var)
+int64_to_numericvar(int64 val, NumericVar *var)
{
uint64 uval,
newuval;
NumericDigit *ptr;
int ndigits;
- /* int8 can require at most 19 decimal digits; add one for safety */
+ /* int64 can require at most 19 decimal digits; add one for safety */
alloc_var(var, 20 / DEC_DIGITS);
if (val < 0)
{
@@ -4530,6 +4833,53 @@ int8_to_numericvar(int64 val, NumericVar *var)
var->weight = ndigits - 1;
}
+#ifdef HAVE_INT128
+/*
+ * Convert 128 bit integer to numeric.
+ */
+static void
+int128_to_numericvar(int128 val, NumericVar *var)
+{
+ uint128 uval,
+ newuval;
+ NumericDigit *ptr;
+ int ndigits;
+
+ /* int128 can require at most 39 decimal digits; add one for safety */
+ alloc_var(var, 40 / DEC_DIGITS);
+ if (val < 0)
+ {
+ var->sign = NUMERIC_NEG;
+ uval = -val;
+ }
+ else
+ {
+ var->sign = NUMERIC_POS;
+ uval = val;
+ }
+ var->dscale = 0;
+ if (val == 0)
+ {
+ var->ndigits = 0;
+ var->weight = 0;
+ return;
+ }
+ ptr = var->digits + var->ndigits;
+ ndigits = 0;
+ do
+ {
+ ptr--;
+ ndigits++;
+ newuval = uval / NBASE;
+ *ptr = uval - newuval * NBASE;
+ uval = newuval;
+ } while (uval);
+ var->digits = ptr;
+ var->ndigits = ndigits;
+ var->weight = ndigits - 1;
+}
+#endif
+
/*
* Convert numeric to float8; if out of range, return +/- HUGE_VAL
*/
diff --git a/src/include/c.h b/src/include/c.h
index a2d4a2c..e98085a 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -293,6 +293,22 @@ typedef unsigned long long int uint64;
#define HAVE_INT64_TIMESTAMP
#endif
+/*
+ * 128-bit signed and unsigned integers
+ * These are lumped together, since they
+ * are used only for aggregate transition
+ * state. snprintf formatting support is
+ * not required. GCC does not even
+ * support __int128 literals, so int128
+ * is likely to remain a very specialized
+ * type.
+ */
+#if defined(HAVE_GCC__INT128)
+#define HAVE_INT128
+typedef __int128 int128;
+typedef unsigned __int128 uint128;
+#endif
+
/* sig_atomic_t is required by ANSI C, but may be missing on old platforms */
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 3e28e2f..b6b6988 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -126,23 +126,23 @@ typedef FormData_pg_aggregate *Form_pg_aggregate;
*/
/* avg */
-DATA(insert ( 2100 n 0 int8_avg_accum numeric_avg int8_avg_accum int8_accum_inv numeric_avg f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2101 n 0 int4_avg_accum int8_avg int4_avg_accum int4_avg_accum_inv int8_avg f f 0 1016 0 1016 0 "{0,0}" "{0,0}" ));
-DATA(insert ( 2102 n 0 int2_avg_accum int8_avg int2_avg_accum int2_avg_accum_inv int8_avg f f 0 1016 0 1016 0 "{0,0}" "{0,0}" ));
-DATA(insert ( 2103 n 0 numeric_avg_accum numeric_avg numeric_avg_accum numeric_accum_inv numeric_avg f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2104 n 0 float4_accum float8_avg - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2105 n 0 float8_accum float8_avg - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2106 n 0 interval_accum interval_avg interval_accum interval_accum_inv interval_avg f f 0 1187 0 1187 0 "{0 second,0 second}" "{0 second,0 second}" ));
+DATA(insert ( 2100 n 0 int8_avg_accum numeric_poly_avg int8_avg_accum int8_avg_accum_inv numeric_poly_avg f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2101 n 0 int4_avg_accum int8_avg int4_avg_accum int4_avg_accum_inv int8_avg f f 0 1016 0 1016 0 "{0,0}" "{0,0}" ));
+DATA(insert ( 2102 n 0 int2_avg_accum int8_avg int2_avg_accum int2_avg_accum_inv int8_avg f f 0 1016 0 1016 0 "{0,0}" "{0,0}" ));
+DATA(insert ( 2103 n 0 numeric_avg_accum numeric_avg numeric_avg_accum numeric_accum_inv numeric_avg f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2104 n 0 float4_accum float8_avg - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2105 n 0 float8_accum float8_avg - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2106 n 0 interval_accum interval_avg interval_accum interval_accum_inv interval_avg f f 0 1187 0 1187 0 "{0 second,0 second}" "{0 second,0 second}" ));
/* sum */
-DATA(insert ( 2107 n 0 int8_avg_accum numeric_sum int8_avg_accum int8_accum_inv numeric_sum f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2108 n 0 int4_sum - int4_avg_accum int4_avg_accum_inv int2int4_sum f f 0 20 0 1016 0 _null_ "{0,0}" ));
-DATA(insert ( 2109 n 0 int2_sum - int2_avg_accum int2_avg_accum_inv int2int4_sum f f 0 20 0 1016 0 _null_ "{0,0}" ));
-DATA(insert ( 2110 n 0 float4pl - - - - f f 0 700 0 0 0 _null_ _null_ ));
-DATA(insert ( 2111 n 0 float8pl - - - - f f 0 701 0 0 0 _null_ _null_ ));
-DATA(insert ( 2112 n 0 cash_pl - cash_pl cash_mi - f f 0 790 0 790 0 _null_ _null_ ));
-DATA(insert ( 2113 n 0 interval_pl - interval_pl interval_mi - f f 0 1186 0 1186 0 _null_ _null_ ));
-DATA(insert ( 2114 n 0 numeric_avg_accum numeric_sum numeric_avg_accum numeric_accum_inv numeric_sum f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2107 n 0 int8_avg_accum numeric_poly_sum int8_avg_accum int8_avg_accum_inv numeric_poly_sum f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2108 n 0 int4_sum - int4_avg_accum int4_avg_accum_inv int2int4_sum f f 0 20 0 1016 0 _null_ "{0,0}" ));
+DATA(insert ( 2109 n 0 int2_sum - int2_avg_accum int2_avg_accum_inv int2int4_sum f f 0 20 0 1016 0 _null_ "{0,0}" ));
+DATA(insert ( 2110 n 0 float4pl - - - - f f 0 700 0 0 0 _null_ _null_ ));
+DATA(insert ( 2111 n 0 float8pl - - - - f f 0 701 0 0 0 _null_ _null_ ));
+DATA(insert ( 2112 n 0 cash_pl - cash_pl cash_mi - f f 0 790 0 790 0 _null_ _null_ ));
+DATA(insert ( 2113 n 0 interval_pl - interval_pl interval_mi - f f 0 1186 0 1186 0 _null_ _null_ ));
+DATA(insert ( 2114 n 0 numeric_avg_accum numeric_sum numeric_avg_accum numeric_accum_inv numeric_sum f f 0 2281 128 2281 128 _null_ _null_ ));
/* max */
DATA(insert ( 2115 n 0 int8larger - - - - f f 413 20 0 0 0 _null_ _null_ ));
@@ -195,52 +195,52 @@ DATA(insert ( 2147 n 0 int8inc_any - int8inc_any int8dec_any - f f 0 2
DATA(insert ( 2803 n 0 int8inc - int8inc int8dec - f f 0 20 0 20 0 "0" "0" ));
/* var_pop */
-DATA(insert ( 2718 n 0 int8_accum numeric_var_pop int8_accum int8_accum_inv numeric_var_pop f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2719 n 0 int4_accum numeric_var_pop int4_accum int4_accum_inv numeric_var_pop f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2720 n 0 int2_accum numeric_var_pop int2_accum int2_accum_inv numeric_var_pop f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2721 n 0 float4_accum float8_var_pop - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2722 n 0 float8_accum float8_var_pop - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2723 n 0 numeric_accum numeric_var_pop numeric_accum numeric_accum_inv numeric_var_pop f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2718 n 0 int8_accum numeric_var_pop int8_accum int8_accum_inv numeric_var_pop f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2719 n 0 int4_accum numeric_poly_var_pop int4_accum int4_accum_inv numeric_poly_var_pop f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2720 n 0 int2_accum numeric_poly_var_pop int2_accum int2_accum_inv numeric_poly_var_pop f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2721 n 0 float4_accum float8_var_pop - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2722 n 0 float8_accum float8_var_pop - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2723 n 0 numeric_accum numeric_var_pop numeric_accum numeric_accum_inv numeric_var_pop f f 0 2281 128 2281 128 _null_ _null_ ));
/* var_samp */
-DATA(insert ( 2641 n 0 int8_accum numeric_var_samp int8_accum int8_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2642 n 0 int4_accum numeric_var_samp int4_accum int4_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2643 n 0 int2_accum numeric_var_samp int2_accum int2_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2644 n 0 float4_accum float8_var_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2645 n 0 float8_accum float8_var_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2646 n 0 numeric_accum numeric_var_samp numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2641 n 0 int8_accum numeric_var_samp int8_accum int8_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2642 n 0 int4_accum numeric_poly_var_samp int4_accum int4_accum_inv numeric_poly_var_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2643 n 0 int2_accum numeric_poly_var_samp int2_accum int2_accum_inv numeric_poly_var_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2644 n 0 float4_accum float8_var_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2645 n 0 float8_accum float8_var_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2646 n 0 numeric_accum numeric_var_samp numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
/* variance: historical Postgres syntax for var_samp */
-DATA(insert ( 2148 n 0 int8_accum numeric_var_samp int8_accum int8_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2149 n 0 int4_accum numeric_var_samp int4_accum int4_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2150 n 0 int2_accum numeric_var_samp int2_accum int2_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2151 n 0 float4_accum float8_var_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2152 n 0 float8_accum float8_var_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2153 n 0 numeric_accum numeric_var_samp numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2148 n 0 int8_accum numeric_var_samp int8_accum int8_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2149 n 0 int4_accum numeric_poly_var_samp int4_accum int4_accum_inv numeric_poly_var_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2150 n 0 int2_accum numeric_poly_var_samp int2_accum int2_accum_inv numeric_poly_var_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2151 n 0 float4_accum float8_var_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2152 n 0 float8_accum float8_var_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2153 n 0 numeric_accum numeric_var_samp numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 128 2281 128 _null_ _null_ ));
/* stddev_pop */
-DATA(insert ( 2724 n 0 int8_accum numeric_stddev_pop int8_accum int8_accum_inv numeric_stddev_pop f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2725 n 0 int4_accum numeric_stddev_pop int4_accum int4_accum_inv numeric_stddev_pop f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2726 n 0 int2_accum numeric_stddev_pop int2_accum int2_accum_inv numeric_stddev_pop f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2727 n 0 float4_accum float8_stddev_pop - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2728 n 0 float8_accum float8_stddev_pop - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2729 n 0 numeric_accum numeric_stddev_pop numeric_accum numeric_accum_inv numeric_stddev_pop f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2724 n 0 int8_accum numeric_stddev_pop int8_accum int8_accum_inv numeric_stddev_pop f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2725 n 0 int4_accum numeric_poly_stddev_pop int4_accum int4_accum_inv numeric_poly_stddev_pop f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2726 n 0 int2_accum numeric_poly_stddev_pop int2_accum int2_accum_inv numeric_poly_stddev_pop f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2727 n 0 float4_accum float8_stddev_pop - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2728 n 0 float8_accum float8_stddev_pop - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2729 n 0 numeric_accum numeric_stddev_pop numeric_accum numeric_accum_inv numeric_stddev_pop f f 0 2281 128 2281 128 _null_ _null_ ));
/* stddev_samp */
-DATA(insert ( 2712 n 0 int8_accum numeric_stddev_samp int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2713 n 0 int4_accum numeric_stddev_samp int4_accum int4_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2714 n 0 int2_accum numeric_stddev_samp int2_accum int2_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2715 n 0 float4_accum float8_stddev_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2716 n 0 float8_accum float8_stddev_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2717 n 0 numeric_accum numeric_stddev_samp numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2712 n 0 int8_accum numeric_stddev_samp int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2713 n 0 int4_accum numeric_poly_stddev_samp int4_accum int4_accum_inv numeric_poly_stddev_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2714 n 0 int2_accum numeric_poly_stddev_samp int2_accum int2_accum_inv numeric_poly_stddev_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2715 n 0 float4_accum float8_stddev_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2716 n 0 float8_accum float8_stddev_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2717 n 0 numeric_accum numeric_stddev_samp numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
/* stddev: historical Postgres syntax for stddev_samp */
-DATA(insert ( 2154 n 0 int8_accum numeric_stddev_samp int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2155 n 0 int4_accum numeric_stddev_samp int4_accum int4_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2156 n 0 int2_accum numeric_stddev_samp int2_accum int2_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
-DATA(insert ( 2157 n 0 float4_accum float8_stddev_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2158 n 0 float8_accum float8_stddev_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
-DATA(insert ( 2159 n 0 numeric_accum numeric_stddev_samp numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2154 n 0 int8_accum numeric_stddev_samp int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
+DATA(insert ( 2155 n 0 int4_accum numeric_poly_stddev_samp int4_accum int4_accum_inv numeric_poly_stddev_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2156 n 0 int2_accum numeric_poly_stddev_samp int2_accum int2_accum_inv numeric_poly_stddev_samp f f 0 2281 48 2281 48 _null_ _null_ ));
+DATA(insert ( 2157 n 0 float4_accum float8_stddev_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2158 n 0 float8_accum float8_stddev_samp - - - f f 0 1022 0 0 0 "{0,0,0}" _null_ ));
+DATA(insert ( 2159 n 0 numeric_accum numeric_stddev_samp numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 128 2281 128 _null_ _null_ ));
/* SQL2003 binary regression aggregates */
DATA(insert ( 2818 n 0 int8inc_float8_float8 - - - - f f 0 20 0 0 0 "0" _null_ ));
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index b8a3660..c0ad48d 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -2495,6 +2495,8 @@ DATA(insert OID = 3568 ( int4_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f f f i
DESCR("aggregate transition function");
DATA(insert OID = 3569 ( int8_accum_inv 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_inv _null_ _null_ _null_ ));
DESCR("aggregate transition function");
+DATA(insert OID = 3387 ( int8_avg_accum_inv 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_inv _null_ _null_ _null_ ));
+DESCR("aggregate transition function");
DATA(insert OID = 3178 ( 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 = 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_ ));
@@ -2513,6 +2515,19 @@ DATA(insert OID = 1841 ( int4_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0
DESCR("aggregate transition function");
DATA(insert OID = 1842 ( int8_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 1700 "1700 20" _null_ _null_ _null_ _null_ int8_sum _null_ _null_ _null_ ));
DESCR("aggregate transition function");
+DATA(insert OID = 3388 ( numeric_poly_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_poly_sum _null_ _null_ _null_ ));
+DESCR("aggregate final function");
+DATA(insert OID = 3389 ( numeric_poly_avg PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_poly_avg _null_ _null_ _null_ ));
+DESCR("aggregate final function");
+DATA(insert OID = 3390 ( numeric_poly_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_poly_var_pop _null_ _null_ _null_ ));
+DESCR("aggregate final function");
+DATA(insert OID = 3391 ( numeric_poly_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_poly_var_samp _null_ _null_ _null_ ));
+DESCR("aggregate final function");
+DATA(insert OID = 3392 ( numeric_poly_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_poly_stddev_pop _null_ _null_ _null_ ));
+DESCR("aggregate final function");
+DATA(insert OID = 3393 ( numeric_poly_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_poly_stddev_samp _null_ _null_ _null_ ));
+DESCR("aggregate final function");
+
DATA(insert OID = 1843 ( interval_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1187 "1187 1186" _null_ _null_ _null_ _null_ interval_accum _null_ _null_ _null_ ));
DESCR("aggregate transition function");
DATA(insert OID = 3549 ( interval_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1187 "1187 1186" _null_ _null_ _null_ _null_ interval_accum_inv _null_ _null_ _null_ ));
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ece57c8..55c1a52 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -183,6 +183,9 @@
*/
#undef HAVE_GCC__ATOMIC_INT64_CAS
+/* Define to 1 if the system has the type `__int128'. */
+#undef HAVE_GCC__INT128
+
/* Define to 1 if you have __sync_lock_test_and_set(char *) and friends. */
#undef HAVE_GCC__SYNC_CHAR_TAS
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index bc4517d..6310641 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -1027,6 +1027,12 @@ extern Datum numeric_var_pop(PG_FUNCTION_ARGS);
extern Datum numeric_var_samp(PG_FUNCTION_ARGS);
extern Datum numeric_stddev_pop(PG_FUNCTION_ARGS);
extern Datum numeric_stddev_samp(PG_FUNCTION_ARGS);
+extern Datum numeric_poly_sum(PG_FUNCTION_ARGS);
+extern Datum numeric_poly_avg(PG_FUNCTION_ARGS);
+extern Datum numeric_poly_var_pop(PG_FUNCTION_ARGS);
+extern Datum numeric_poly_var_samp(PG_FUNCTION_ARGS);
+extern Datum numeric_poly_stddev_pop(PG_FUNCTION_ARGS);
+extern Datum numeric_poly_stddev_samp(PG_FUNCTION_ARGS);
extern Datum int2_sum(PG_FUNCTION_ARGS);
extern Datum int4_sum(PG_FUNCTION_ARGS);
extern Datum int8_sum(PG_FUNCTION_ARGS);
@@ -1034,6 +1040,7 @@ extern Datum int2_avg_accum(PG_FUNCTION_ARGS);
extern Datum int4_avg_accum(PG_FUNCTION_ARGS);
extern Datum int2_avg_accum_inv(PG_FUNCTION_ARGS);
extern Datum int4_avg_accum_inv(PG_FUNCTION_ARGS);
+extern Datum int8_avg_accum_inv(PG_FUNCTION_ARGS);
extern Datum int8_avg(PG_FUNCTION_ARGS);
extern Datum int2int4_sum(PG_FUNCTION_ARGS);
extern Datum width_bucket_numeric(PG_FUNCTION_ARGS);
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers