2013-11-26 2 views
1

PostgreSQL 스키마의 모든 함수를 나열하고 함수의 모든 인수에 대해 사람이 읽을 수있는 형식이 필요합니다. 형태 a의 OID는 배열로서 나타내진다. proallargtypes. 배열을 unnest하고 format_type()을 적용하면 쿼리가 단일 함수의 여러 행으로 분할됩니다. 이를 피하기 위해, 외부의 SELECT에서 GROUP까지 다시 argtypes를 만들어야한다는 것을 피하기 위해, apperently, 하나는 중첩되지 않은 배열을 그룹화 할 수 없기 때문입니다. 모든 열은 proname에 따라 다르지만 불필요하지만 proname is not a primary key 인 모든 열을 GROUP BY 절에 나열해야합니다.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) 

이제 빌드 "지도"기능이 없습니다. 그래서 불길한, 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()는 함수가 아니며 "subselect가있는 배열 생성자"입니다. 구문은 동일하지만 의미가 조금 다릅니다 :) –

관련 문제