Home Explore Blog CI



postgresql

6th chunk of `doc/src/sgml/xfunc.sgml`
568431841a3ba6867615d3ae2b0b4ed97f999f1d08b4e2890000000100000fa7
 explicit cast.
     For example, suppose we wanted the
     previous <function>add_em</function> function to return
     type <type>float8</type> instead.  It's sufficient to write

<programlisting>
CREATE FUNCTION add_em(integer, integer) RETURNS float8 AS $$
    SELECT $1 + $2;
$$ LANGUAGE SQL;
</programlisting>

     since the <type>integer</type> sum can be implicitly cast
     to <type>float8</type>.
     (See <xref linkend="typeconv"/> or <xref linkend="sql-createcast"/>
     for more about casts.)
    </para>
   </sect2>

   <sect2 id="xfunc-sql-composite-functions">
    <title><acronym>SQL</acronym> Functions on Composite Types</title>

    <para>
     When writing functions with arguments of composite types, we must not
     only specify which argument we want but also the desired attribute
     (field) of that argument.  For example, suppose that
     <type>emp</type> is a table containing employee data, and therefore
     also the name of the composite type of each row of the table.  Here
     is a function <function>double_salary</function> that computes what someone's
     salary would be if it were doubled:

<screen>
CREATE TABLE emp (
    name        text,
    salary      numeric,
    age         integer,
    cubicle     point
);

INSERT INTO emp VALUES ('Bill', 4200, 45, '(2,1)');

CREATE FUNCTION double_salary(emp) RETURNS numeric AS $$
    SELECT $1.salary * 2 AS salary;
$$ LANGUAGE SQL;

SELECT name, double_salary(emp.*) AS dream
    FROM emp
    WHERE emp.cubicle ~= point '(2,1)';

 name | dream
------+-------
 Bill |  8400
</screen>
    </para>

    <para>
     Notice the use of the syntax <literal>$1.salary</literal>
     to select one field of the argument row value.  Also notice
     how the calling <command>SELECT</command> command
     uses <replaceable>table_name</replaceable><literal>.*</literal> to select
     the entire current row of a table as a composite value.  The table
     row can alternatively be referenced using just the table name,
     like this:
<screen>
SELECT name, double_salary(emp) AS dream
    FROM emp
    WHERE emp.cubicle ~= point '(2,1)';
</screen>
     but this usage is deprecated since it's easy to get confused.
     (See <xref linkend="rowtypes-usage"/> for details about these
     two notations for the composite value of a table row.)
    </para>

    <para>
     Sometimes it is handy to construct a composite argument value
     on-the-fly.  This can be done with the <literal>ROW</literal> construct.
     For example, we could adjust the data being passed to the function:
<screen>
SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream
    FROM emp;
</screen>
    </para>

    <para>
     It is also possible to build a function that returns a composite type.
     This is an example of a function
     that returns a single <type>emp</type> row:

<programlisting>
CREATE FUNCTION new_emp() RETURNS emp AS $$
    SELECT text 'None' AS name,
        1000.0 AS salary,
        25 AS age,
        point '(2,2)' AS cubicle;
$$ LANGUAGE SQL;
</programlisting>

     In this example we have specified each of  the  attributes
     with  a  constant value, but any computation
     could have been substituted for these constants.
    </para>

    <para>
     Note two important things about defining the function:

     <itemizedlist>
      <listitem>
       <para>
        The select list order in the query must be exactly the same as
        that in which the columns appear in the composite type.
        (Naming the columns, as we did above,
        is irrelevant to the system.)
       </para>
      </listitem>
      <listitem>
       <para>
        We must ensure each expression's type can be cast to that of
        the corresponding column of the composite type.
        Otherwise we'll get errors like this:
<screen>
<computeroutput>
ERROR:  return type mismatch in function declared to return emp
DETAIL:  Final statement returns text instead of point at column 4.
</computeroutput>

Title: SQL Functions on Composite Types: Accessing and Returning Composite Data
Summary
This section details how to work with composite types in SQL functions. It explains how to access specific fields of composite type arguments using the `$1.field` syntax, illustrated with an example of doubling an employee's salary. The use of `table_name.*` to pass an entire row as a composite value is demonstrated. It also shows how to construct composite argument values on-the-fly using the `ROW` construct. Furthermore, the section covers creating functions that return composite types, emphasizing the importance of matching the select list order with the column order in the composite type and ensuring type compatibility.