Home Explore Blog CI



postgresql

13th chunk of `doc/src/sgml/xfunc.sgml`
12830b004c6af53ce12d4d5a6b1d94826906e5094b3f854e0000000100000fb6
 returning sets can also be called in the select list
     of a query.  For each row that the query
     generates by itself, the set-returning function is invoked, and an output
     row is generated for each element of the function's result set.
     The previous example could also be done with queries like
     these:

<screen>
SELECT listchildren('Top');
 listchildren
--------------
 Child1
 Child2
 Child3
(3 rows)

SELECT name, listchildren(name) FROM nodes;
  name  | listchildren
--------+--------------
 Top    | Child1
 Top    | Child2
 Top    | Child3
 Child1 | SubChild1
 Child1 | SubChild2
(5 rows)
</screen>

     In the last <command>SELECT</command>,
     notice that no output row appears for <literal>Child2</literal>, <literal>Child3</literal>, etc.
     This happens because <function>listchildren</function> returns an empty set
     for those arguments, so no result rows are generated.  This is the same
     behavior as we got from an inner join to the function result when using
     the <literal>LATERAL</literal> syntax.
    </para>

    <para>
     <productname>PostgreSQL</productname>'s behavior for a set-returning function in a
     query's select list is almost exactly the same as if the set-returning
     function had been written in a <literal>LATERAL FROM</literal>-clause item
     instead.  For example,
<programlisting>
SELECT x, generate_series(1,5) AS g FROM tab;
</programlisting>
     is almost equivalent to
<programlisting>
SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g;
</programlisting>
     It would be exactly the same, except that in this specific example,
     the planner could choose to put <structname>g</structname> on the outside of the
     nested-loop join, since <structname>g</structname> has no actual lateral dependency
     on <structname>tab</structname>.  That would result in a different output row
     order.  Set-returning functions in the select list are always evaluated
     as though they are on the inside of a nested-loop join with the rest of
     the <literal>FROM</literal> clause, so that the function(s) are run to
     completion before the next row from the <literal>FROM</literal> clause is
     considered.
    </para>

    <para>
     If there is more than one set-returning function in the query's select
     list, the behavior is similar to what you get from putting the functions
     into a single <literal>LATERAL ROWS FROM( ... )</literal> <literal>FROM</literal>-clause
     item.  For each row from the underlying query, there is an output row
     using the first result from each function, then an output row using the
     second result, and so on.  If some of the set-returning functions
     produce fewer outputs than others, null values are substituted for the
     missing data, so that the total number of rows emitted for one
     underlying row is the same as for the set-returning function that
     produced the most outputs.  Thus the set-returning functions
     run <quote>in lockstep</quote> until they are all exhausted, and then
     execution continues with the next underlying row.
    </para>

    <para>
     Set-returning functions can be nested in a select list, although that is
     not allowed in <literal>FROM</literal>-clause items.  In such cases, each level
     of nesting is treated separately, as though it were
     a separate <literal>LATERAL ROWS FROM( ... )</literal> item.  For example, in
<programlisting>
SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab;
</programlisting>
     the set-returning functions <function>srf2</function>, <function>srf3</function>,
     and <function>srf5</function> would be run in lockstep for each row
     of <structname>tab</structname>, and then <function>srf1</function> and <function>srf4</function>
     would be applied in lockstep to each row produced by the lower
     functions.
    </para>

    <para>
     Set-returning functions cannot be used within conditional-evaluation
     constructs, such as <literal>CASE</literal>

Title: Set-Returning Functions in Select Lists and Nested Calls
Summary
This section details the behavior of set-returning functions within a query's select list, explaining that each function invocation generates an output row for each element of its result set, analogous to a `LATERAL FROM` clause. It highlights that `PostgreSQL` treats multiple set-returning functions in the select list as if they were in a single `LATERAL ROWS FROM` clause, ensuring they run 'in lockstep'. If the functions produce different numbers of outputs, null values are substituted for missing data. The section also covers nested set-returning functions, where each level of nesting is treated as a separate `LATERAL ROWS FROM` item. Finally, it notes that set-returning functions cannot be used within conditional constructs like `CASE`.