PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

43.8. PL/Perl 的内部机制 #

43.8.1. 配置
43.8.2. 限制与缺失的特性

43.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 中, 初始化会在 postmaster 中发生,这种情况下应当额外考虑导致 postmaster 不稳定的风险。 使用这一特性的主要原因是:由 plperl.on_init 加载的 Perl 模块只需在 postmaster 启动时加载一次,随后在各个数据库会话中就能立即 使用,而无需加载开销。 不过,请记住这一开销只对数据库会话使用的第一个 Perl 解释器 避免 — 要么是 PL/PerlU,要么是第一个调用 PL/Perl 函数的 SQL 角色的 PL/Perl。 数据库会话中创建的任何额外的 Perl 解释器都必须重新执行 plperl.on_init。 此外,在 Windows 上预加载不会带来任何节省,因为在 postmaster 进程中创建的 Perl 解释器不会传播到子进程。

这个参数只能在 postgresql.conf 文件中或 服务器命令行上设置。

plperl.on_plperl_init (string)
plperl.on_plperlu_init (string) #

这些参数分别指定当 Perl 解释器被专门化用于 plperl 或 plperlu 时要执行的 Perl 代码。 这会在 PL/Perl 或 PL/PerlU 函数在数据库会话中首次执行时发生, 或者当必须因调用另一种语言或因 PL/Perl 函数被新的 SQL 角色 调用而创建额外的解释器时发生。 它发生在 plperl.on_init 完成的任何初始化 之后。 这段代码执行时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码在解释器 被“锁定”之后执行,因此它只能执行受信任的 操作。

如果代码因错误而失败,它会中止初始化并传播到调用查询,导致 当前事务或子事务被中止。 Perl 内已经完成的任何动作都不会被撤销;不过,该解释器不会再被 使用。 如果再次使用该语言,初始化会在一个全新的 Perl 解释器中再次 尝试。

只有超级用户可以修改这些设置。 虽然这些设置可以在会话内被修改,这样的修改不会影响已经执行过 函数的 Perl 解释器。

plperl.use_strict (boolean) #

设置为真时,后续 PL/Perl 函数的编译将启用 strict pragma。 该参数不影响当前会话中已经编译的函数。

43.8.2. 限制与缺失的特性 #

以下特性目前在 PL/Perl 中缺失,但对它们的贡献将受到欢迎。

  • PL/Perl 函数无法相互直接调用。

  • SPI 尚未完全实现。

  • 如果您使用 spi_exec_query 取回非常大的数据集,应当注意 这些数据都会进入内存。 您可以通过使用前文演示的 spi_query/spi_fetchrow 来 避免这一点。

    如果一个集合返回函数通过 return 把大量行 传回 PostgreSQL,也会发生类似的问题。 您同样可以避免这个问题,方法是改用 return_next 逐行返回,如前所示。

  • 当会话正常结束(而非因致命错误)时,任何已定义的 END 块都会被执行。 目前不会执行其他任何动作。特别地,文件句柄不会被自动冲刷, 对象也不会被自动销毁。