2013-11-26 5 views
1

Я перечисляю все функции схемы PostgreSQL и нуждаюсь в человеческих читаемых типах для каждого аргумента функций. OID типов a, представленных в виде массива в proallargtypes. Я могу отключить массив и применить к нему format_type(), что заставляет запрос разбиваться на несколько строк для одной функции. Чтобы этого избежать, мне нужно создать внешний SELECT до GROUP аргументов снова, потому что, по-видимому, нельзя группировать неустановленный массив. Все столбцы зависят от пронума, но я должен перечислить все столбцы в разделе 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) 

Теперь нет функции построения «карты». Поэтому unsest, 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: just note - ARRAY() не является функцией - это «конструктор массива с подзапросом». Синтаксис такой же, но семантика немного отличается :) –

Смежные вопросы