如何获取 PostgreSQL 中聚合的定义/源代码?

qin*_*gbo 6 sql postgresql ddl aggregate-functions psql

我发现这个相关答案很有用:

CREATE AGGREGATE但是如何在没有 GUI 客户端(例如使用 psql 命令行)的情况下获取语句?

Erw*_*ter 5

生成语句的现代版本CREATE AGGREGATE- 使用format()并转换为对象标识符类型以使其简单,并在需要时自动向标识符添加双引号和模式限定:

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
Run Code Online (Sandbox Code Playgroud)

您可以根据需要对聚合函数的名称进行架构限定:

'public.my_agg_func'::regproc
Run Code Online (Sandbox Code Playgroud)

和/或添加函数参数以在聚合函数重载的情况下消除歧义:

'array_agg(anyarray)'::regprocedure
Run Code Online (Sandbox Code Playgroud)

这不包括特殊情况,例如移动聚合函数等。可以轻松扩展以涵盖当前 Postgres 版本的所有选项。但下一个主要版本可能会带来新的选择。

pg_get_aggregatedef()与现有功能类似的功能pg_get_functiondef()将很好地消除对这个自定义查询的需要 - 这可能必须适应每个新的主要 Postgres 版本......


小智 3

像这样的东西,但我不确定这是否涵盖了创建聚合的所有可能方法(它绝对没有考虑到引用标识符的需要)

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  
Run Code Online (Sandbox Code Playgroud)