pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
CREATE LANGUAGE — 为函数定义一种新语言
CREATE [ TRUSTED ] PROCEDURAL LANGUAGE 'langname' HANDLERcall_handlerLANCOMPILER 'comment'
TRUSTED指定该语言的调用处理器是安全的;也就是说,它不会为无特权用户提供任何绕过访问限制的功能。如果注册语言时省略这个关键字,则只有拥有 Postgres超级用户权限的用户能用这种语言创建新函数 (就像'C'语言那样)。
langname新过程语言的名称。语言名不区分大小写。过程语言不能覆盖 Postgres的内建语言之一。
call_handlercall_handler是一个先前已注册函数的名称,该函数将被调用来执行 PL 过程。
commentLANCOMPILER参数是将被插入到新的 pg_language项的LANCOMPILER属性中的字符串。目前, Postgres完全不以任何方式使用这个属性。
CREATE如果语言成功创建,就返回此消息。
ERROR: PL handler function funcname() doesn't exist如果找不到函数 funcname(),就返回此错误。
使用CREATE LANGUAGE, Postgres用户可以向 Postgres注册一种新语言。随后,就可以用这种新语言定义函数和触发器过程。注册新语言的用户必须拥有 Postgres超级用户权限。
过程语言的调用处理器必须用 'C'之类的编译器语言编写,并作为不带参数、返回 opaque类型的函数注册到 Postgres中,这个类型是为未指定或未定义类型准备的占位类型。这可以防止调用处理器被当作函数从查询中直接调用。(不过,当要执行处理器所提供的语言中的某个 PL 函数时,实际调用中还是可以提供参数的。)
不过,当要执行处理器所提供的语言中的某个 PL 函数或触发器过程时,实际调用中必须提供参数。
从触发器管理器调用时,唯一的参数是过程的pg_proc项的对象 ID。来自触发器管理的所有其他信息都可以在全局CurrentTriggerData指针中找到。
从函数管理器调用时,参数是过程pg_proc项的对象 ID、给 PL 函数的参数个数、放在FmgrValues结构中的参数,以及一个指向布尔值的指针,函数通过它告诉调用方返回值是否为 SQL NULL 值。
获取pg_proc项并分析被调用过程的参数和返回类型,是调用处理器的责任。过程的 CREATE FUNCTION中的 AS 子句可以在pg_proc表项的prosrc属性中找到。它可以是过程语言自身的源文本(例如 PL/Tcl),可以是一个文件的路径名,也可以是任何能告诉调用处理器具体做什么的东西。
使用CREATE FUNCTION创建函数。
使用DROP LANGUAGE删除过程语言。
参阅表pg_language以获得更多信息:
Table = pg_language
+--------------------------+--------------------------+-------+
| Field | Type | Length|
+--------------------------+--------------------------+-------+
| lanname | name | 32 |
| lancompiler | text | var |
+--------------------------+--------------------------+-------+
lanname |lancompiler
--------+--------------
internal|n/a
lisp |/usr/ucb/liszt
C |/bin/cc
sql |postgres
由于过程语言的调用处理器必须以 'C'语言注册到 Postgres中,它继承了 'C'函数的所有能力和限制。
目前,过程语言的定义一旦创建就不能更改。
这是一个用 'C'编写的 PL 处理器模板:
#include "executor/spi.h"
#include "commands/trigger.h"
#include "utils/elog.h"
#include "fmgr.h" /* for FmgrValues struct */
#include "access/heapam.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
Datum
plsample_call_handler(
Oid prooid,
int pronargs,
FmgrValues *proargs,
bool *isNull)
{
Datum retval;
TriggerData *trigdata;
if (CurrentTriggerData == NULL) {
/*
* Called as a function
*/
retval = ...
} else {
/*
* Called as a trigger procedure
*/
trigdata = CurrentTriggerData;
CurrentTriggerData = NULL;
retval = ...
}
*isNull = false;
return retval;
}
只需在省略号处再加上几千行代码,就能完成这个 PL 调用处理器。关于如何把它编译成可装载模块,见CREATE FUNCTION。
下面的命令随后注册这个示例过程语言:
CREATE FUNCTION plsample_call_handler () RETURNS opaque
AS '/usr/local/pgsql/lib/plsample.so'
LANGUAGE 'C';
CREATE PROCEDURAL LANGUAGE 'plsample'
HANDLER plsample_call_handler
LANCOMPILER 'PL/Sample';
CREATE LANGUAGE 是 Postgres扩展。
SQL92中没有 CREATE LANGUAGE语句。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。