バージョンごとのドキュメント一覧

44.2. PL/Tcl関数と引数 #

<title>PL/Tcl Functions and Arguments</title>

To create a function in the <application>PL/Tcl</application> language, use the standard <xref linkend="sql-createfunction"/> syntax: PL/Tcl言語で関数を作成するには、以下の標準的なCREATE FUNCTION構文を使用してください。

CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$

    # PL/Tcl function body

    # PL/Tcl関数本体
$$ LANGUAGE pltcl;

<application>PL/TclU</application> is the same, except that the language has to be specified as <literal>pltclu</literal>. PL/TclUでも、言語にpltcluを指定しなければならない点以外は同様です。

The body of the function is simply a piece of Tcl script. When the function is called, the argument values are passed to the Tcl script as variables named <literal>1</literal> ... <literal><replaceable>n</replaceable></literal>. The result is returned from the Tcl code in the usual way, with a <literal>return</literal> statement. In a procedure, the return value from the Tcl code is ignored. 関数本体は、単なる小さなTclスクリプトです。 関数が呼び出された時、引数の値はTclスクリプトに1 ... nという名前の変数として渡されます。 結果は通常通りreturn文を使用してTclのコードから返されます。 プロシージャでは、Tclコードからの戻り値は無視されます。

For example, a function returning the greater of two integer values could be defined as: 例えば、2つの整数のうち大きな方を返す関数は以下のように定義できます。

CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
    if {$1 > $2} {return $1}
    return $2
$$ LANGUAGE pltcl STRICT;

Note the clause <literal>STRICT</literal>, which saves us from having to think about null input values: if a null value is passed, the function will not be called at all, but will just return a null result automatically. STRICT句に注意してください。 これによりプログラマは、入力にNULL値が与えられた場合を検討する手間を省くことができます。 NULLが渡された場合、関数はまったく呼び出されず、単にNULLという結果が自動的に返されます。

In a nonstrict function, if the actual value of an argument is null, the corresponding <literal>$<replaceable>n</replaceable></literal> variable will be set to an empty string. To detect whether a particular argument is null, use the function <literal>argisnull</literal>. For example, suppose that we wanted <function>tcl_max</function> with one null and one nonnull argument to return the nonnull argument, rather than null: 厳密(strict)でない関数では、引数の実際の値がNULLである場合、対応する$n変数は空文字列に設定されます。 ある引数がNULLかどうかを検出するためには、argisnull関数を使用してください。 例えば、引数の片方がNULL、もう片方が非NULLであって、NULLではなく、非NULLの引数の方を返すtcl_maxを考えると、以下のようになります。

CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
    if {[argisnull 1]} {
        if {[argisnull 2]} { return_null }
        return $2
    }
    if {[argisnull 2]} { return $1 }
    if {$1 > $2} {return $1}
    return $2
$$ LANGUAGE pltcl;

As shown above, to return a null value from a PL/Tcl function, execute <literal>return_null</literal>. This can be done whether the function is strict or not. 上で示した通り、NULL値をPL/Tcl関数から返すためには、return_nullを実行してください。 これは、関数が厳密かどうかに関係なく、実行することができます。

Composite-type arguments are passed to the function as Tcl arrays. The element names of the array are the attribute names of the composite type. If an attribute in the passed row has the null value, it will not appear in the array. Here is an example: 複合型の引数は、Tcl配列として関数に渡されます。 配列の要素名は複合型の属性名です。 渡された行の属性がNULL値の場合、その属性は配列内には現れません。 以下に例を示します。

CREATE TABLE employee (
    name text,
    salary integer,
    age integer
);

CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
    if {200000.0 < $1(salary)} {
        return "t"
    }
    if {$1(age) < 30 && 100000.0 < $1(salary)} {
        return "t"
    }
    return "f"
$$ LANGUAGE pltcl;

PL/Tcl functions can return composite-type results, too. To do this, the Tcl code must return a list of column name/value pairs matching the expected result type. Any column names omitted from the list are returned as nulls, and an error is raised if there are unexpected column names. Here is an example: PL/Tcl関数は複合型の結果を返すこともできます。 このためには、Tclコードは期待する結果型と一致する列の名前/値のペアのリストを返さなければなりません。 そのリストで省略された列名は結果がNULLになり、期待されない列名があるとエラーが生じます。 例を示します。

CREATE FUNCTION square_cube(in int, out squared int, out cubed int) AS $$
    return [list squared [expr {$1 * $1}] cubed [expr {$1 * $1 * $1}]]
$$ LANGUAGE pltcl;

Output arguments of procedures are returned in the same way, for example: プロシージャの出力引数は同様に返されます。以下に例を示します。

CREATE PROCEDURE tcl_triple(INOUT a integer, INOUT b integer) AS $$
    return [list a [expr {$1 * 3}] b [expr {$2 * 3}]]
$$ LANGUAGE pltcl;

CALL tcl_triple(5, 10);

ヒント

The result list can be made from an array representation of the desired tuple with the <literal>array get</literal> Tcl command. For example: array get Tclコマンドを使って、希望するタプルの配列表現から結果リストを作成することができます。

CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$
    set 1(salary) [expr {$1(salary) + $2}]
    return [array get 1]
$$ LANGUAGE pltcl;

PL/Tcl functions can return sets. To do this, the Tcl code should call <function>return_next</function> once per row to be returned, passing either the appropriate value when returning a scalar type, or a list of column name/value pairs when returning a composite type. Here is an example returning a scalar type: PL/Tcl関数は集合を返すことができます。 このためにはTclコードで、return_nextを返却する行ごとに呼び出します。 スカラー値を返却する場合は適切な値を、複合型を返す場合は列の名前/値ペアのリストを渡します。 スカラー型を返す例を示します。

CREATE FUNCTION sequence(int, int) RETURNS SETOF int AS $$
    for {set i $1} {$i < $2} {incr i} {
        return_next $i
    }
$$ LANGUAGE pltcl;

and here is one returning a composite type: 複合型を返す例を示します。

CREATE FUNCTION table_of_squares(int, int) RETURNS TABLE (x int, x2 int) AS $$
    for {set i $1} {$i < $2} {incr i} {
        return_next [list x $i x2 [expr {$i * $i}]]
    }
$$ LANGUAGE pltcl;