Home Explore Blog CI



postgresql

32th chunk of `doc/src/sgml/syntax.sgml`
c252da7c251c5923ec17123f8c9912a5bd62f3f48d53f0730000000100000fa1
 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 &gt; 0 AND y/x &gt; 1.5;
</programlisting>
    But this is safe:
<programlisting>
SELECT ... WHERE CASE WHEN x &gt; 0 THEN y/x &gt; 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 &gt; 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

Title: Row Constructor Usage and Expression Evaluation
Summary
This section continues discussing row constructors, explaining that they can be used to store composite values in table columns or pass them to functions. It also mentions that rows can be compared and used in subqueries. Then, the section shifts to expression evaluation rules, emphasizing that the evaluation order of subexpressions is undefined and short-circuiting behavior (as found in some programming languages) is not guaranteed. It advises against using functions with side effects in complex expressions, especially in WHERE and HAVING clauses. A CASE construct can be used to force evaluation order, but it can hinder optimization. However, even CASE is not a cure-all for all issues related to expression evaluation.