Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f13a127

Browse files
committed
Doc: improve documentation of new SRF-in-tlist behavior.
Correct a misstatement about how things used to work: we did allow nested SRFs before, as long as no function had more than one set-returning input. Also, attempt to document the fact that the new implementation changes the behavior for SRFs within conditional constructs (eg CASE): the conditional construct no longer gates whether the SRF is run, and thus cannot affect the number of rows emitted. We might want to change this behavior, but first it behooves us to see if we can explain it. Minor other wordsmithing on what I wrote yesterday, too. Discussion: https://postgr.es/m/20170118214702.54b2mdbxce5piwv5@alap3.anarazel.de
1 parent 69f4b9c commit f13a127

File tree

1 file changed

+47
-10
lines changed

1 file changed

+47
-10
lines changed

doc/src/sgml/xfunc.sgml

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ SELECT name, listchildren(name) FROM nodes;
998998
</para>
999999

10001000
<para>
1001-
If there is more than one set-returning function in the same select
1001+
If there is more than one set-returning function in the query's select
10021002
list, the behavior is similar to what you get from putting the functions
10031003
into a single <literal>LATERAL ROWS FROM( ... )</> <literal>FROM</>-clause
10041004
item. For each row from the underlying query, there is an output row
@@ -1007,21 +1007,53 @@ SELECT name, listchildren(name) FROM nodes;
10071007
produce fewer outputs than others, null values are substituted for the
10081008
missing data, so that the total number of rows emitted for one
10091009
underlying row is the same as for the set-returning function that
1010-
produced the most outputs.
1010+
produced the most outputs. Thus the set-returning functions
1011+
run <quote>in lockstep</> until they are all exhausted, and then
1012+
execution continues with the next underlying row.
10111013
</para>
10121014

10131015
<para>
10141016
Set-returning functions can be nested in a select list, although that is
10151017
not allowed in <literal>FROM</>-clause items. In such cases, each level
10161018
of nesting is treated separately, as though it were
1017-
another <literal>LATERAL ROWS FROM( ... )</> item. For example, in
1019+
a separate <literal>LATERAL ROWS FROM( ... )</> item. For example, in
10181020
<programlisting>
1019-
SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM ...
1021+
SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab;
10201022
</programlisting>
10211023
the set-returning functions <function>srf2</>, <function>srf3</>,
1022-
and <function>srf5</> would be run in lockstep for each row of the
1023-
underlying query, and then <function>srf1</> and <function>srf4</> would
1024-
be applied in lockstep to each row produced by the lower functions.
1024+
and <function>srf5</> would be run in lockstep for each row
1025+
of <structname>tab</>, and then <function>srf1</> and <function>srf4</>
1026+
would be applied in lockstep to each row produced by the lower
1027+
functions.
1028+
</para>
1029+
1030+
<para>
1031+
This behavior also means that set-returning functions will be evaluated
1032+
even when it might appear that they should be skipped because of a
1033+
conditional-evaluation construct, such as <literal>CASE</>
1034+
or <literal>COALESCE</>. For example, consider
1035+
<programlisting>
1036+
SELECT x, CASE WHEN x &gt; 0 THEN generate_series(1, 5) ELSE 0 END FROM tab;
1037+
</programlisting>
1038+
It might seem that this should produce five repetitions of input
1039+
rows that have <literal>x &gt; 0</>, and a single repetition of those
1040+
that do not; but actually it will produce five repetitions of every
1041+
input row. This is because <function>generate_series()</> is run first,
1042+
and then the <literal>CASE</> expression is applied to its result rows.
1043+
The behavior is thus comparable to
1044+
<programlisting>
1045+
SELECT x, CASE WHEN x &gt; 0 THEN g ELSE 0 END
1046+
FROM tab, LATERAL generate_series(1,5) AS g;
1047+
</programlisting>
1048+
It would be exactly the same, except that in this specific example,
1049+
the planner could choose to put <structname>g</> on the outside of the
1050+
nestloop join, since <structname>g</> has no actual lateral dependency
1051+
on <structname>tab</>. That would result in a different output row
1052+
order. Set-returning functions in the select list are always evaluated
1053+
as though they are on the inside of a nestloop join with the rest of
1054+
the <literal>FROM</> clause, so that the function(s) are run to
1055+
completion before the next row from the <literal>FROM</> clause is
1056+
considered.
10251057
</para>
10261058

10271059
<note>
@@ -1043,9 +1075,14 @@ SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM ...
10431075
sensibly unless they always produced equal numbers of rows. Otherwise,
10441076
what you got was a number of output rows equal to the least common
10451077
multiple of the numbers of rows produced by the set-returning
1046-
functions. Furthermore, nested set-returning functions did not work at
1047-
all. Use of the <literal>LATERAL</> syntax is recommended when writing
1048-
queries that need to work in older <productname>PostgreSQL</> versions.
1078+
functions. Also, nested set-returning functions did not work as
1079+
described above; instead, a set-returning function could have at most
1080+
one set-returning argument, and each nest of set-returning functions
1081+
was run independently. The behavior for conditional execution
1082+
(set-returning functions inside <literal>CASE</> etc) was different too.
1083+
Use of the <literal>LATERAL</> syntax is recommended when writing
1084+
queries that need to work in older <productname>PostgreSQL</> versions,
1085+
because that will give consistent results across different versions.
10491086
</para>
10501087
</note>
10511088
</sect2>

0 commit comments

Comments
 (0)