PL/Perlにおけるグローバルな値

PostgreSQL 9.1.1文書
前のページ | 巻戻し | 第 41章PL/Perl - Perl手続き言語 | 早送り | 次のページ

# 41.4. PL/Perlにおけるグローバルな値

現在のセッションの有効期間中の関数呼び出し間でデータ（コード参照を含む）を受け渡しするためにグローバルな`%_SHARED`ハッシュを使用することができます。

データの共有について簡単な例を以下に示します。

    CREATE OR REPLACE FUNCTION set_var(name text, val text) RETURNS text AS $$
        if ($_SHARED{$_[0]} = $_[1]) {
            return 'ok';
        } else {
            return "cannot set shared variable $_[0] to $_[1]";
        }
    $$ LANGUAGE plperl;

    CREATE OR REPLACE FUNCTION get_var(name text) RETURNS text AS $$
        return $_SHARED{$_[0]};
    $$ LANGUAGE plperl;

    SELECT set_var('sample', 'Hello, PL/Perl!  How''s tricks?');
    SELECT get_var('sample');

以下は、コード参照を使用した、多少複雑な例です。

    CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$
        $_SHARED{myquote} = sub {
            my $arg = shift;
            $arg =~ s/(['\\])/\\$1/g;
            return "'$arg'";
        };
    $$ LANGUAGE plperl;

    SELECT myfuncs(); /* 関数の初期化 */

    /* 引用符関数を使用する関数を作成 */

    CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$
        my $text_to_quote = shift;
        my $qfunc = $_SHARED{myquote};
        return &$qfunc($text_to_quote);
    $$ LANGUAGE plperl;

（可読性を犠牲にすると、上は`return $_SHARED{myquote}->($_[0]);`という1行のみで置き換えることができます。）

セキュリティ上の理由により、PL/Perlは、あるロールで呼び出された関数をそのロール用に独立したPerlインタプリタ内で実行します。 これにより、あるユーザの事故または悪意によって他のユーザのPL/Perl関数の動作が干渉されてしまうことを防ぎます。 こうしたインタプリタはそれぞれ独自の`%_SHARED`などのグローバル状態を持ちます。 したがって、同一のSQLロールによって実行された場合のみ、２つのPL/Perl関数は同じ`%_SHARED`値を共有します。 １つのセッション内で複数のSQLロールの元でコードを（`SECURITY DEFINER`経由、`SET ROLE`の使用など）実行するアプリケーションでは、確実にPL/Perl関数が`%_SHARED`を介してデータを共有することができるように、明示的な処理を行う必要があります。 このためには、通信しなければならない関数が同じユーザによって所有されること、および`SECURITY DEFINER`と印付けられていることを確実にしなければなりません。 当然ながらこうした関数が意図していないことを行うために使用することができないように注意しなければなりません。

前のページ | ホーム | 次のページ
組込み関数 | 上に戻る | 信頼されたPL/Perlおよび信頼されないPL/Perl