在SELECT语句中将函数应用于数组的每个元素

时间:2013-11-26 17:10:36

标签: arrays postgresql select

我列出了PostgreSQL架构的所有函数,并且需要为函数的每个参数提供人类可读的类型。在proallargtypes中表示为数组的类型的OID。我可以删除数组并将format_type()应用于它,这会导致查询分成多个行以用于单个函数。为了避免这种情况,我必须再次创建一个外部的SELECTGROUP argtypes,因为,显然,人们不能对一个unnested数组进行分组。所有列都依赖于proname,但我必须列出GROUP BY子句中的所有列,这是不必要的但是代号为is not a primary key

有没有更好的方法来实现我的输出目标:

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

1 个答案:

答案 0 :(得分:6)

你可以使用内部的“未记录的”函数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)

现在,没有构建“map”功能。所以不需要,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)