PL/PerlはPerlプログラミング言語を使用してPostgreSQL関数を作成することができる、ロード可能な手続き言語です。
PL/Perlを特定のデータベースにインストールするには、createlang plperl dbnameを使用してください。
ティップ: 言語をtemplate1にインストールすると、その後に作成されるデータベース全てにその言語は自動的にインストールされます。
注意: ソースパッケージを使用するユーザは、インストールプロセスの間PL/Perlの構築を特に使用可能にしておく必要があります。 (詳細については、項14.1を参照してください。) バイナリパッケージを使用する場合は、別個のサブパッケージにPL/Perlが入っている可能性があります。
PL/Perl言語で関数を作成するには、以下の標準構文を使用してください。
CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ # PL/Perl function body $$ LANGUAGE plperl;
関数本体は通常のPerlのコードです。
CREATE FUNCTIONコマンドの構文では、関数本体は文字列定数として記述されることを必須としています。 通常、文字列定数にはドル引用符付け(項4.1.2.2を参照)を使用することが最も便利です。 通常の単一引用符による文字列定数構文を使用することを選択したとすると、関数本体で使用される単一引用符(')とバックスラッシュ(\) を、通常はそれを二重にすることによってエスケープする必要があります。(項4.1.2.1を参照。)
引数と結果は他の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;
必要な属性を持つハッシュの参照を返すという同じ方法で、PL/Perl関数は複合型の結果を返すことができます。 以下に例を示します。
CREATE TYPE testrowperl AS (f1 integer, f2 text, f3 text); CREATE OR REPLACE FUNCTION perl_row() RETURNS testrowperl AS $$ return {f2 => 'hello', f1 => 1, f3 => 'world'}; $$ LANGUAGE plperl; SELECT * FROM perl_row();
宣言されたデータ型の任意の列の内、ハッシュ内に存在しないものはNULLとして返されます。
また、PL/Perl関数はスカラ型の配列や複合型の配列を返すこともできます。 このためには、それぞれスカラもしくはハッシュへの参照を保持する配列への参照を返してください。 以下に数例を示します。
CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$ return [0..$_[0]]; $$ LANGUAGE plperl; SELECT * FROM perl_set_int(5); CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$ return [ { f1 => 1, f2 => 'Hello', f3 => 'World' }, { f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' }, { f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' } ]; $$ LANGUAGE plperl; SELECT * FROM perl_set();
この際Perlは配列全体をメモリ内に構築しなければならないことに注意してください。 このため、この技法は非常に大規模な集合には向いていません。
今のところPL/Perlはドメイン型を完全にサポートしていません。 ドメインをその背後にあるスカラ型と同様に扱います。 これは、ドメインに関連する制約が強制されないことを意味しています。 これは関数の引数では問題ありませんが、PL/Perl関数をドメイン型を返すように宣言した場合は危険です。