《PostgreSQL Conference Japan 2018》   他のバージョンの文書10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

43.8. PL/Perlの内部

43.8.1. 設定

本節ではPL/Perlに影響する設定パラメータを列挙します。

plperl.on_init (string)

Perlインタプリタが最初に初期化され、plperlまたはplperluでの使用のための準備がなされる前に実行されるperlコードを指定します。 このコードが実行される時にはSPI関数を利用できません。 このコードがエラーで失敗した場合、インタプリタの初期化は中断され、呼び出し元の問い合わせに伝わり、現在のトランザクションまたはサブトランザクションがアボートすることになります。

このPerlコードは単一文字列に制限されます。 長いコードをモジュール化し、on_init文字列でロードすることができます。 以下に例を示します。

plperl.on_init = 'require "plperlinit.pl"'
plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;'

plperl.on_initにより直接または間接的に読み込まれるモジュールはすべて、plperlにより使用可能になります。 これはセキュリティの危険性が発生する可能性があります。 どんなモジュールが読み込まれたかを確認するためには以下を使用します。

DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;

plperlライブラリがshared_preload_librariesに含まれている場合、初期化はpostmaster内部で起こります。 この場合、postmasterが不安定になる危険が出てくるため、一層の考慮が必要です。 この機能を使用できるようにした大きな理由は、plperl.on_initでロードされるPerlモジュールはpostmaster起動時点のみでロードされなければならないためです。 このため個々のデータベースセッション内にロードというオーバーヘッドをもたらすことなく即座に利用できるようになります。 しかし、データベースセッションで最初に使用されるPerlインタプリタ(PL/PerlUまたはPL/Perl関数を呼び出す最初のSQLロール用のPL/Perl)に対してのみ、このオーバーヘッドを防ぐことができる点に注意してください。 データベースセッション内でその後に作成されるPerlインタプリタはすべて、新たにplperl.on_initを実行する必要があります。 また、postmasterプロセス内で作成されるPerlインタプリタは子プロセスに伝播されませんので、Windowsにおける事前ロードには何かを節約することはまったくありません。

このパラメータはpostgresql.confファイルまたはサーバのコマンドラインでのみ設定可能です。

plperl.on_plperl_init (string)
plperl.on_plperlu_init (string)

これらのパラメータはそれぞれ、plperlまたはplperlu用にPerlインタプリタを特化する時に実行されるPerlコードを指定します。 これは、データベースセッション内でPL/PerlまたはPL/PerlU関数が最初に実行される時、または、他の言語が呼び出されたため、あるいは新しいSQLロールでPL/Perl関数が呼び出されたために追加のインタプリタを呼び出す必要があった時に起こります。 この後にplperl.on_initによる初期化が行われます。 このコードを実行する時にはSPI関数は利用できません。 plperl.on_plperl_init内のPerlコードはインタプリタを権限で制限した後に実行されます。 このためPerlコードは信頼できる操作のみを行うことができます。

コードがエラーで失敗した場合、初期化は中断され、呼び出し元にエラーが伝わります。 その結果現在のトランザクションまたはサブトランザクションはアボートします。 Perl内ですでに行われた処理は取り消されません。 言語が再度使用される時、初期化は新しいインタプリタの中で再度試行されます。

スーパーユーザのみがこれらの設定を変更することができます。 これらの設定はセッション内で変更することができますが、このような変更は関数を実行するためにすでに使用されたPerlインタプリタには影響を与えません。

plperl.use_strict (boolean)

真の場合、その後のPL/Perl関数のコンパイルはstrictプラグマが有効になります。 このパラメータは現在のセッションでコンパイル済みの関数には影響しません。

43.8.2. 制限および存在しない機能

現時点では、以下の機能はPL/Perlにありません。 各機能の寄稿を歓迎します。

  • PL/Perl関数は互いに直接呼び出すことができません。

  • SPIはまだ完全に実装されていません。

  • spi_exec_queryを使用して、非常に大規模なデータセットを取り出そうとする場合、これらがすべてメモリ内に保存されることに注意しなければなりません。 上で示した通り、spi_query/spi_fetchrowを使用することで、これを避けることができます。

    集合を返す関数が大規模な行セットをreturnを介してPostgreSQLに返す場合、同様の問題が起こります。 前述の通り、この問題もreturn_nextを使用して行毎に返すことで避けることができます。

  • セッションが正常に終了した時、致命的なエラーによるものでなければ、定義された任意のENDブロックが実行されます。 現在、その他の動作は行われません。 特にファイルハンドルは自動的に吐き出されません。 またオブジェクトも自動的に破棄されません。