45.8. PL/Perl 的内部机制#
45.8.1. 配置#
本部分列出了影响PL/Perl的配置参数。
plperl.on_init
(string
) #指定在 Perl 解释器首次初始化时(在
plperl
或plperlu
专门使用它之前)执行的 Perl 代码。执行此代码时,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 中,则初始化将在后端中发生,在这种情况下,应特别考虑使后端不稳定的风险。使用此功能的主要原因是,由plperl.on_init
加载的 Perl 模块只需在后端启动时加载,并且可以在各个数据库会话中立即使用,而无需加载开销。但是,请记住,仅为数据库会话使用的第一个 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 解释器专门用于
plperl
或plperlu
时执行的 Perl 代码。这将在数据库会话中首次执行 PL/Perl 或 PL/PerlU 函数时发生,或者当必须创建其他解释器时,因为调用了其他语言或新 SQL 角色调用了 PL/Perl 函数。这遵循plperl.on_init
所做的任何初始化。执行此代码时,SPI 函数不可用。在plperl.on_plperl_init
中的 Perl 代码在“锁定”解释器后执行,因此它只能执行受信任的操作。如果代码因错误而失败,它将中止初始化并传播到调用查询,导致当前事务或子事务中止。Perl 中已完成的任何操作都不会撤消;但是,该解释器将不会再次使用。如果再次使用该语言,将在新的 Perl 解释器中再次尝试初始化。
只有超级用户才能更改这些设置。尽管可以在会话中更改这些设置,但此类更改不会影响已用于执行函数的 Perl 解释器。
plperl.use_strict
(boolean
) #当设置为 true 时,PL/Perl 函数的后续编译将启用
strict
pragma。此参数不影响当前会话中已编译的函数。
45.8.2. 限制和缺失功能#
PL/Perl 目前缺少以下功能,但它们将做出受欢迎的贡献。
PL/Perl 函数无法直接相互调用。
SPI 尚未完全实现。
如果您使用
spi_exec_query
提取非常大的数据集,您应该知道所有这些数据集都将进入内存。您可以通过使用spi_query
/spi_fetchrow
来避免这种情况,如前所述。如果一个返回结果集的函数通过
return
将大量行集返回给 PostgreSQL,也会出现类似的问题。您也可以通过对返回的每一行使用return_next
来避免此问题,如前所示。当会话正常结束,不是由于致命错误时,将执行任何已定义的
END
块。目前不会执行任何其他操作。具体来说,文件句柄不会自动刷新,并且对象不会自动销毁。