第 39章PL/Perl - Perl 手続き言語

目次
39.1. PL/Perl関数と引数
39.2. PL/Perlにおけるデータ値
39.3. PL/Perlからのデータベースアクセス
39.4. 信頼されたPL/Perlおよび信頼されないPL/Perl
39.5. 存在しない機能

PL/PerlはPerlプログラミング言語を使用してPostgreSQL関数を作成することができる、読み込み可能な手続き言語です。

PL/Perlを特定のデータベースにインストールするには、createlang plperl dbnameを使用してください。

ティップ: 言語をtemplate1にインストールすると、その後に作成されるデータベース全てにその言語は自動的にインストールされます。

注意: ソースパッケージを使用するユーザは、インストールプロセスの間PL/Perlの構築を特に使用可能にしておく必要があります。 (詳細については、インストール手順を参照してください。) バイナリパッケージを使用する場合は、別個のサブパッケージにPL/Perlが入っている可能性があります。

39.1. PL/Perl関数と引数

PL/Perl言語で関数を作成するには、以下の標準構文を使用して下さい。

CREATE FUNCTION funcname (argument-types) RETURNS return-type AS '
    # PL/Perl function body
' LANGUAGE plperl;

関数本体は通常のPerlのコードです。

引数と結果は他のPerlサブルーチンと同様に扱われます。 引数は@_の中に渡され、結果値はreturn、または、その関数で最後に評価された式として返されます。

例えば、2つの整数の内大きな方を返す関数は以下のように定義できます。

CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS '
    if ($_[0] > $_[1]) { return $_[0]; }
    return $_[1];
' LANGUAGE plperl;

SQLのNULL値が関数に渡された場合、その引数値はPerlにおける"未定義"として現れます。 上の関数定義では、NULLが入力された場合うまく動作しないでしょう(実際はそれがゼロであるかのように動作するでしょう)。 STRICTを関数定義に加えることで、PostgreSQLの動作をより合理的にすることができます。 NULL値が渡された場合、関数はまったく呼び出されず、単にNULLという結果が自動的に返されます。 他の方法として、関数本体で未定義な入力をチェックすることもできます。 たとえば、perl_maxの引数の片方がNULL、もう片方が非NULLの場合に、NULL値ではなく非NULLの引数を返すようにするとします。

CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS '
    my ($a,$b) = @_;
    if (! defined $a) {
        if (! defined $b) { return undef; }
        return $b;
    }
    if (! defined $b) { return $a; }
    if ($a > $b) { return $a; }
    return $b;
' LANGUAGE plperl;

上で示した通り、PL/Perl関数からSQLのNULL値を返すためには、未定義値を返すようにして下さい。 これは、関数が厳密かどうかに関係なく、実行することができます。

複合型の引数はハッシュへの参照として関数に渡されます。 ハッシュのキーは複合型の属性名です。 以下に例を示します。

CREATE TABLE employee (
    name text,
    basesalary integer,
    bonus integer
);

CREATE FUNCTION empcomp(employee) RETURNS integer AS '
    my ($emp) = @_;
    return $emp->{''basesalary''} + $emp->{''bonus''};
' LANGUAGE plperl;

SELECT name, empcomp(employee) FROM employee;

今のところ、複合型の結果値を返す機能はサポートされていません。

ティップ: 関数本体は、CREATE FUNCTIONにSQL文字リテラルとして渡されますので、Perlソース内の単一引用符やバックスラッシュをエスケープしなければなりません。 通常は上の例のようにそれらを二重にします。 他の方法は、Perlの拡張引用演算子(q[]qq[]qw[])を使用して、単一引用符を使用しないようにすることです。