CREATE [ TRUSTED ] PROCEDURAL LANGUAGE 'langname' HANDLER call_handler LANCOMPILER 'comment'
但是,要想在该句柄提供的语言里进行PL函数或触发器过程实际调用,就必须提供参数.
当从函数管理器里调用时,参数是过程 pg_proc 入口的对象标识(object ID),传递给PL函数的参数个数,在FmgrValues 一个结构里的参数和一个指向布尔变量的指针,函数通过这个指针告诉调用者返回值是否SQL NULL.
使用 DROP LANGUAGE 删除一个过程语言.
请参考 pg_language 获取更多信息:
Table "pg_language" Attribute | Type | Modifier ---------------+---------+---------- lanname | name | lanispl | boolean | lanpltrusted | boolean | lanplcallfoid | oid | lancompiler | text | lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler ----------+---------+--------------+---------------+------------- internal | f | f | 0 | n/a C | f | f | 0 | /bin/cc sql | f | f | 0 | postgres因为所有过程语言的调用句柄都必须在 Postgres 里用'C' 语言注册,因而它继承了所有 'C' 函数的功能和限制.
目前,过程语言的定义一旦建立就不能更改.
#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';