Home Explore Blog CI



postgresql

3rd chunk of `doc/src/sgml/pltcl.sgml`
572fdd088970a9c01710647bd543843ba6aed269d70471900000000100000fa0
 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:

<programlisting>
CREATE TABLE employee (
    name text,
    salary integer,
    age integer
);

CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
    if {200000.0 &lt; $1(salary)} {
        return "t"
    }
    if {$1(age) &lt; 30 &amp;&amp; 100000.0 &lt; $1(salary)} {
        return "t"
    }
    return "f"
$$ LANGUAGE pltcl;
</programlisting>
    </para>

    <para>
     PL/Tcl functions can return composite-type results, too.  To do this,
     the Tcl code must return a list of column name/value pairs matching
     the expected result type.  Any column names omitted from the list
     are returned as nulls, and an error is raised if there are unexpected
     column names.  Here is an example:

<programlisting>
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;
</programlisting>
    </para>

    <para>
     Output arguments of procedures are returned in the same way, for example:

<programlisting>
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);
</programlisting>
    </para>

    <tip>
     <para>
      The result list can be made from an array representation of the
      desired tuple with the <literal>array get</literal> Tcl command.  For example:

<programlisting>
CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$
    set 1(salary) [expr {$1(salary) + $2}]
    return [array get 1]
$$ LANGUAGE pltcl;
</programlisting>
     </para>
    </tip>

    <para>
     PL/Tcl functions can return sets.  To do this, the Tcl code should
     call <function>return_next</function> once per row to be returned,
     passing either the appropriate value when returning a scalar type,
     or a list of column name/value pairs when returning a composite type.
     Here is an example returning a scalar type:

<programlisting>
CREATE FUNCTION sequence(int, int) RETURNS SETOF int AS $$
    for {set i $1} {$i &lt; $2} {incr i} {
        return_next $i
    }
$$ LANGUAGE pltcl;
</programlisting>

     and here is one returning a composite type:

<programlisting>
CREATE FUNCTION table_of_squares(int, int) RETURNS TABLE (x int, x2 int) AS $$
    for {set i $1} {$i &lt; $2} {incr i} {
        return_next [list x $i x2 [expr {$i * $i}]]
    }
$$ LANGUAGE pltcl;
</programlisting>
    </para>

   </sect1>

   <sect1 id="pltcl-data">
    <title>Data Values in PL/Tcl</title>

    <para>
     The argument values supplied to a PL/Tcl function's code are simply
     the input arguments converted to text form (just as if they had been
     displayed by a <command>SELECT</command> statement).  Conversely, the
     <literal>return</literal> and <literal>return_next</literal> commands will accept
     any string that is acceptable input format for the function's declared
     result type, or for the specified column of a composite result type.
    </para>

   </sect1>

   <sect1 id="pltcl-global">
    <title>Global Data in PL/Tcl</title>

    <indexterm zone="pltcl-global">
     <primary>global data</primary>
     <secondary>in PL/Tcl</secondary>
    </indexterm>

    <para>
     Sometimes it
     is useful to have some global data that is held between two
     calls to a function or is shared between different functions.
     This is easily done in PL/Tcl, but there are some restrictions that
     must be understood.
    </para>

    <para>
     For security reasons, PL/Tcl executes functions called by any one SQL
     role in a separate Tcl interpreter for that role.  This prevents
     accidental or malicious interference by one user with the behavior of
     another user's PL/Tcl functions.  Each such interpreter will have its own
     values for

Title: PL/Tcl: Composite Types, Output Arguments, Returning Sets, and Data Values
Summary
This section describes how PL/Tcl functions handle composite-type results and output arguments by returning lists of column name/value pairs. It demonstrates returning sets using the `return_next` function for both scalar and composite types. It also explains that argument values are converted to text form and that the `return` commands accept any string acceptable for the declared result type. Finally, it introduces global data and Tcl interpreters for security reasons.