2 42.2. PL/Tcl Functions and Arguments #
4 To create a function in the PL/Tcl language, use the standard CREATE
6 CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$
10 PL/TclU is the same, except that the language has to be specified as
13 The body of the function is simply a piece of Tcl script. When the
14 function is called, the argument values are passed to the Tcl script as
15 variables named 1 ... n. The result is returned from the Tcl code in
16 the usual way, with a return statement. In a procedure, the return
17 value from the Tcl code is ignored.
19 For example, a function returning the greater of two integer values
21 CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
22 if {$1 > $2} {return $1}
24 $$ LANGUAGE pltcl STRICT;
26 Note the clause STRICT, which saves us from having to think about null
27 input values: if a null value is passed, the function will not be
28 called at all, but will just return a null result automatically.
30 In a nonstrict function, if the actual value of an argument is null,
31 the corresponding $n variable will be set to an empty string. To detect
32 whether a particular argument is null, use the function argisnull. For
33 example, suppose that we wanted tcl_max with one null and one nonnull
34 argument to return the nonnull argument, rather than null:
35 CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
37 if {[argisnull 2]} { return_null }
40 if {[argisnull 2]} { return $1 }
41 if {$1 > $2} {return $1}
45 As shown above, to return a null value from a PL/Tcl function, execute
46 return_null. This can be done whether the function is strict or not.
48 Composite-type arguments are passed to the function as Tcl arrays. The
49 element names of the array are the attribute names of the composite
50 type. If an attribute in the passed row has the null value, it will not
51 appear in the array. Here is an example:
52 CREATE TABLE employee (
58 CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
59 if {200000.0 < $1(salary)} {
62 if {$1(age) < 30 && 100000.0 < $1(salary)} {
68 PL/Tcl functions can return composite-type results, too. To do this,
69 the Tcl code must return a list of column name/value pairs matching the
70 expected result type. Any column names omitted from the list are
71 returned as nulls, and an error is raised if there are unexpected
72 column names. Here is an example:
73 CREATE FUNCTION square_cube(in int, out squared int, out cubed int) AS $$
74 return [list squared [expr {$1 * $1}] cubed [expr {$1 * $1 * $1}]]
77 Output arguments of procedures are returned in the same way, for
79 CREATE PROCEDURE tcl_triple(INOUT a integer, INOUT b integer) AS $$
80 return [list a [expr {$1 * 3}] b [expr {$2 * 3}]]
83 CALL tcl_triple(5, 10);
87 The result list can be made from an array representation of the desired
88 tuple with the array get Tcl command. For example:
89 CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$
90 set 1(salary) [expr {$1(salary) + $2}]
94 PL/Tcl functions can return sets. To do this, the Tcl code should call
95 return_next once per row to be returned, passing either the appropriate
96 value when returning a scalar type, or a list of column name/value
97 pairs when returning a composite type. Here is an example returning a
99 CREATE FUNCTION sequence(int, int) RETURNS SETOF int AS $$
100 for {set i $1} {$i < $2} {incr i} {
105 and here is one returning a composite type:
106 CREATE FUNCTION table_of_squares(int, int) RETURNS TABLE (x int, x2 int) AS $$
107 for {set i $1} {$i < $2} {incr i} {
108 return_next [list x $i x2 [expr {$i * $i}]]