How to get definition/source code of an aggregate in PostgreSQL?

[亡魂溺海] 提交于 2020-01-13 11:32:11

问题


I found this related answer useful:

  • Export "Create Aggregate" functions from PostgreSQL

But how do I get the CREATE AGGREGATE statement without a GUI client (e.g. with psql command line)?


回答1:


Something like this, but I'm not sure if this covers all possible ways of creating an aggregate (it definitely does not take the need for quoted identifiers into account)

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  



回答2:


A modern version to generate the CREATE AGGREGATE statement - using format() and casts to object identifier types to make it simple and add double-quotes and schema-qualification to identifiers where required automatically:

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

You can schema-qualify the aggregate function's name where necessary: 'public.my_agg_func'::regproc.
And / or add function parameters to disambiguate in case of overloaded aggregate functions: 'array_agg(anyarray)'::regprocedure.

This does not cover special cases like moving-aggregate functions etc. Can easily be extended to cover all options for your current Postgres version. But the next major version may bring new options.

A function pg_get_aggregatedef() similar to the existing pg_get_functiondef() would be great to eliminate the need for this custom query - which may have to be adapted with every new major Postgres version ...




回答3:


My version using some system functions

SELECT 
format(
   E'CREATE AGGREGATE %s (\n%s\n);'
   , (pg_identify_object('pg_proc'::regclass, aggfnoid, 0)).identity
   , array_to_string(
      ARRAY[
     format(E'\tSFUNC = %s', aggtransfn::regproc)
     , format(E'\tSTYPE = %s', format_type(aggtranstype, NULL))
     , CASE aggfinalfn WHEN '-'::regproc THEN NULL ELSE format(E'\tFINALFUNC = %s',aggfinalfn::text) END
     , CASE aggsortop WHEN 0 THEN NULL ELSE format(E'\tSORTOP = %s', oprname) END
     , CASE WHEN agginitval IS NULL THEN NULL ELSE format(E'\tINITCOND = %s', agginitval) END
      ]
      , E',\n'
   )
)

FROM pg_aggregate
LEFT JOIN pg_operator ON pg_operator.oid = aggsortop
WHERE aggfnoid = 'regr_r2'::regproc;


来源:https://stackoverflow.com/questions/27899642/how-to-get-definition-source-code-of-an-aggregate-in-postgresql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!