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';