はじめに
にゃーん。趣味でポスグレをやっている者だ。
とある事情で、表題にあるように、PostgreSQLの拡張機能(EXTENSION)に含まれる関数が、どの言語で実装されているかを調べることになった。
SQL例
以下のようなSQLを実行することで、指定したEXTENSIONに含まれるSQL関数が、どの言語(C, SQL, PL/pgSQL)で実装されているかを調べられる。
--
-- EXTENSIONに含まれる関数が何の言語で実装されているか表示する
-- (PostgreSQL 9.1以降)
--
SELECT t.objid, p.proname, l.lanname FROM
(
SELECT objid, pg_identify_object_as_address(classid, objid, 0) r
FROM pg_catalog.pg_depend
WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND
refobjid = (SELECT oid FROM pg_extension WHERE extname = 'pg_fraction') AND
deptype = 'e'
ORDER BY 1
) t JOIN pg_proc p ON (t.objid = p.oid)
JOIN pg_language l ON (p.prolang = l.oid)
WHERE (r).type = 'function';
上記の例だと、pg_fractionという拡張(これは自分が学習用につくった分数型EXTENSION)に含まれるSQL関数名とそれを実装した言語を表示する。
実行例はこんな感じ。
--
-- EXTENSIONに含まれる関数が何の言語で実装されているか表示する
-- (PostgreSQL 9.1以降)
--
SELECT t.objid, p.proname, l.lanname FROM
(
SELECT objid, pg_identify_object_as_address(classid, objid, 0) r
FROM pg_catalog.pg_depend
WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND
refobjid = (SELECT oid FROM pg_extension WHERE extname = 'pg_fraction') AND
deptype = 'e'
ORDER BY 1
) t JOIN pg_proc p ON (t.objid = p.oid)
JOIN pg_language l ON (p.prolang = l.oid)
WHERE (r).type = 'function';
objid | proname | lanname
-------+--------------------+---------
16401 | fraction_in | c
16402 | fraction_out | c
16404 | get_value | c
16405 | fraction_add | c
16407 | fraction_sub | c
16409 | fraction_mul | c
16411 | fraction_div | c
16413 | fraction_max | c
16415 | fraction_min | c
16417 | fraction_to_float8 | c
16419 | int32_to_fraction | c
16421 | fraction_eq | c
16423 | fraction_ne | c
16425 | fraction_lt | c
16427 | fraction_gt | c
16429 | fraction_le | c
16431 | fraction_ge | c
16433 | fraction_cmp | c
(18 rows)
もう一つの例として、SQLのみで作成されたEXTENSIONの例を示す。このEXTENSIONは、PostgreSQL文書の拡張の例に記載されていた、pairというデータ型拡張である。データ型を実装するためには、結局のところSQL関数を実装する必要がある。
で、このSQL関数はSQLで作成されているので、実行するとこんな感じになる。
testdb=# SELECT t.objid, p.proname, l.lanname FROM
(
SELECT objid, pg_identify_object_as_address(classid, objid, 0) r
FROM pg_catalog.pg_depend
WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND
refobjid = (SELECT oid FROM pg_extension WHERE extname = 'pair') AND
deptype = 'e'
ORDER BY 1
) t JOIN pg_proc p ON (t.objid = p.oid)
JOIN pg_language l ON (p.prolang = l.oid)
WHERE (r).type = 'function';
objid | proname | lanname
-------+-------------+---------
16389 | pair | sql
16391 | lower | sql
16392 | pair_concat | sql
(3 rows)
testdb=#
本当はこれをPREPARED STATEMENTで組んでEXECUTEすべきなんだろうけど、まあ、やり方は分かっているので、ここではあえて書かない。
おわりに
最初はpsqlの\dx+メタコマンドとかで簡単にだせるかなー?と思っていたのだが、実際にやってみると、そう単純なものじゃなかった。
でも、この調査の中で、オブジェクト情報とアドレスの関数という関数群がPostgreSQLに実装されていることもわかったので、なかなか為になる調べ物になりました。