psql コマンドで関数ソースコード取得方法
PgAdmin3 あるいは PgAdmin4 等の GUI ツールを使っていると難なく PL/PgSQL 関数の ソースコードを取得することが出来ますが、いざ psql コマンド上で関数のソースコードを取得しようとすると方法が分かりませんでしたが、最終的に完全な形で関数のソースコードを取得する方法を見つけましたので解説します。まずソースコードを取得したい関数を探します。
ここでは情報スキーマ(information_schema)内にある下記関数のソースコードを取得してみます。もちろんご自身で作成したソースコードに置き換えても 同じことが出来ます。
=> \df information_schema._pg_char_max_length;
List of functions
--------------------+---------------------+------------------+---------------------------+--------
Schema | Name | Result data type | Argument data types | Type
--------------------+---------------------+------------------+---------------------------+--------
information_schema | _pg_char_max_length | integer | typid oid, typmod integer | normal
--------------------+---------------------+------------------+---------------------------+--------
(1 row)
上記 "_pg_char_max_length" という関数のソースコードを取得するつもりで、"pg_catalog.pg_proc" というテーブルを以下のように検索してみました。確かに内容は取得できますが、"CREATE FUNCTION" あるいは "CREATE OR REPLACE FUNCTION" が無かったり引数情報がなく、そのままでは利用できません。
=> SELECT proname, prosrc FROM pg_proc WHERE proname = '_pg_char_max_length';
---------------------+----------------------------------------------------
proname | prosrc
---------------------+----------------------------------------------------
_pg_char_max_length | SELECT +
| CASE WHEN $2 = -1 /* default typmod */ +
| THEN null +
| WHEN $1 IN (1042, 1043) /* char, varchar */+
| THEN $2 - 4 +
| WHEN $1 IN (1560, 1562) /* bit, varbit */ +
| THEN $2 +
| ELSE null +
| END
---------------------+----------------------------------------------------
(1 row)
そこで色々調べた結果、pg_get_functiondef という関数を見つけました。早速以下のように 実行してみると、見事に関数のソースコードが完全な形で取得できました。
=> SELECT pg_get_functiondef((SELECT oid FROM pg_proc WHERE proname = '_pg_char_max_length'));
----------------------------------------------------------------------------------------------
pg_get_functiondef
----------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION information_schema._pg_char_max_length(typid oid, typmod integer)+
RETURNS integer +
LANGUAGE sql +
IMMUTABLE STRICT +
AS $function$SELECT +
CASE WHEN $2 = -1 /* default typmod */ +
THEN null +
WHEN $1 IN (1042, 1043) /* char, varchar */ +
THEN $2 - 4 +
WHEN $1 IN (1560, 1562) /* bit, varbit */ +
THEN $2 +
ELSE null +
END$function$ +
----------------------------------------------------------------------------------------------
(1 row)
