Perl 5.12.4 を使用した Postgres 9.2 の plperl ストアド プロシージャの特異性に遭遇しました。
この「壊れた」SP を使用して、奇妙な動作を再現できます。
CREATE FUNCTION foo(VARCHAR) RETURNS VARCHAR AS $$
my ( $re ) = @_;
$re = ''.qr/\b($re)\b/i;
return $re;
$$ LANGUAGE plperl;
実行時:
# select foo('foo');
ERROR: Unable to load utf8.pm into plperl at line 3.
BEGIN failed--compilation aborted.
CONTEXT: PL/Perl function "foo"
ただし、qr//操作を評価に移動すると、機能します。
CREATE OR REPLACE FUNCTION bar(VARCHAR) RETURNS VARCHAR AS $$
my ( $re ) = @_;
eval "\$re = ''.qr/\\b($re)\\b/i;";
return $re;
$$ LANGUAGE plperl;
結果:
# select bar('foo');
bar
-----------------
(?^i:\b(foo)\b)
(1 row)
eval が自動をバイパスするのはなぜ
use utf8ですか?use utf8そもそもなぜ必要なのですか?私のコードは UTF8 ではありませんuse utf8。どちらかといえば、スクリプトへの入力に非 ASCII 値が含まれている場合、
evalバージョンが なしで壊れると予想されるかもしれません。use utf8(さらなるテストでは、ASCII 以外の値を bar() に渡すと、実際に eval が同じエラーで失敗することが示されています)
多くの Postgres インストールでは、perl インタープリターの起動時に「utf8」が自動的に読み込まれることに注意してください。これは、少なくとも Debian ではデフォルトであり、次の実行で示され
DO 'elog(WARNING, join ", ", sort keys %INC)' language plperl;ます。
警告: Carp.pm、Carp/Heavy.pm、Exporter.pm、feature.pm、overload.pm、strict.pm、unicore/Heavy.pl、unicore/To/Fold.pl、unicore/lib/Perl/SpacePer。 pl、utf8.pm、utf8_heavy.pl、vars.pm、warnings.pm、warnings/register.pm コンテキスト
: PL/Perl 匿名コード ブロック
DO
しかし、奇妙な動作を示すマシンではそうではありません:
警告: Carp.pm、Carp/Heavy.pm、Exporter.pm、feature.pm、overload.pm、overloading.pm、strict.pm、vars.pm、warnings.pm、warnings/register.pm コンテキスト
: PL/Perl匿名コード ブロック
DO
この質問は、ターゲット マシンに utf8 を自動的にロードさせる方法に関するものではありません。私はそれを行う方法を知っています。そもそもなぜ必要なのか気になります。