ranking INTEGER ) AS best_loser INNER JOIN product ON product.color = best_loser.best_color INNER JOIN sales_order_items ON product.id = sales_order_items.prod_id INNER JOIN sales_order ON sales_order_items.id = sales_order.id AND sales_order.order_date = best_loser.best_day ORDER BY best_loser.ranking ASC, product.id ASC; A procedure reference in a FROM clause is executed exactly once, and the result set is materialized exactly once, if that procedure has an empty argument list or only receives constant arguments. This can be bad news or good news depending on your needs. If the procedure returns a lot of unnecessary rows, the query processor wont optimize the call and performance may be worse for a procedure reference than, say, for the equivalent view reference or derived table if one could be defined. On the other hand, knowing that the procedure will def- initely be called exactly once, and the result set materialized, may help you solve some tricky problems. In this discussion, materialized means the result set is fully evaluated and stored in memory or in the temporary file if memory is exhausted. Also, con- stant argument means an argument that doesnt change in value while the FROM clause is evaluated; literals fall into that category, as do program vari- ables, and expressions involving literals and variables, but not references to columns in other tables in the FROM clause. The next section talks about a procedure that receives a variable argument; i.e., a column from another table in the FROM clause.
3.8 LATERAL Procedure Call
If a column from another table is passed as an argument to a procedure refer- ence in a FROM clause, that procedure reference must appear as part of a LATERAL derived table definition. Also, the other table must appear ahead of the LATERAL derived table definition and be separated from it by a comma rather than one of the join operators like INNER JOIN. This is a situation where the comma join operator must be used and the ON condition cannot be used. Here is the general syntax for a LATERAL derived table: <lateral_derived_table> ::= LATERAL <subquery> [ AS ] <correlation_name> [ <derived_column_name_list> ] | LATERAL "(" <table_expression> ")" [ AS ] <correlation_name> [ <derived_column_name_list> ] Here is the simplified syntax for a join between a table and a procedure refer- ence where a column from that table is passed as an argument; this is the only use of the comma join and the LATERAL keyword that is discussed in this book: