2013-11-26 51 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()不是函數 - 它是一個「帶有子選擇的數組構造函數」。語法是一樣的,但語義有點不同:) –

相關問題