===============
CREATE LANGUAGE
===============


.. container:: refentry
   :name: SQL-CREATELANGUAGE

   .. container:: titlepage

   .. container:: refnamediv

      .. rubric:: CREATE LANGUAGE
         :name: create-language

      CREATE LANGUAGE — 定义一种新的过程语言

   .. container:: refsynopsisdiv

      .. rubric:: 大纲
         :name: 大纲

      .. code:: synopsis

         CREATE [ OR REPLACE ] [ PROCEDURAL ] LANGUAGE name
         CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name
             HANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ]

   .. container:: refsect1
      :name: SQL-CREATELANGUAGE-DESCRIPTION

      .. rubric:: 描述
         :name: 描述

      ``CREATE LANGUAGE``\ 为一个 PostgreSQL数据库注册一种新的
      过程语言。接着,可以用这种新语言定义函数和存储过程。

      .. note::

         .. rubric:: 注意
            :name: 注意
            :class: title

         从PostgreSQL 9.1 开始,大多数
         过程语言已经被做成了“扩展”,并且应该用 `CREATE
         EXTENSION <sql-createextension.html>`__\ 而不是
         ``CREATE LANGUAGE``\ 来安装。
         ``CREATE LANGUAGE``\ 的直接使用现在应该
         被限制在扩展安装脚本中。如果在数据库中有一种“裸”语言(
         可能是一次升级的结果),可以用 ``CREATE EXTENSION langname``
         FROM unpackaged把它转换成一个扩展。

      ``CREATE LANGUAGE``\ 实际上把该语言名称与
      负责执行用该语言编写的函数的处理器函数关联在一起。

      有两种形式的\ ``CREATE LANGUAGE``\ 命令。在
      第一种形式中,用户只提供想要的语言的名称。 PostgreSQL服务器会查询
      ```pg_pltemplate`` <catalog-pg-pltemplate.html>`__\ 系统目录来决定正确的参数。在第二种形式中,用户
      要提供语言参数和语言名称。第二种形式可以被用来创建一种没有定义在
      ``pg_pltemplate``\ 中的语言,但是这种方法被认为即将 废弃。

      当服务器在\ ``pg_pltemplate``\ 目录中为给定的语言名称
      找到一个项时,即使命令中已经包括了语言参数,它也将使用目录中的
      数据。这种行为简化了旧转储文件的载入,旧转储文件很可能包含过时的
      信息。

      通常,用户必须拥有 PostgreSQL超级用户特权来注册
      一种新的语言。不过,如果该语言被列举在
      ``pg_pltemplate``\ 目录中并且被标记为允许
      由数据库拥有者创建(\ ``tmpldbacreate``\ 为真),则数据
      库的拥有者可以把新语言注册在数据库中。默认是可信的语言能够由数据
      库拥有者创建,但是超级用户可以通过修改
      ``pg_pltemplate``\ 的内容来调整这种行为。
      语言的创建者会成为它的拥有者,并且以后可以删除它、对它重命名或者
      把它赋予给一个新的拥有者。

      ``CREATE OR REPLACE LANGUAGE``\ 将创建
      或者替换一种现有的定义。如果该语言已经存在,其参数会被根据指定的
      值或者来自\ ``pg_pltemplate``\ 的值更新。但
      该语言的拥有关系和权限设置不会更改,并且任何已有的用该语言编写的
      函数仍然被假定有效。除了创建一种语言的普通特权需求,用户还必须是
      超级用户或者已有语言的拥有者。\ ``REPLACE``\ 情况主要被用来
      确保该语言存在。如果该语言有一个 ``pg_pltemplate``\ 项,那么
      ``REPLACE``\ 将不会实际更改现有定义的任何东西,除非从该语
      言被创建以来\ ``pg_pltemplate``\ 已经被修改 过(很少见的情况)。

   .. container:: refsect1
      :name: SQL-CREATELANGUAGE-PARAMETERS

      .. rubric:: 参数
         :name: 参数

      .. container:: variablelist

         ``TRUSTED``
            ``TRUSTED``\ 指定该语言不会授予用户不该具有的
            数据访问。如果在注册语言时这个关键词被省略,只有具有
            PostgreSQL超级用户特权的用户才能 使用该语言创建新函数。

         ``PROCEDURAL``
            这是一个噪声词。

         *``name``*
            新过程语言的名称。该名称必须在该数据库的语言中唯一。

            为了向后兼容,名称可以用单引号围绕。

         ``HANDLER`` *``call_handler``*
            *``call_handler``*
            是一个之前注册的函数的名称,它将被调用来执行该过程语言的函数。
            一种过程语言的调用处理器必须以一种编译型语言(如 C)编写并且
            具有版本 1 的调用约定,它必须在 PostgreSQL内注册为一个没有
            参数并且返回\ ``language_handler``\ 类型的函数。
            ``language_handler``\ 是一种占位符类型, 它被用来
            标识该函数为一个调用处理器。

         ``INLINE`` *``inline_handler``*
            *``inline_handler``*
            是一个之前注册的函数的名称,它将被调用来执行一个该语言的匿名代码块(
            `DO <sql-do.html>`__\ 命令)。如果没有指定
            *``inline_handler``*\ 函数,则
            该语言不支持匿名代码块。该处理器函数必须接受一个\ ``internal``
            类型的参数,该参数将是\ ``DO``\ 命令的内部表示,而且它通常
            将返回\ ``void``\ 。该处理器的返回值会被忽略。

         ``VALIDATOR`` *``valfunction``*
            *``valfunction``* is the
            是一个之前注册的函数的名称,当一个该语言的新函数被创建时会调用该函数来
            验证新函数。如果没有指定验证器函数,那么一个新函数被创建时不会被检查。
            验证器函数必须接受一个\ ``oid``\ 类型的参数,它将是要被创建的
            函数的 OID,而且它通常将返回\ ``void``\ 。

            一个验证器函数通常会检查函数体中的语法正确性,但是它也能查看函数的其他
            属性,例如该语言能否处理特定的参数类型。为了发出一个错误,验证器函数应该
            使用\ ``ereport()``\ 函数。验证器函数的返回值会被忽略。

      如果指定的语言名称在\ ``pg_pltemplate``\ 中有一项,服务器会忽略
      ``TRUSTED``\ 选项和支持函数的名称。

   .. container:: refsect1
      :name: SQL-CREATELANGUAGE-NOTES

      .. rubric:: 注解
         :name: 注解

      使用\ `DROP LANGUAGE <sql-droplanguage.html>`__\ 删除过程语言。

      系统目录\ ``pg_language``\ 记录着有关当前已安装的语言的信息。
      还有,psql命令\ ``\dL``\ 列出已安装的语言。

      要以一种过程语言创建函数,用户必须具有对于该语言的
      ``USAGE``\ 特权。默认情况下,对于可信语言,
      ``USAGE``\ 被授予给\ ``PUBLIC``\ (即所有人)。
      如果需要可以将它收回。

      过程语言对于单个数据库来说是本地的。但是,一种语言可以被安装在
      ``template1``\ 数据库中,这会导致它在所有后续创建的
      数据库中自动变得可用。

      如果对语言在服务器的\ ``pg_pltemplate``\ 中没有一项,
      调用处理器函数、内联处理器函数(如果有)以及验证器函数(如果有)
      必须已经存在。但是当有一个那样的项时,这些函数不必已经存在。如果
      它们在数据库中不存在,将自动定义它们(如果安装中实现该语言的共享
      库不可用可能会导致\ ``CREATE LANGUAGE``\ 失败)。

      在PostgreSQL 版本 7.3 之前,需要
      将处理器函数声明为返回占位符类型\ ``opaque``\ 而不是
      ``language_handler``\ 。为了支持载入旧的转储文件,
      ``CREATE LANGUAGE``\ 将接受被声明为返回
      ``opaque``\ 的函数,但是它将发出一个提示并且把该函数的声明
      返回类型改为\ ``language_handler``\ 。

   .. container:: refsect1
      :name: SQL-CREATELANGUAGE-EXAMPLES

      .. rubric:: 示例
         :name: 示例

      创建任何标准过程语言的最好的方式是:

      .. code:: programlisting

         CREATE LANGUAGE plperl;

      对于\ ``pg_pltemplate``\ 目录不知道的一种语言,需要这样的命令序列:

      .. code:: programlisting

         CREATE FUNCTION plsample_call_handler() RETURNS language_handler
             AS '$libdir/plsample'
             LANGUAGE C;
         CREATE LANGUAGE plsample
             HANDLER plsample_call_handler;

   .. container:: refsect1
      :name: SQL-CREATELANGUAGE-COMPAT

      .. rubric:: 兼容性
         :name: 兼容性

      ``CREATE LANGUAGE``\ 是一种 PostgreSQL扩展。

   .. container:: refsect1
      :name: id-1.9.3.70.10

      .. rubric:: 另见
         :name: 另见

      `ALTER LANGUAGE <sql-alterlanguage.html>`__, `CREATE
      FUNCTION <sql-createfunction.html>`__, `DROP
      LANGUAGE <sql-droplanguage.html>`__, `GRANT <sql-grant.html>`__,
      `REVOKE <sql-revoke.html>`__