mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Create AVG() aggregates for int8 and NUMERIC which do not compute X^2,
as a performance enhancement. Mark Kirkwood
This commit is contained in:
parent
72a070a365
commit
89a624439e
@ -14,7 +14,7 @@
|
|||||||
* Copyright (c) 1998-2007, PostgreSQL Global Development Group
|
* Copyright (c) 1998-2007, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.99 2007/01/16 21:41:13 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.100 2007/02/17 00:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2165,6 +2165,40 @@ do_numeric_accum(ArrayType *transarray, Numeric newval)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Improve avg performance by not caclulating sum(X*X).
|
||||||
|
*/
|
||||||
|
static ArrayType *
|
||||||
|
do_numeric_avg_accum(ArrayType *transarray, 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');
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
numeric_accum(PG_FUNCTION_ARGS)
|
numeric_accum(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@ -2174,6 +2208,18 @@ numeric_accum(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
|
PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Optimized case for average of numeric.
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
numeric_avg_accum(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
|
Numeric newval = PG_GETARG_NUMERIC(1);
|
||||||
|
|
||||||
|
PG_RETURN_ARRAYTYPE_P(do_numeric_avg_accum(transarray, newval));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Integer data types all use Numeric accumulators to share code and
|
* Integer data types all use Numeric accumulators to share code and
|
||||||
* avoid risk of overflow. For int2 and int4 inputs, Numeric accumulation
|
* avoid risk of overflow. For int2 and int4 inputs, Numeric accumulation
|
||||||
@ -2219,6 +2265,22 @@ int8_accum(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
|
PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Optimized case for average of int8.
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
int8_avg_accum(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
|
Datum newval8 = PG_GETARG_DATUM(1);
|
||||||
|
Numeric newval;
|
||||||
|
|
||||||
|
newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8));
|
||||||
|
|
||||||
|
PG_RETURN_ARRAYTYPE_P(do_numeric_avg_accum(transarray, newval));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
numeric_avg(PG_FUNCTION_ARGS)
|
numeric_avg(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@ -2232,11 +2294,10 @@ numeric_avg(PG_FUNCTION_ARGS)
|
|||||||
deconstruct_array(transarray,
|
deconstruct_array(transarray,
|
||||||
NUMERICOID, -1, false, 'i',
|
NUMERICOID, -1, false, 'i',
|
||||||
&transdatums, NULL, &ndatums);
|
&transdatums, NULL, &ndatums);
|
||||||
if (ndatums != 3)
|
if (ndatums != 2)
|
||||||
elog(ERROR, "expected 3-element numeric array");
|
elog(ERROR, "expected 2-element numeric array");
|
||||||
N = DatumGetNumeric(transdatums[0]);
|
N = DatumGetNumeric(transdatums[0]);
|
||||||
sumX = DatumGetNumeric(transdatums[1]);
|
sumX = DatumGetNumeric(transdatums[1]);
|
||||||
/* ignore sumX2 */
|
|
||||||
|
|
||||||
/* SQL92 defines AVG of no values to be NULL */
|
/* SQL92 defines AVG of no values to be NULL */
|
||||||
/* N is zero iff no digits (cf. numeric_uminus) */
|
/* N is zero iff no digits (cf. numeric_uminus) */
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.385 2007/02/16 07:46:55 petere Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.386 2007/02/17 00:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200702161
|
#define CATALOG_VERSION_NO 200702162
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_aggregate.h,v 1.60 2007/01/20 09:27:19 petere Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_aggregate.h,v 1.61 2007/02/17 00:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -80,10 +80,10 @@ typedef FormData_pg_aggregate *Form_pg_aggregate;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* avg */
|
/* avg */
|
||||||
DATA(insert ( 2100 int8_accum numeric_avg 0 1231 "{0,0,0}" ));
|
DATA(insert ( 2100 int8_avg_accum numeric_avg 0 1231 "{0,0}" ));
|
||||||
DATA(insert ( 2101 int4_avg_accum int8_avg 0 1016 "{0,0}" ));
|
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 ( 2102 int2_avg_accum int8_avg 0 1016 "{0,0}" ));
|
||||||
DATA(insert ( 2103 numeric_accum numeric_avg 0 1231 "{0,0,0}" ));
|
DATA(insert ( 2103 numeric_avg_accum numeric_avg 0 1231 "{0,0}" ));
|
||||||
DATA(insert ( 2104 float4_accum float8_avg 0 1022 "{0,0,0}" ));
|
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 ( 2105 float8_accum float8_avg 0 1022 "{0,0,0}" ));
|
||||||
DATA(insert ( 2106 interval_accum interval_avg 0 1187 "{0 second,0 second}" ));
|
DATA(insert ( 2106 interval_accum interval_avg 0 1187 "{0 second,0 second}" ));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.444 2007/02/16 07:46:55 petere Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.445 2007/02/17 00:55:57 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -2744,12 +2744,16 @@ DATA(insert OID = 1832 ( float8_stddev_samp PGNSP PGUID 12 1 0 f f t f i 1 701
|
|||||||
DESCR("STDDEV_SAMP aggregate final function");
|
DESCR("STDDEV_SAMP aggregate final function");
|
||||||
DATA(insert OID = 1833 ( numeric_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 1700" _null_ _null_ _null_ numeric_accum - _null_ ));
|
DATA(insert OID = 1833 ( numeric_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 1700" _null_ _null_ _null_ numeric_accum - _null_ ));
|
||||||
DESCR("aggregate transition function");
|
DESCR("aggregate transition function");
|
||||||
|
DATA(insert OID = 2858 ( numeric_avg_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 1700" _null_ _null_ _null_ numeric_avg_accum - _null_ ));
|
||||||
|
DESCR("aggregate transition function");
|
||||||
DATA(insert OID = 1834 ( int2_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 21" _null_ _null_ _null_ int2_accum - _null_ ));
|
DATA(insert OID = 1834 ( int2_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 21" _null_ _null_ _null_ int2_accum - _null_ ));
|
||||||
DESCR("aggregate transition function");
|
DESCR("aggregate transition function");
|
||||||
DATA(insert OID = 1835 ( int4_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 23" _null_ _null_ _null_ int4_accum - _null_ ));
|
DATA(insert OID = 1835 ( int4_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 23" _null_ _null_ _null_ int4_accum - _null_ ));
|
||||||
DESCR("aggregate transition function");
|
DESCR("aggregate transition function");
|
||||||
DATA(insert OID = 1836 ( int8_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 20" _null_ _null_ _null_ int8_accum - _null_ ));
|
DATA(insert OID = 1836 ( int8_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 20" _null_ _null_ _null_ int8_accum - _null_ ));
|
||||||
DESCR("aggregate transition function");
|
DESCR("aggregate transition function");
|
||||||
|
DATA(insert OID = 2746 ( int8_avg_accum PGNSP PGUID 12 1 0 f f t f i 2 1231 "1231 20" _null_ _null_ _null_ int8_avg_accum - _null_ ));
|
||||||
|
DESCR("aggregate transition function");
|
||||||
DATA(insert OID = 1837 ( numeric_avg PGNSP PGUID 12 1 0 f f t f i 1 1700 "1231" _null_ _null_ _null_ numeric_avg - _null_ ));
|
DATA(insert OID = 1837 ( numeric_avg PGNSP PGUID 12 1 0 f f t f i 1 1700 "1231" _null_ _null_ _null_ numeric_avg - _null_ ));
|
||||||
DESCR("AVG aggregate final function");
|
DESCR("AVG aggregate final function");
|
||||||
DATA(insert OID = 2514 ( numeric_var_pop PGNSP PGUID 12 1 0 f f t f i 1 1700 "1231" _null_ _null_ _null_ numeric_var_pop - _null_ ));
|
DATA(insert OID = 2514 ( numeric_var_pop PGNSP PGUID 12 1 0 f f t f i 1 1700 "1231" _null_ _null_ _null_ numeric_var_pop - _null_ ));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.287 2007/01/28 16:16:54 neilc Exp $
|
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.288 2007/02/17 00:55:58 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -841,9 +841,11 @@ extern Datum numeric_float4(PG_FUNCTION_ARGS);
|
|||||||
extern Datum text_numeric(PG_FUNCTION_ARGS);
|
extern Datum text_numeric(PG_FUNCTION_ARGS);
|
||||||
extern Datum numeric_text(PG_FUNCTION_ARGS);
|
extern Datum numeric_text(PG_FUNCTION_ARGS);
|
||||||
extern Datum numeric_accum(PG_FUNCTION_ARGS);
|
extern Datum numeric_accum(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum numeric_avg_accum(PG_FUNCTION_ARGS);
|
||||||
extern Datum int2_accum(PG_FUNCTION_ARGS);
|
extern Datum int2_accum(PG_FUNCTION_ARGS);
|
||||||
extern Datum int4_accum(PG_FUNCTION_ARGS);
|
extern Datum int4_accum(PG_FUNCTION_ARGS);
|
||||||
extern Datum int8_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_avg(PG_FUNCTION_ARGS);
|
||||||
extern Datum numeric_var_pop(PG_FUNCTION_ARGS);
|
extern Datum numeric_var_pop(PG_FUNCTION_ARGS);
|
||||||
extern Datum numeric_var_samp(PG_FUNCTION_ARGS);
|
extern Datum numeric_var_samp(PG_FUNCTION_ARGS);
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
--
|
--
|
||||||
-- all functions CREATEd
|
-- all functions CREATEd
|
||||||
CREATE AGGREGATE newavg (
|
CREATE AGGREGATE newavg (
|
||||||
sfunc = int4_accum, basetype = int4, stype = _numeric,
|
sfunc = int4_avg_accum, basetype = int4, stype = _int8,
|
||||||
finalfunc = numeric_avg,
|
finalfunc = int8_avg,
|
||||||
initcond1 = '{0,0,0}'
|
initcond1 = '{0,0}'
|
||||||
);
|
);
|
||||||
-- test comments
|
-- test comments
|
||||||
COMMENT ON AGGREGATE newavg_wrong (int4) IS 'an agg comment';
|
COMMENT ON AGGREGATE newavg_wrong (int4) IS 'an agg comment';
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
-- all functions CREATEd
|
-- all functions CREATEd
|
||||||
CREATE AGGREGATE newavg (
|
CREATE AGGREGATE newavg (
|
||||||
sfunc = int4_accum, basetype = int4, stype = _numeric,
|
sfunc = int4_avg_accum, basetype = int4, stype = _int8,
|
||||||
finalfunc = numeric_avg,
|
finalfunc = int8_avg,
|
||||||
initcond1 = '{0,0,0}'
|
initcond1 = '{0,0}'
|
||||||
);
|
);
|
||||||
|
|
||||||
-- test comments
|
-- test comments
|
||||||
|
Loading…
x
Reference in New Issue
Block a user