我对 stddev_pop() 函数的实现或代码感兴趣。我理解它的作用,我知道文档中有定义,但我对代码本身感兴趣。 我试图在 pgAdmin 的公共模式/函数和聚合中找到它,但它不在那里。我也尝试过这个查询:
SELECT *
FROM pg_proc
WHERE proname = 'stddev_pop';
这给了我 6 个不同的结果。但是当我尝试使用函数的 oid 进行查询时,会发生以下情况:
SELECT pg_get_functiondef(2724);
ERROR: "stddev_pop" is an aggregate function
SQL state: 42809
也在 psql 中我尝试过:
isa=# \df stddev_pop
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+------------+------------------+---------------------+------
pg_catalog | stddev_pop | numeric | bigint | agg
pg_catalog | stddev_pop | double precision | double precision | agg
pg_catalog | stddev_pop | numeric | integer | agg
pg_catalog | stddev_pop | numeric | numeric | agg
pg_catalog | stddev_pop | double precision | real | agg
pg_catalog | stddev_pop | numeric | smallint | agg
(6 rows)
但无法更进一步。
如何“查看”聚合函数?
您要查询
pg_aggregate
目录:
SELECT a.aggfnoid::regprocedure AS aggregate,
a.agginitval AS initial_value,
a.aggtransfn::regprocedure AS state_transition_function,
a.aggfinalfn::regprocedure AS final_function
FROM pg_aggregate AS a
JOIN pg_proc AS p
ON a.aggfnoid = p.oid
WHERE p.prokind = 'a'
AND p.proname = 'stddev_pop';
aggregate │ initial_value │ state_transition_function │ final_function
══════════════════════════════╪═══════════════╪═══════════════════════════════════════════════════╪═══════════════════════════════════════
stddev_pop(bigint) │ ∅ │ int8_accum(internal,bigint) │ numeric_stddev_pop(internal)
stddev_pop(integer) │ ∅ │ int4_accum(internal,integer) │ numeric_poly_stddev_pop(internal)
stddev_pop(smallint) │ ∅ │ int2_accum(internal,smallint) │ numeric_poly_stddev_pop(internal)
stddev_pop(real) │ {0,0,0} │ float4_accum(double precision[],real) │ float8_stddev_pop(double precision[])
stddev_pop(double precision) │ {0,0,0} │ float8_accum(double precision[],double precision) │ float8_stddev_pop(double precision[])
stddev_pop(numeric) │ ∅ │ numeric_accum(internal,numeric) │ numeric_stddev_pop(internal)
(6 rows)
这是一个内置的聚合函数。您将在 postgres 代码库中找到实现。
Datum
float8_stddev_pop(PG_FUNCTION_ARGS)
{
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
float8 *transvalues;
float8 N,
Sxx;
transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
N = transvalues[0];
/* ignore Sx */
Sxx = transvalues[2];
/* Population stddev is undefined when N is 0, so return NULL */
if (N == 0.0)
PG_RETURN_NULL();
/* Note that Sxx is guaranteed to be non-negative */
PG_RETURN_FLOAT8(sqrt(Sxx / N));
}