受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

43.8. PL/Perl 内部机制 #

43.8.1. 配置 #

本节列出影响 PL/Perl 的配置参数。

plperl.on_init (string) #

指定在 Perl 解释器首次初始化时、在它被专用于 plperlplperlu 之前,要执行 的 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 解释器被专用于 plperlplperlu 时要执行的 Perl 代码。这会在数据库 会话中首次执行 PL/Perl 或 PL/PerlU 函数时发生;如果因为调用另一种 语言,或某个新的 SQL 角色调用了 PL/Perl 函数而需要创建额外解释器时, 也会发生。这是在 plperl.on_init 完成的任何初始化 之后进行的。执行这段代码时 SPI 函数不可用。 plperl.on_plperl_init 中的 Perl 代码是在对解释器 进行锁定之后执行的,因此只能执行可信操作。

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

只有超级用户可以更改这些设置。尽管这些设置可以在会话中修改,但这类 更改不会影响已经用于执行函数的 Perl 解释器。

plperl.use_strict (boolean) #

如果将其设为真,后续编译的 PL/Perl 函数都会启用 strict 编译指示。该参数不影响当前会话中已经编译 的函数。

43.8.2. 限制与缺失特性 #

PL/Perl 目前仍缺少下列特性,但欢迎为此作出贡献。

  • PL/Perl 函数不能直接调用彼此。

  • SPI 尚未完全实现。

  • 如果使用 spi_exec_query 取回非常大的数据集, 应注意这些数据都会进入内存。可以像前面所示那样,通过使用 spi_query/spi_fetchrow 来避免 这种情况。

    如果集合返回函数通过 return 把一个大型行集 返回给 PostgreSQL,也会出现类似问题。 前面已经说明过,可以改为对每一行使用 return_next,从而避免这个问题。

  • 当会话正常结束(而不是由于致命错误结束)时,任何已经定义的 END 块都会被执行。目前不会执行其他操作。具体来说, 文件句柄不会自动刷写,对象也不会自动销毁。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。