2013-11-26 50 views
1

我列出了PostgreSQL模式的所有函数,并且需要用于函数的每个参数的人类可读类型。在proallargtypes中表示为数组的类型的OID。我可以取消数组并将format_type()应用于它,这会导致查询分裂为单个函数的多行。为了避免这种情况,我必须再次创建外部SELECTGROUP这个argtypes,因为,显然,不能将一个未配置的数组分组。所有列都依赖于proname,但我必须列出GROUP BY子句中的所有列,这是不必要的,但是代替is not a primary key将函数应用于SELECT语句中数组的每个元素

有没有更好的方式来实现我的这样一个输出的目标:

proname | ... | protypes 
------------------------------------- 
test | ... | {integer,integer} 
我目前使用此查询

SELECT 
      proname, 
      prosrc, 
      pronargs, 
      proargmodes, 
      array_agg(proargtypes), -- see here 
      proallargtypes, 
      proargnames, 
      prodefaults, 
      prorettype, 
      lanname 
FROM (
     SELECT 
      p.proname, 
      p.prosrc, 
      p.pronargs, 
      p.proargmodes, 
      format_type(unnest(p.proallargtypes), NULL) AS proargtypes, -- and here 
      p.proallargtypes, 
      p.proargnames, 
      pg_get_expr(p.proargdefaults, 0) AS prodefaults, 
      format_type(p.prorettype, NULL) AS prorettype, 
      l.lanname 
     FROM pg_catalog.pg_proc p 
     JOIN pg_catalog.pg_language l 
     ON l.oid = p.prolang 
     JOIN pg_catalog.pg_namespace n 
     ON n.oid = p.pronamespace 
     WHERE n.nspname = 'public' 
) x 
GROUP BY proname, prosrc, pronargs, proargmodes, proallargtypes, proargnames, prodefaults, prorettype, lanname 

回答

4

可以使用内部的“无证”功能pg_catalog。 pg_get_function_arguments(p.oid)。

postgres=# SELECT pg_catalog.pg_get_function_arguments('fufu'::regproc); 
pg_get_function_arguments 
--------------------------- 
a integer, b integer 
(1 row) 

现在,没有构建“地图”功能。如此unnest,array_agg只有一种可能。您可以简化生活与自己的自定义功能:

CREATE OR REPLACE FUNCTION format_types(oid[]) 
RETURNS text[] AS $$ 
    SELECT ARRAY(SELECT format_type(unnest($1), null)) 
$$ LANGUAGE sql IMMUTABLE; 

,并导致

postgres=# SELECT format_types('{21,22,23}'); 
      format_types   
------------------------------- 
{smallint,int2vector,integer} 
(1 row) 

然后你的查询应该是:

SELECT proname, format_types(proallargtypes) 
    FROM pg_proc 
    WHERE pronamespace = 2200 AND proallargtypes; 

但结果不会被人或许期望,因为是proallargtypes场只有在使用OUT参数时才是空的。通常是空的。你应该看看proargtypes字段,但它是一个oidvector类型 - 所以你应该首先转换为oid []。

postgres=# SELECT proname, format_types(string_to_array(proargtypes::text,' ')::oid[]) 
       FROM pg_proc 
      WHERE pronamespace = 2200 
      LIMIT 10; 
      proname   |     format_types      
------------------------------+---------------------------------------------------- 
quantile_append_double  | {internal,"double precision","double precision"} 
quantile_append_double_array | {internal,"double precision","double precision[]"} 
quantile_double    | {internal} 
quantile_double_array  | {internal} 
quantile      | {"double precision","double precision"} 
quantile      | {"double precision","double precision[]"} 
quantile_cont_double   | {internal} 
quantile_cont_double_array | {internal} 
quantile_cont    | {"double precision","double precision"} 
quantile_cont    | {"double precision","double precision[]"} 
(10 rows) 
+0

谢谢!我会测试并回到你身边。可悲的是,我无法创建自己的函数,因为我正在编写一个数据库独立工具,它可以列出函数。尽管阅读访问。 – AmShaegar

+0

太棒了,我意识到OUT参数的问题。我需要解决的所有问题是自定义函数的ARRAY()函数。非常感谢你! – AmShaegar

+1

@AmShaegar:注意 - ARRAY()不是函数 - 它是一个“带有子选择的数组构造函数”。语法是一样的,但语义有点不同:) –

相关问题