他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

43.2. PL/Tcl関数と引数

PL/Tcl言語で関数を作成するには、以下の標準的なCREATE FUNCTION構文を使用してください。

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

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

PL/TclUでも、言語にpltcluを指定しなければならない点以外は同様です。

関数本体は、単なる小さなTclスクリプトです。 関数が呼び出された時、引数の値はTclスクリプトに1 ... nという名前の変数として渡されます。 結果は通常通りreturn文を使用してTclのコードから返されます。 プロシージャでは、Tclコードからの戻り値は無視されます。

例えば、2つの整数のうち大きな方を返す関数は以下のように定義できます。

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

STRICT句に注意してください。 これによりプログラマは、入力にNULL値が与えられた場合を検討する手間を省くことができます。 NULLが渡された場合、関数はまったく呼び出されず、単に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;

上で示した通り、NULL値をPL/Tcl関数から返すためには、return_nullを実行してください。 これは、関数が厳密かどうかに関係なく、実行することができます。

複合型の引数は、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関数は複合型の結果を返すこともできます。 このためには、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;

プロシージャの出力引数は同様に返されます。以下に例を示します。

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

ヒント

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関数は集合を返すことができます。 このためには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;

複合型を返す例を示します。

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;