Я столкнулся с особенностью хранимой процедуры plperl на Postgres 9.2 с Perl 5.12.4.Почему эта хранимая процедура postgres хочет использовать utf8?
Любопытное поведение может быть воспроизведена с помощью этого "сломанный" 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//
операцию в Eval, он работает:
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, который называется only time one shoulduse utf8
.Во всяком случае, я мог ожидать, что версия
eval
разрывается безuse utf8
, в случае, если входные данные для скрипта содержат значения, отличные от ASCII. (Дальнейшее тестирование показывает, что передача значений не-ASCII преградить() действительно вызывает Eval на неудачу с такой же ошибкой)
Обратите внимание, что многие Postgres установки автоматической загрузки «utf8» при запуске на Perl переводчик. Это значение по умолчанию в Debian, по крайней мере, как показано на выполнение
DO 'elog(WARNING, join ", ", sort keys %INC)' language plperl;
:
ВНИМАНИЕ: Carp.pm, карп/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, перегрузка.pm, strict.pm, vars.pm, warnings.pm, warnings/register.pm
КОНТЕКСТ: PL/Perl анонимный блок кода
DO
Этот вопрос не о том, как получить свою целевую машину для загрузки utf8 автоматически; Я знаю, как это сделать. Мне любопытно, почему это, по-видимому, необходимо в первую очередь.
(Не работает, потому что вы забыли избежать '' '. Вы также должны избежать второго' $ '.) – ikegami
@ikegami: Второй' $ 'не должен быть экранирован, но хороший вызов на' \ 'chars; теперь я получаю правильный вывод, что делает вопрос еще более загадочным. – Flimzy
Да, должно. Если вы не избежите второго '$', он будет терпеть неудачу для '$ re = '/; система («rm -rf /»); дг/';'. Ошибка впрыска! – ikegami