CREATE LANGUAGE

Name

CREATE LANGUAGE  --  関数のための新しい言語の定義

Synopsis

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

入力

TRUSTED

TRUSTED はその言語の呼び出しハンドラが安全 であることを指定します。つまり、権限を持たないユーザには アクセス制限を無視する機能を何も与えないということです。もし 言語を登録するときにこのキーワードが省略されると、 Postgres スーパーユーザ権限を持つ ユーザのみが新しい関数を作るためにこの言語を使うことができるように なります。

langname

新しい手続き言語の名前です。言語名は大文字小文字の区別が ありません。手続き言語はどの Postgres の組み込み言語を上書きすることはできません。

HANDLER call_handler

call_handler は 以前登録されていた関数の名前で、 PL プロシージャを実行するために 呼び出されるものです。

comment

LANCOMPILER 引数は、新しい pg_language エントリの LANCOMPILER 属性に挿入されるための 文字列です。現時点では、Postgres はこの属性をどこにも使っていません。

出力

CREATE

このメッセージは言語の作成に成功した場合に返されます。

ERROR: PL handler function funcname() doesn't exist

このエラーは、関数 funcname() が見つからない場合に返されます。

説明

Postgres ユーザは CREATE LANGUAGE を使って新しい言語を Postgresに登録することができます。 続いて、関数とトリガプロシージャはこの新しい言語で定義可能に なります。ユーザは新しい言語を登録するためには Postgres のスーパーユーザ 権限を持っていなければいけません。

PL ハンドラの書き方

Note: Postgres 7.1 以降では、呼び出しハンドラ は古い様式のインタフェースではなく、 "version 1" 関数管理者 インタフェースに忠実でなければなりません。

手続き言語の呼び出しハンドラは、 C 言語のようなコンパイラ型 言語で書かれ、引数をとらず未定義の型を意味する opaque 型を返す関数として Postgres に登録されなければ なりません。これは呼び出しハンドラが関数として直接問い合わせ で呼び出されることを防ぐものです。(しかし、言語内でハンドラによって 提供される PL 関数が実行されるべき時は、実際の呼び出しの際に引数が 供給されることもあります。)

呼び出しハンドラは他の関数と同じように呼び出されます。 呼び出される関数に関する情報と引数値を持つ構造体FunctionCallInfoData へのポインタを受け取り、Datum 結果を返すようになっています (そして SQL NULL の結果を返そうとする場合、できる限り FunctionCallInfoData 構造体の isnull フィールドを設定します)。呼び出しハンドラと通常の呼び出される 関数の違いは FunctionCallInfoData 構造体の flinfo->fn_oid フィールドが、 呼び出しハンドラ自身ではなく呼び出される PL 関数の OID を持つと いうことです。呼び出しハンドラはどの関数を実行するかを 決定するためにこのフィールドを使わなければなりません。更に、 渡される引数のリストは呼び出しハンドラではなく目的の PL 関数の宣言 に基づいて設定されています。

pg_proc エントリを取り出し、呼び出された プロシージャの引数と返り値を分析するのは呼び出しハンドラ 次第です。プロシージャの CREATE FUNCTION からの AS 句は pg_proc テーブル エントリの prosrc 属性の中にあります。 これは(PL/Tcl のような)手続き言語自身の中のソーステキスト、 ファイルへのパス名、もしくは呼び出しハンドラに何をすべきか 詳細に指示するほかのものかもしれません。

しばしば、SQL 文ごとに同じ関数が何度も呼び出されることがあります。 呼び出しハンドラは flinfo->fn_extra フィールドを使って呼び出される関数に関する情報が繰り返し検索すること を回避できます。このフィールドの初期値は NULL ですが、 呼び出しハンドラによって PL 関数に関する情報を指し示すように設定 することができます。続く呼び出しでは、もし flinfo->fn_extra がすでに非 NULL である 場合はそれを使うことができ情報検索が飛ばされます。 FmgrInfo データ構造体は現在の問い合わせが終了するまで保存されて いなければならないので、 呼び出しハンドラは flinfo->fn_extra が少なくともその問い合わせが終るまでは存続中のメモリを 指し示すようになっていなければならないことに注意しなければなりません。 この目的のための一つの方法として、 flinfo->fn_mcxt で指定される メモリコンテキストに余分なデータを割り当てることです。 そのようなデータは通常 FmgrInfo 自身と同じ寿命をもちます。 しかしハンドラは、問い合わせを越えて関数定義情報をキャッシュ できるように、更に長く生きるコンテキストの使用を 選ぶこともできます。

PL 関数がトリガとして呼び出されると、明示的な引数は何も 渡されませんが、FunctionCallInfoData の context フィールドは、普通の関数呼出しの中にあるため NULL ではなく TriggerData ノードを指し示します。PL ハンドラは PL 関数が トリガ情報に到達するための仕組を提供しなくてはなりません。

注釈

関数を作成するためには 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

手続き言語の呼び出しハンドラは通常は C 言語で書かれ、バックエンドに リンクされているか動的にロードされるかによって'内部'もしくは 'C'言語として登録されなければなりません。呼び出しハンドラは 古い様式の 'C' 関数インタフェースを使うことはできません。

現時点では、手続き言語の定義は一度作成されると変えることは できません。

使用方法

これは C で書かれた PL ハンドラのテンプレートです。

#include "executor/spi.h"
#include "commands/trigger.h"
#include "utils/elog.h"
#include "fmgr.h"
#include "access/heapam.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"

PG_FUNCTION_INFO_V1(plsample_call_handler);

Datum
plsample_call_handler(PG_FUNCTION_ARGS)
{
     Datum          retval;

     if (CALLED_AS_TRIGGER(fcinfo))
     {
         
      
          /*
           * トリガプロシージャとして呼び出されます。
           */
  
          TriggerData    *trigdata = (TriggerData *) fcinfo->context;

          retval = ...
     } else {
          

          /*
           * 関数として呼び出されます。
           */
           
          retval = ...
     }

     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 LANGUAGEPostgres の拡張です。 SQL92にはCREATE LANGUAGE 文はありません。