To create a function in the PL/Tcl language, use
the standard CREATE FUNCTION syntax:
CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$
# PL/Tcl function body
$$ LANGUAGE pltcl;
PL/TclU is the same, except that the language has to be specified as
pltclu.
The body of the function is simply a piece of Tcl script.
When the function is called, the argument values are passed as
variables $1 ... $n to the
Tcl script. The result is returned
from the Tcl code in the usual way, with a return
statement.
For example, a function
returning the greater of two integer values could be defined as:
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl STRICT;
Note the clause STRICT, 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.
In a nonstrict function,
if the actual value of an argument is null, the corresponding
$n variable will be set to an empty string.
To detect whether a particular argument is null, use the function
argisnull. For example, suppose that we wanted tcl_max
with one null and one nonnull argument to return the nonnull
argument, rather than 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;
As shown above,
to return a null value from a PL/Tcl function, execute
return_null. This can be done whether the
function is strict or not.
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:
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;
There is currently no support for returning a composite-type
result value, nor for returning sets.
PL/Tcl does not currently have full support for
domain types: it treats a domain the same as the underlying scalar
type. This means that constraints associated with the domain will
not be enforced. This is not an issue for function arguments, but
it is a hazard if you declare a PL/Tcl function
as returning a domain type.