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)