如何在PostgreSQL中获取聚合的定义/源代码?
我发现这个相关的答案很有用:如何在PostgreSQL中获取聚合的定义/源代码?,sql,postgresql,aggregate-functions,psql,ddl,Sql,Postgresql,Aggregate Functions,Psql,Ddl,我发现这个相关的答案很有用: 但是,如果没有GUI客户端(例如,使用psql命令行),我如何获得CREATE AGGRATE语句呢?类似的内容,但我不确定这是否涵盖了创建聚合的所有可能方法,它肯定没有考虑引用标识符的需要 SELECT 'create aggregate '||n.nspname||'.'||p.proname||'('||format_type(a.aggtranstype, null)||') (sfunc = '||a.aggtransfn ||', styp
但是,如果没有GUI客户端(例如,使用psql命令行),我如何获得CREATE AGGRATE语句呢?类似的内容,但我不确定这是否涵盖了创建聚合的所有可能方法,它肯定没有考虑引用标识符的需要
SELECT 'create aggregate '||n.nspname||'.'||p.proname||'('||format_type(a.aggtranstype, null)||') (sfunc = '||a.aggtransfn
||', stype = '||format_type(a.aggtranstype, null)
||case when op.oprname is null then '' else ', sortop = '||op.oprname end
||case when a.agginitval is null then '' else ', initcond = '||a.agginitval end
||')' as source
FROM pg_proc p
JOIN pg_namespace n ON p.pronamespace = n.oid
JOIN pg_aggregate a ON a.aggfnoid = p.oid
LEFT JOIN pg_operator op ON op.oid = a.aggsortop
where p.proname = 'your_aggregate'
and n.nspname = 'public' --- replace with your schema name
我的版本使用了一些系统功能
生成CREATE AGGRATE语句的现代版本-使用格式转换和对象标识符类型转换使其简单,并在需要时自动向标识符添加双引号和模式限定:
SELECT format('CREATE AGGREGATE %s (SFUNC = %s, STYPE = %s%s%s%s%s)'
, aggfnoid::regprocedure
, aggtransfn
, aggtranstype::regtype
, ', SORTOP = ' || NULLIF(aggsortop, 0)::regoper
, ', INITCOND = ' || agginitval
, ', FINALFUNC = ' || NULLIF(aggfinalfn, 0)
, CASE WHEN aggfinalextra THEN ', FINALFUNC_EXTRA' END
-- add more to cover special cases like moving-aggregate etc.
) AS ddl_agg
FROM pg_aggregate
WHERE aggfnoid = 'my_agg_func'::regproc; -- name of agg func here
您可以根据需要对聚合函数的名称进行模式限定:“public.my_agg_func”::regproc。
和/或添加函数参数以消除重载聚合函数时的歧义:“array_agganyarray”::regprocedure
这不包括特殊情况,如移动聚合函数等。可以轻松扩展,以涵盖当前Postgres版本的所有选项。但下一个主要版本可能会带来新的选择
与现有函数类似的函数pg_get_aggregatedef将非常有助于消除对该自定义查询的需求-这可能必须适应每个新的主要Postgres版本…良好的开端,但参数应该类似于unnestp.proargtypes::oid[]中的SELECT string_aggreat_typet,null,,”t-see-还要注意,在PostgreSQL 9.4+中有更多自定义聚合函数的选项和类型。谢谢大家。我想可能会有类似于pg_get_functiondef的东西,但看起来不是。对于这一点,也存在一些问题。或者更优雅一些:aggfnoid::regprocedure。我添加了一个更新版本。
SELECT format('CREATE AGGREGATE %s (SFUNC = %s, STYPE = %s%s%s%s%s)'
, aggfnoid::regprocedure
, aggtransfn
, aggtranstype::regtype
, ', SORTOP = ' || NULLIF(aggsortop, 0)::regoper
, ', INITCOND = ' || agginitval
, ', FINALFUNC = ' || NULLIF(aggfinalfn, 0)
, CASE WHEN aggfinalextra THEN ', FINALFUNC_EXTRA' END
-- add more to cover special cases like moving-aggregate etc.
) AS ddl_agg
FROM pg_aggregate
WHERE aggfnoid = 'my_agg_func'::regproc; -- name of agg func here