]> begriffs open source - ai-pg/blob - full-docs/txt/pltcl-functions.txt
Convert HTML docs to more streamlined TXT
[ai-pg] / full-docs / txt / pltcl-functions.txt
1
2 42.2. PL/Tcl Functions and Arguments #
3
4    To create a function in the PL/Tcl language, use the standard CREATE
5    FUNCTION syntax:
6 CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$
7     # PL/Tcl function body
8 $$ LANGUAGE pltcl;
9
10    PL/TclU is the same, except that the language has to be specified as
11    pltclu.
12
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.
18
19    For example, a function returning the greater of two integer values
20    could be defined as:
21 CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
22     if {$1 > $2} {return $1}
23     return $2
24 $$ LANGUAGE pltcl STRICT;
25
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.
29
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 $$
36     if {[argisnull 1]} {
37         if {[argisnull 2]} { return_null }
38         return $2
39     }
40     if {[argisnull 2]} { return $1 }
41     if {$1 > $2} {return $1}
42     return $2
43 $$ LANGUAGE pltcl;
44
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.
47
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 (
53     name text,
54     salary integer,
55     age integer
56 );
57
58 CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
59     if {200000.0 < $1(salary)} {
60         return "t"
61     }
62     if {$1(age) < 30 && 100000.0 < $1(salary)} {
63         return "t"
64     }
65     return "f"
66 $$ LANGUAGE pltcl;
67
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}]]
75 $$ LANGUAGE pltcl;
76
77    Output arguments of procedures are returned in the same way, for
78    example:
79 CREATE PROCEDURE tcl_triple(INOUT a integer, INOUT b integer) AS $$
80     return [list a [expr {$1 * 3}] b [expr {$2 * 3}]]
81 $$ LANGUAGE pltcl;
82
83 CALL tcl_triple(5, 10);
84
85 Tip
86
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}]
91     return [array get 1]
92 $$ LANGUAGE pltcl;
93
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
98    scalar type:
99 CREATE FUNCTION sequence(int, int) RETURNS SETOF int AS $$
100     for {set i $1} {$i < $2} {incr i} {
101         return_next $i
102     }
103 $$ LANGUAGE pltcl;
104
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}]]
109     }
110 $$ LANGUAGE pltcl;