45.8. Внутренние особенности PL/Perl #
45.8.1. Конфигурирование #
В этом разделе описываются параметры конфигурации, влияющие на работу PL/Perl.
plperl.on_init
(string
) #Задаёт код Perl, который будет выполняться при первой инициализации интерпретатора Perl, до того, как он получает специализацию
plperl
илиplperlu
. Когда этот код выполняется, функции SPI ещё не доступны. Если выполнение кода завершается ошибкой, инициализация интерпретатора прерывается и ошибка распространяется в вызывающий запрос, в результате чего текущая транзакция или подтранзакция прерывается.Размер этого кода ограничивается одной строкой. Более объёмный код можно поместить в модуль и загрузить этот модуль в строке
on_init
. Например:plperl.on_init = 'require "plperlinit.pl"' plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;'
Любые модули, загруженные в
plperl.on_init
, явно или неявно, будут доступны для использования в коде на языкеplperl
. Это может создать угрозу безопасности. Чтобы определить, какие модули были загружены, можно выполнить:DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
Если библиотека
plperl
включена в shared_preload_libraries, инициализация произойдёт в главном процессе (postmaster) и в этом случае необходимо очень серьёзно оценить риск нарушения работоспособности этого процесса. Основной смысл использовать эту возможность в том, чтобы модули Perl, подключаемые вplperl.on_init
, загружались только при запуске главного процесса, и это исключало бы издержки загрузки для отдельных сеансов. Однако имейте в виду, что эти издержки исключаются только при загрузке в сеансе первого интерпретатора Perl — будь то PL/PerlU или PL/Perl для первой SQL-роли, вызывающей функцию на PL/Perl. Любые дополнительные интерпретаторы Perl, создаваемые в сеансе базы данных, должны будут выполнятьplperl.on_init
заново. Также учтите, что в Windows предварительная загрузка не даёт никакого выигрыша, так как интерпретатор Perl, созданный в главном процессе, не передаётся дочерним процессам.Задать этот параметр можно только в
postgresql.conf
или в командной строке при запуске сервера.plperl.on_plperl_init
(string
)plperl.on_plperlu_init
(string
) #В этих параметрах задаётся код Perl, который будет выполняться в момент, когда интерпретатор Perl получает специализацию
plperl
илиplperlu
, соответственно. Это произойдёт, когда в рамках сеанса будет первый раз вызвана функция на PL/Perl или PL/PerlU, либо когда потребуется дополнительный интерпретатор при использовании другого языка или при вызове функции PL/Perl новой SQL-ролью. Этот код выполняется после инициализации, произведённой вplperl.on_init
. Однако функции SPI в момент исполнения этого кода ещё не доступны. Код вplperl.on_plperl_init
запускается после того, как интерпретатор «помещается под замок», так что в нём разрешаются только доверенные операции.Если этот код завершается ошибкой, инициализация прерывается и ошибка распространяется в вызывающий запрос, что приводит к прерыванию текущей транзакции или подтранзакции. При этом любые действия, уже произведённые в Perl, не будут отменены; однако использоваться этот интерпретатор больше не будет. При следующей попытке использовать этот язык система попытается заново инициализировать свежий интерпретатор Perl.
Изменять эти параметры разрешено только суперпользователям. Хотя изменить их можно в рамках сеанса, такие изменения не повлияют на работу интерпретаторов Perl, задействованных для выполнения функций ранее.
plperl.use_strict
(boolean
) #При значении, равном true, последующая компиляция функций PL/Perl будет выполняться с включённым указанием
strict
. Этот параметр не влияет на функции, уже скомпилированные в текущем сеансе.
45.8.2. Ограничения и недостающие возможности #
Следующие возможности в настоящее время в PL/Perl отсутствуют, но их реализация будет желанной доработкой.
Функции на PL/Perl не могут напрямую вызывать друг друга.
SPI ещё не полностью реализован.
Если вы выбираете очень большие наборы данных, используя
spi_exec_query
, вы должны понимать, что все эти данные загружаются в память. Вы можете избежать этого, используя пару функцийspi_query
/spi_fetchrow
, как показано ранее.Похожая проблема возникает, если функция, возвращающая множество, передаёт в PostgreSQL большое число строк, выполняя
return
. Этой проблемы так же можно избежать, выполняя для каждой возвращаемой строкиreturn_next
, как показано ранее.Когда сеанс завершается штатно, не по причине критической ошибки, в Perl выполняются все блоки
END
, которые были определены. Никакие другие действия в настоящее время не выполняются. В частности, буферы файлов автоматически не сбрасываются и объекты автоматически не уничтожаются.