42.2. Функции на PL/Tcl и их аргументы

Чтобы создать функцию на языке PL/Tcl, используйте стандартный синтаксис CREATE FUNCTION:

CREATE FUNCTION имя_функции (типы_аргументов) RETURNS тип_результата AS $$
    # Тело функции на PL/Tcl
$$ LANGUAGE pltcl;

С PL/TclU команда та же, но в качестве языка должно быть указано pltclu.

Тело функции содержит просто скрипт на Tcl. Когда вызывается функция, значения аргументов передаются скрипту Tcl в виде переменных $1 ... $n. Результат из кода Tcl возвращается как обычно, оператором return.

Например, функцию, возвращающую большее из двух целых чисел, можно определить так:

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

Обратите внимание на предложение STRICT, которое избавляет нас от необходимости думать о входящих значениях NULL: если при вызове передаётся значение NULL, функция не будет выполняться вовсе, будет сразу возвращён результат NULL.

В нестрогой функции, если фактическое значение аргумента — NULL, соответствующей переменной $n будет присвоена пустая строка. Чтобы определить, был ли передан NULL в определённом аргументе, используйте функцию argisnull. Например, предположим, что нам нужна функция tcl_max, которая с одним аргументом NULL и вторым аргументом не NULL должна возвращать не NULL, а второй аргумент:

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 в настоящее время не поддерживает полностью доменные типы: он воспринимает домен как нижележащий скалярный тип. Это означает, что ограничения, связанные с доменом, не будут действовать. Это не проблема для аргументов функции, но представляет опасность, когда функция PL/Tcl объявлена как возвращающая доменный тип.