@@ -50,10 +50,10 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replac
5050<phrase>where <replaceable class="parameter">from_item</replaceable> can be one of:</phrase>
5151
5252 [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ] ]
53- ( <replaceable class="parameter">select</replaceable> ) [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ]
53+ [ LATERAL ] ( <replaceable class="parameter">select</replaceable> ) [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ]
5454 <replaceable class="parameter">with_query_name</replaceable> [ [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ] ]
55- <replaceable class="parameter">function_name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> [, ...] ] ) [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] | <replaceable class="parameter">column_definition</replaceable> [, ...] ) ]
56- <replaceable class="parameter">function_name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> [, ...] ] ) AS ( <replaceable class="parameter">column_definition</replaceable> [, ...] )
55+ [ LATERAL ] <replaceable class="parameter">function_name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> [, ...] ] ) [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] | <replaceable class="parameter">column_definition</replaceable> [, ...] ) ]
56+ [ LATERAL ] <replaceable class="parameter">function_name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> [, ...] ] ) AS ( <replaceable class="parameter">column_definition</replaceable> [, ...] )
5757 <replaceable class="parameter">from_item</replaceable> [ NATURAL ] <replaceable class="parameter">join_type</replaceable> <replaceable class="parameter">from_item</replaceable> [ ON <replaceable class="parameter">join_condition</replaceable> | USING ( <replaceable class="parameter">join_column</replaceable> [, ...] ) ]
5858
5959<phrase>and <replaceable class="parameter">with_query</replaceable> is:</phrase>
@@ -284,8 +284,8 @@ TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ]
284284 The <literal>FROM</literal> clause specifies one or more source
285285 tables for the <command>SELECT</command>. If multiple sources are
286286 specified, the result is the Cartesian product (cross join) of all
287- the sources. But usually qualification conditions
288- are added to restrict the returned rows to a small subset of the
287+ the sources. But usually qualification conditions are added (via
288+ <literal>WHERE</>) to restrict the returned rows to a small subset of the
289289 Cartesian product.
290290 </para>
291291
@@ -414,17 +414,18 @@ TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ]
414414 </para>
415415
416416 <para>
417- A <literal>JOIN</literal> clause combines two
418- <literal>FROM</> items. Use parentheses if necessary to
419- determine the order of nesting. In the absence of parentheses,
420- <literal>JOIN</literal>s nest left-to-right. In any case
421- <literal>JOIN</literal> binds more tightly than the commas
422- separating <literal>FROM</> items.
417+ A <literal>JOIN</literal> clause combines two <literal>FROM</>
418+ items, which for convenience we will refer to as <quote>tables</>,
419+ though in reality they can be any type of <literal>FROM</> item.
420+ Use parentheses if necessary to determine the order of nesting.
421+ In the absence of parentheses, <literal>JOIN</literal>s nest
422+ left-to-right. In any case <literal>JOIN</literal> binds more
423+ tightly than the commas separating <literal>FROM</>-list items.
423424 </para>
424425
425426 <para><literal>CROSS JOIN</> and <literal>INNER JOIN</literal>
426427 produce a simple Cartesian product, the same result as you get from
427- listing the two items at the top level of <literal>FROM</>,
428+ listing the two tables at the top level of <literal>FROM</>,
428429 but restricted by the join condition (if any).
429430 <literal>CROSS JOIN</> is equivalent to <literal>INNER JOIN ON
430431 (TRUE)</>, that is, no rows are removed by qualification.
@@ -449,7 +450,7 @@ TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ]
449450 joined rows, plus one row for each unmatched right-hand row
450451 (extended with nulls on the left). This is just a notational
451452 convenience, since you could convert it to a <literal>LEFT
452- OUTER JOIN</> by switching the left and right inputs .
453+ OUTER JOIN</> by switching the left and right tables .
453454 </para>
454455
455456 <para><literal>FULL OUTER JOIN</> returns all the joined rows, plus
@@ -495,6 +496,47 @@ TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ]
495496 </para>
496497 </listitem>
497498 </varlistentry>
499+
500+ <varlistentry>
501+ <term><literal>LATERAL</literal></term>
502+ <listitem>
503+ <para>The <literal>LATERAL</literal> key word can precede a
504+ sub-<command>SELECT</command> or function-call <literal>FROM</>
505+ item. This allows the sub-<command>SELECT</command> or function
506+ expression to refer to columns of <literal>FROM</> items that appear
507+ before it in the <literal>FROM</> list. (Without
508+ <literal>LATERAL</literal>, each <literal>FROM</> item is evaluated
509+ independently and so cannot cross-reference any other
510+ <literal>FROM</> item.) A <literal>LATERAL</literal> item can
511+ appear at top level in the <literal>FROM</> list, or within a
512+ <literal>JOIN</> tree; in the latter case it can also refer to any
513+ items that are on the left-hand side of a <literal>JOIN</> that it is
514+ on the right-hand side of.
515+ </para>
516+
517+ <para>
518+ When a <literal>FROM</> item contains <literal>LATERAL</literal>
519+ cross-references, evaluation proceeds as follows: for each row of the
520+ <literal>FROM</> item providing the cross-referenced column(s), or
521+ set of rows of multiple <literal>FROM</> items providing the
522+ columns, the <literal>LATERAL</literal> item is evaluated using that
523+ row or row set's values of the columns. The resulting row(s) are
524+ joined as usual with the rows they were computed from. This is
525+ repeated for each row or set of rows from the column source table(s).
526+ </para>
527+
528+ <para>
529+ The column source table(s) must be <literal>INNER</> or
530+ <literal>LEFT</> joined to the <literal>LATERAL</literal> item, else
531+ there would not be a well-defined set of rows from which to compute
532+ each set of rows for the <literal>LATERAL</literal> item. Thus,
533+ although a construct such as <literal><replaceable>X</> RIGHT JOIN
534+ LATERAL <replaceable>Y</></literal> is syntactically valid, it is
535+ not actually allowed for <replaceable>Y</> to reference
536+ <replaceable>X</>.
537+ </para>
538+ </listitem>
539+ </varlistentry>
498540 </variablelist>
499541 </para>
500542 </refsect2>
@@ -1532,6 +1574,26 @@ SELECT distance, employee_name FROM employee_recursive;
15321574 else the query will loop indefinitely. (See <xref linkend="queries-with">
15331575 for more examples.)
15341576 </para>
1577+
1578+ <para>
1579+ This example uses <literal>LATERAL</> to apply a set-returning function
1580+ <function>get_product_names()</> for each row of the
1581+ <structname>manufacturers</> table:
1582+
1583+ <programlisting>
1584+ SELECT m.name AS mname, pname
1585+ FROM manufacturers m, LATERAL get_product_names(m.id) pname;
1586+ </programlisting>
1587+
1588+ Manufacturers not currently having any products would not appear in the
1589+ result, since it is an inner join. If we wished to include the names of
1590+ such manufacturers in the result, we could do:
1591+
1592+ <programlisting>
1593+ SELECT m.name AS mname, pname
1594+ FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true;
1595+ </programlisting>
1596+ </para>
15351597 </refsect1>
15361598
15371599 <refsect1>
@@ -1611,6 +1673,20 @@ SELECT distributors.* WHERE distributors.name = 'Westward';
16111673 </para>
16121674 </refsect2>
16131675
1676+ <refsect2>
1677+ <title>Function Calls in <literal>FROM</literal></title>
1678+
1679+ <para>
1680+ <productname>PostgreSQL</productname> allows a function call to be
1681+ written directly as a member of the <literal>FROM</> list. In the SQL
1682+ standard it would be necessary to wrap such a function call in a
1683+ sub-<command>SELECT</command>; that is, the syntax
1684+ <literal>FROM <replaceable>func</>(...) <replaceable>alias</></literal>
1685+ is approximately equivalent to
1686+ <literal>FROM (SELECT <replaceable>func</>(...)) <replaceable>alias</></literal>.
1687+ </para>
1688+ </refsect2>
1689+
16141690 <refsect2>
16151691 <title>Namespace Available to <literal>GROUP BY</literal> and <literal>ORDER BY</literal></title>
16161692
0 commit comments