Greenplum的PL/Perl语言扩展
Parent topic: Greenplum数据库参考指南
通过Greenplum数据库的PL/Perl扩展,用户可以用Perl写用户定义的函数,可以利用Perl先进的字符串处理操作和函数。 PL/Perl同时提供了可信和不可信的语言变体。
PL/Perl内嵌在用户的Greenplum数据库发布中。 Greenplum数据库的PL/Perl要求系统中每台数据库主机都要事先装好Perl。
参考获取额外信息。
Greenplum数据库PL/Perl的限制包括:
- Greenplum数据库不支持PL/Perl触发器。
- PL/Perl函数不能直接相互调用。
- SPI还没有完全的实现。
- 当一个会话正常结束而不是由于一个致命错误结束时,PL/Perl会执行用户定义好的任何END块。 当前没有其它的动作执行(文件处理不会被自动地刷写并且对象也不会被自动销毁)。
PL/Perl 包含了可信和不可信两种语言的变体。
PL/Perl可信语言被命名为plperl。 可信PL/Perl语言限制文件系统操作,和require、use以及其它可能同操作系统或者数据库服务进程进行交互的语句。 有了这些限制,任何Greenplum用户能够创建和执行可信的plperl语言的函数。
PL/Perl不可信语言被命名为plperlu。 您不能使用plperlu不受信任的语言限制您创建的函数的操作。 只有数据库的超级用户才有权限创建有不可信PL/Perl语言的用户定义函数。 同时只有数据库的超级用户以及其他被显式授予特权的用户能够执行不可信PL/Perl的用户定义函数。
在解释器以及运行在单个进程中的多个解释器之间的通信方面,PL/Perl有限制。 请参考 PostgreSQL的可信与不可信PL/PerlPL/Perl文档获取更多的信息。
Note: 只用数据库超级用户可能注册或者移除对不可信PL/Perl语言plperlu的支持。
在用户在数据库中开启或者移除PL/Perl支持之前,确保:
- 用户的Greenplum数据库正在运行。
- 用户已经执行(source)了greenplum_path.sh。
- 用户已经设置了$MASTER_DATA_DIRECTORY和$GPHOME环境变量。
对于要在其中启用PL/Perl的每个数据库,请使用SQL 命令注册该语言。 例如,以gpadmin用户身份运行以下命令,为名为testdb的数据库注册可信PL/Perl语言:
要从数据库中删除对PL/Perl的支持,请运行SQL DROP EXTENSION命令。 例如,以gpadmin用户身份运行以下命令,从名为testdb的数据库中删除对可信PL/Perl语言的支持:
如果任何现有对象(如函数)依赖于语言,则默认命令将失败。 指定CASCADE选项也可以删除所有依赖对象,包括使用PL/Perl创建的函数。
您可以使用标准SQL 语法定义PL/Perl函数。 PL/Perl用户定义函数的主体是普通的Perl代码。 PL/Perl解释器将此代码包装在Perl子例程中。
您还可以使用PL/Perl创建匿名代码块。 使用SQL DO命令调用的匿名代码块不接收任何参数,并且丢弃它可能返回的任何值。 否则,PL/Perl匿名代码块的行为就像一个函数。 只有数据库超级用户使用不受信任的plperlu语言创建匿名代码块。
CREATE FUNCTION命令的语法要求您将PL/Perl函数体写为字符串常量。 虽然使用美元引用更方便,但您可以选择使用转义字符串语法(E’’),前提是您将函数体中使用的任何单引号和反斜杠加倍。
PL/Perl参数和结果在Perl中处理。 传递给PL/Perl函数的参数可通过@_数组访问。 使用return语句返回结果值,或者作为函数中计算的最后一个表达式返回结果值。 PL/Perl函数不能直接返回非标量类型,因为您在标量上下文中调用它。 您可以通过返回引用来返回PL/Perl函数中的非标量类型(如数组,记录和集)。
以下PL/Perl函数使用STRICT关键字返回两个整数中的较大者,如果任何输入为null,则返回null:
PL/Perl认为函数参数中的任何内容都不是对字符串的引用,即标准的Greenplum数据库外部文本表示。 提供给PL/Perl函数的参数值只是转换为文本形式的输入参数(就像它们已经被SELECT语句显示一样)。 如果函数参数不是普通的数字或文本类型,则必须将Greenplum数据库类型转换为Perl更易使用的形式。 相反,return和return_next语句接受任何字符串,该字符串是函数声明的返回类型的可接受输入格式。
有关其他信息,请参阅PostgreSQL 文档,包括复合类型和结果集操作。
PL/Perl包含用于访问数据库的内置函数,包括用于准备和执行查询以及操作查询结果的函数。 该语言还包括用于错误记录和字符串操作的实用程序函数。
以下示例创建一个包含整数和文本列的简单表。 它创建一个PL/Perl用户定义函数,该函数接受输入字符串参数并调用spi_exec_query()内置函数来选择表的所有列和行。 该函数返回查询结果中的所有行,其中v列包含函数输入字符串。
有关可用函数的详细讨论,请参阅PostgreSQL PL/Perl内置函数文档。
您可以使用全局哈希映射%_SHARED在当前会话的生命周期内在PL/Perl函数调用之间共享数据,包括代码引用。
以下示例使用%_SHARED在用户定义的set_var()和get_var() PL/Perl函数之间共享数据:
出于安全原因,PL/Perl为每个角色创建一个单独的Perl解释器。 这可以防止一个用户对另一个用户的PL/Perl函数的行为进行意外或恶意干扰。 每个这样的解释器都保留其自己的%_SHARED变量值和其他全局状态。 当且仅当它们由相同的SQL角色执行时,两个PL/Perl函数共享相同的%_SHARED值。
在开发PL/Perl函数其它要考虑的:
- PL/Perl内部使用UTF-8编码。 它将其他编码中提供的任何参数转换为UTF-8,并将UTF-8的返回值转换回原始编码。
- 嵌套命名的PL/Perl子例程保留了与Perl相同的危险。
- 只有不受信任的PL/Perl语言变体支持模块导入。 小心使用plperlu。
- 您在plperlu函数中使用的任何模块都必须在所有Greenplum数据库主机上的相同位置可用。