CREATE LANGUAGE

名称

CREATE LANGUAGE — 为函数定义一个新的语言

语法

CREATE [ TRUSTED ] PROCEDURAL LANGUAGE 'langname'
    HANDLER call_handler
    LANCOMPILER 'comment'

输入

TRUSTED
TRUSTED 说明对该语言的调用句柄是安全的;也就是说,它不会提供给非特权用户饶过访问限制的功能.如果忽略这个关键字,只有具有Postgres 超级用户权限的人可以使用这个语言创建新的函数(如 'C' 语言).
langname
新的过程化语言的名称.语言名是大小写无关的.一个过程化语言不能超越Postgres 内建的语言.
HANDLER call_handler
call_handler 是预先注册过的函数名,它将被调用于执行PL过程.
comment
LANCOMPILER 参数是将被插入 pg_languageLANCOMPILER 字段的字串.当前,Postgres 不使用这个字段.

输出

CREATE
语言成功创建后返回的信息.
ERROR: PL handler function funcname() doesn't exist
如果函数 funcname() 不存在,返回此信息.

描述

使用 CREATE LANGUAGE,Postgres 用户可以在 Postgres 里注册一个新的语言.因而,函数和触发器过程可以用这种新语言定义.要注册新语言用户必须具有 Postgres 超级用户权限.

书写 PL 句柄

过程语言的调用句柄必须用一种编译语言,比如说 'C',并且在 Postgres 里注册成一个无参数输入,返回值是 opaque 类型(一个用于未声明或未定义类型的容器)的函数.这就避免了调用句柄直接被查询当作函数调用.

但是,要想在该句柄提供的语言里进行PL函数或触发器过程实际调用,就必须提供参数.

取得 pg_proc 表和分析被调过程参数和返回值类型的任务属于调用句柄.过程中的 CREATE FUNCTION 的 AS 子句可在 pg_proc 表的 prosrc 字段里找到.这里有可能是过程语言的源文件本身(像 PL/Tcl),或者是一指向一个文件的路径或是其他任何一个告诉调用句柄如何处理细节的东西.

注意

使用 CREATE FUNCTION 创建函数.

使用 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' 函数的功能和限制.

目前,过程语言的定义一旦建立就不能更改.
 

用法

下面是一个用 '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';

兼容性

SQL92

CREATE LANGUAGE 是 Postgres 扩展.在 SQL92 里 没有 CREATE LANGUAGE 语句.