Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

43.8. PL/Perl 幕后机制 #

43.8.1. 配置
43.8.2. 限制和缺失的功能

43.8.1. 配置 #

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

plperl.on_init (string) #

指定在 Perl 解释器首次初始化时执行的 Perl 代码,在 Perl 解释器专门用于 plperlplperlu 之前。执行此代码时,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 解释器专用于 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) #

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

43.8.2. 限制和缺失功能 #

PL/Perl 目前缺少以下功能,但它们将是受欢迎的贡献。

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

  • SPI 尚未完全实现。

  • 如果您使用 spi_exec_query 提取非常大的数据集,则应该知道这些数据集都将进入内存。您可以使用 spi_query/spi_fetchrow 避免这种情况,如前所述。

    如果设置返回函数通过 return 将大量行集返回给 PostgreSQL,则也会出现类似问题。您还可以通过针对每一行返回使用 return_next 来避免此问题,如前所示。

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