composite type
created with <command>CREATE TYPE AS</command>. An explicit cast might be needed
to avoid ambiguity. For example:
<programlisting>
CREATE TABLE mytable(f1 int, f2 float, f3 text);
CREATE FUNCTION getf1(mytable) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
-- No cast needed since only one getf1() exists
SELECT getf1(ROW(1,2.5,'this is a test'));
getf1
-------
1
(1 row)
CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
CREATE FUNCTION getf1(myrowtype) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
-- Now we need a cast to indicate which function to call:
SELECT getf1(ROW(1,2.5,'this is a test'));
ERROR: function getf1(record) is not unique
SELECT getf1(ROW(1,2.5,'this is a test')::mytable);
getf1
-------
1
(1 row)
SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));
getf1
-------
11
(1 row)
</programlisting>
</para>
<para>
Row constructors can be used to build composite values to be stored
in a composite-type table column, or to be passed to a function that
accepts a composite parameter. Also, it is possible to test rows
using the standard comparison operators as described in <xref
linkend="functions-comparison"/>, to compare one row against another
as described in <xref linkend="functions-comparisons"/>, and to
use them in connection with subqueries, as discussed in <xref
linkend="functions-subquery"/>.
</para>
</sect2>
<sect2 id="syntax-express-eval">
<title>Expression Evaluation Rules</title>
<indexterm>
<primary>expression</primary>
<secondary>order of evaluation</secondary>
</indexterm>
<para>
The order of evaluation of subexpressions is not defined. In
particular, the inputs of an operator or function are not necessarily
evaluated left-to-right or in any other fixed order.
</para>
<para>
Furthermore, if the result of an expression can be determined by
evaluating only some parts of it, then other subexpressions
might not be evaluated at all. For instance, if one wrote:
<programlisting>
SELECT true OR somefunc();
</programlisting>
then <literal>somefunc()</literal> would (probably) not be called
at all. The same would be the case if one wrote:
<programlisting>
SELECT somefunc() OR true;
</programlisting>
Note that this is not the same as the left-to-right
<quote>short-circuiting</quote> of Boolean operators that is found
in some programming languages.
</para>
<para>
As a consequence, it is unwise to use functions with side effects
as part of complex expressions. It is particularly dangerous to
rely on side effects or evaluation order in <literal>WHERE</literal> and <literal>HAVING</literal> clauses,
since those clauses are extensively reprocessed as part of
developing an execution plan. Boolean
expressions (<literal>AND</literal>/<literal>OR</literal>/<literal>NOT</literal> combinations) in those clauses can be reorganized
in any manner allowed by the laws of Boolean algebra.
</para>
<para>
When it is essential to force evaluation order, a <literal>CASE</literal>
construct (see <xref linkend="functions-conditional"/>) can be
used. For example, this is an untrustworthy way of trying to
avoid division by zero in a <literal>WHERE</literal> clause:
<programlisting>
SELECT ... WHERE x > 0 AND y/x > 1.5;
</programlisting>
But this is safe:
<programlisting>
SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;
</programlisting>
A <literal>CASE</literal> construct used in this fashion will defeat optimization
attempts, so it should only be done when necessary. (In this particular
example, it would be better to sidestep the problem by writing
<literal>y > 1.5*x</literal> instead.)
</para>
<para>
<literal>CASE</literal> is not a cure-all for such issues, however.
One limitation of the technique illustrated above is that it does not
prevent