4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PostgreSQLの拡張機能がどの言語によって実装されているか調べる。

4
Posted at

はじめに

にゃーん。趣味でポスグレをやっている者だ。

とある事情で、表題にあるように、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に実装されていることもわかったので、なかなか為になる調べ物になりました。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?