Перейти к основному содержимому

PL/Perl под капотом

примечание

Эта страница переведена при помощи нейросети GigaChat.

Конфигурация

В этом разделе перечислены параметры конфигурации, которые влияют на PL/Perl.

plperl.on_init (string)

Задает код Perl, который должен быть выполнен при первой инициализации интерпретатора Perl, до того, как он будет специализирован для использования с помощью plperl или plperlu. Функции SPI недоступны при выполнении этого кода. Если код завершается ошибкой, это приведет к прерыванию инициализации интерпретатора и распространению ошибки на вызывающий запрос, что приведет к отмене текущей транзакции или подоперации.

Код Perl ограничен одной строкой. Более длинный код можно поместить в модуль и загрузить с помощью строки 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, в этом случае следует уделить особое внимание риску дестабилизации постмастера. Основная причина использования этой функции заключается в том, что модули 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 недоступны при выполнении этого кода. Код Perl в plperl.on_plperl_init выполняется после «блокировки» интерпретатора, и поэтому он может выполнять только доверенные операции.

Если код завершается с ошибкой, он прервет инициализацию и передаст ее вызывающему запросу, что приведет к прерыванию текущей транзакции или подоперации. Любые действия, уже выполненные в Perl, не будут отменены, однако этот интерпретатор больше использоваться не будет. Если язык используется снова, инициализация будет предпринята снова внутри свежего интерпретатора Perl.

Только суперпользователи могут изменять эти настройки. Хотя эти настройки можно изменить во время сеанса, такие изменения не повлияют на интерпретаторы Perl, которые уже были использованы для выполнения функций.

plperl.use_strict (boolean)

Когда установлено значение true, последующие компиляции функций PL/Perl будут иметь включенную директиву strict. Этот параметр не влияет на функции, уже скомпилированные в текущем сеансе.

Ограничения и отсутствующие функции

В настоящее время отсутствуют следующие функции из PL/Perl:

  • Функции PL/Perl не могут вызывать друг друга напрямую.

  • SPI еще не полностью реализован.

  • Если извлекаются очень большие наборы данных с помощью spi_exec_query, следует знать, что все это будет загружено в память. Можно избежать этого, используя spi_query/spi_fetchrow, как было показано ранее.

    Аналогичная проблема возникает, если функция, возвращающая набор, передает большой набор строк обратно в PostgreSQL через return. Можно избежать и этой проблемы, используя вместо этого return_next для каждой строки, возвращаемой, как показано ранее.

  • Когда сеанс завершается нормально, не из-за фатальной ошибки, любые блоки END, которые были определены, выполняются. В настоящее время никакие другие действия не выполняются. В частности, дескрипторы файлов автоматически не очищаются, а объекты автоматически не уничтожаются.