Commit e1320266 authored by Tom Lane's avatar Tom Lane

Doc: improve documentation about composite-value usage.

Create a section specifically for the syntactic rules around whole-row
variable usage, such as expansion of "foo.*".  This was previously
documented only haphazardly, with some critical info buried in
unexpected places like xfunc-sql-composite-functions.  Per repeated
questions in different mailing lists.

Discussion: <16288.1479610770@sss.pgh.pa.us>
parent 9a1d0af4
...@@ -1457,7 +1457,8 @@ SELECT tbl1.a, tbl2.a, tbl1.b FROM ... ...@@ -1457,7 +1457,8 @@ SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
<programlisting> <programlisting>
SELECT tbl1.*, tbl2.a FROM ... SELECT tbl1.*, tbl2.a FROM ...
</programlisting> </programlisting>
(See also <xref linkend="queries-where">.) See <xref linkend="rowtypes-usage"> for more about
the <replaceable>table_name</><literal>.*</> notation.
</para> </para>
<para> <para>
......
This diff is collapsed.
...@@ -1449,12 +1449,13 @@ $1.somecolumn ...@@ -1449,12 +1449,13 @@ $1.somecolumn
</para> </para>
<para> <para>
In a select list (see <xref linkend="queries-select-lists">), you You can ask for all fields of a composite value by
can ask for all fields of a composite value by
writing <literal>.*</literal>: writing <literal>.*</literal>:
<programlisting> <programlisting>
(compositecol).* (compositecol).*
</programlisting> </programlisting>
This notation behaves differently depending on context;
see <xref linkend="rowtypes-usage"> for details.
</para> </para>
</sect2> </sect2>
...@@ -1531,7 +1532,7 @@ sqrt(2) ...@@ -1531,7 +1532,7 @@ sqrt(2)
interchangeable. This behavior is not SQL-standard but is provided interchangeable. This behavior is not SQL-standard but is provided
in <productname>PostgreSQL</> because it allows use of functions to in <productname>PostgreSQL</> because it allows use of functions to
emulate <quote>computed fields</>. For more information see emulate <quote>computed fields</>. For more information see
<xref linkend="xfunc-sql-composite-functions">. <xref linkend="rowtypes-usage">.
</para> </para>
</note> </note>
</sect2> </sect2>
...@@ -2291,7 +2292,8 @@ SELECT ROW(1,2.5,'this is a test'); ...@@ -2291,7 +2292,8 @@ SELECT ROW(1,2.5,'this is a test');
<replaceable>rowvalue</replaceable><literal>.*</literal>, <replaceable>rowvalue</replaceable><literal>.*</literal>,
which will be expanded to a list of the elements of the row value, which will be expanded to a list of the elements of the row value,
just as occurs when the <literal>.*</> syntax is used at the top level just as occurs when the <literal>.*</> syntax is used at the top level
of a <command>SELECT</> list. For example, if table <literal>t</> has of a <command>SELECT</> list (see <xref linkend="rowtypes-usage">).
For example, if table <literal>t</> has
columns <literal>f1</> and <literal>f2</>, these are the same: columns <literal>f1</> and <literal>f2</>, these are the same:
<programlisting> <programlisting>
SELECT ROW(t.*, 42) FROM t; SELECT ROW(t.*, 42) FROM t;
...@@ -2302,9 +2304,9 @@ SELECT ROW(t.f1, t.f2, 42) FROM t; ...@@ -2302,9 +2304,9 @@ SELECT ROW(t.f1, t.f2, 42) FROM t;
<note> <note>
<para> <para>
Before <productname>PostgreSQL</productname> 8.2, the Before <productname>PostgreSQL</productname> 8.2, the
<literal>.*</literal> syntax was not expanded, so that writing <literal>.*</literal> syntax was not expanded in row constructors, so
<literal>ROW(t.*, 42)</> created a two-field row whose first field that writing <literal>ROW(t.*, 42)</> created a two-field row whose first
was another row value. The new behavior is usually more useful. field was another row value. The new behavior is usually more useful.
If you need the old behavior of nested row values, write the inner If you need the old behavior of nested row values, write the inner
row value without <literal>.*</literal>, for instance row value without <literal>.*</literal>, for instance
<literal>ROW(t, 42)</>. <literal>ROW(t, 42)</>.
......
...@@ -394,8 +394,8 @@ SELECT name, double_salary(emp.*) AS dream ...@@ -394,8 +394,8 @@ SELECT name, double_salary(emp.*) AS dream
<para> <para>
Notice the use of the syntax <literal>$1.salary</literal> Notice the use of the syntax <literal>$1.salary</literal>
to select one field of the argument row value. Also notice to select one field of the argument row value. Also notice
how the calling <command>SELECT</> command uses <literal>*</> how the calling <command>SELECT</> command
to select uses <replaceable>table_name</><literal>.*</> to select
the entire current row of a table as a composite value. The table the entire current row of a table as a composite value. The table
row can alternatively be referenced using just the table name, row can alternatively be referenced using just the table name,
like this: like this:
...@@ -405,6 +405,8 @@ SELECT name, double_salary(emp) AS dream ...@@ -405,6 +405,8 @@ SELECT name, double_salary(emp) AS dream
WHERE emp.cubicle ~= point '(2,1)'; WHERE emp.cubicle ~= point '(2,1)';
</screen> </screen>
but this usage is deprecated since it's easy to get confused. but this usage is deprecated since it's easy to get confused.
(See <xref linkend="rowtypes-usage"> for details about these
two notations for the composite value of a table row.)
</para> </para>
<para> <para>
...@@ -479,7 +481,8 @@ $$ LANGUAGE SQL; ...@@ -479,7 +481,8 @@ $$ LANGUAGE SQL;
</para> </para>
<para> <para>
We could call this function directly in either of two ways: We could call this function directly either by using it in
a value expression:
<screen> <screen>
SELECT new_emp(); SELECT new_emp();
...@@ -487,7 +490,11 @@ SELECT new_emp(); ...@@ -487,7 +490,11 @@ SELECT new_emp();
new_emp new_emp
-------------------------- --------------------------
(None,1000.0,25,"(2,2)") (None,1000.0,25,"(2,2)")
</screen>
or by calling it as a table function:
<screen>
SELECT * FROM new_emp(); SELECT * FROM new_emp();
name | salary | age | cubicle name | salary | age | cubicle
...@@ -524,12 +531,7 @@ LINE 1: SELECT new_emp().name; ...@@ -524,12 +531,7 @@ LINE 1: SELECT new_emp().name;
</para> </para>
<para> <para>
Another option is to use Another option is to use functional notation for extracting an attribute:
functional notation for extracting an attribute. The simple way
to explain this is that we can use the
notations <literal><replaceable>attribute</>(<replaceable>table</>)</>
and <literal><replaceable>table</>.<replaceable>attribute</></>
interchangeably.
<screen> <screen>
SELECT name(new_emp()); SELECT name(new_emp());
...@@ -539,50 +541,10 @@ SELECT name(new_emp()); ...@@ -539,50 +541,10 @@ SELECT name(new_emp());
None None
</screen> </screen>
<screen> As explained in <xref linkend="rowtypes-usage">, the field notation and
-- This is the same as: functional notation are equivalent.
-- SELECT emp.name AS youngster FROM emp WHERE emp.age &lt; 30;
SELECT name(emp) AS youngster FROM emp WHERE age(emp) &lt; 30;
youngster
-----------
Sam
Andy
</screen>
</para> </para>
<tip>
<para>
The equivalence between functional notation and attribute notation
makes it possible to use functions on composite types to emulate
<quote>computed fields</>.
<indexterm>
<primary>computed field</primary>
</indexterm>
<indexterm>
<primary>field</primary>
<secondary>computed</secondary>
</indexterm>
For example, using the previous definition
for <literal>double_salary(emp)</>, we can write
<screen>
SELECT emp.name, emp.double_salary FROM emp;
</screen>
An application using this wouldn't need to be directly aware that
<literal>double_salary</> isn't a real column of the table.
(You can also emulate computed fields with views.)
</para>
<para>
Because of this behavior, it's unwise to give a function that takes
a single composite-type argument the same name as any of the fields of
that composite type.
</para>
</tip>
<para> <para>
Another way to use a function returning a composite type is to pass the Another way to use a function returning a composite type is to pass the
result to another function that accepts the correct row type as input: result to another function that accepts the correct row type as input:
...@@ -599,12 +561,6 @@ SELECT getname(new_emp()); ...@@ -599,12 +561,6 @@ SELECT getname(new_emp());
(1 row) (1 row)
</screen> </screen>
</para> </para>
<para>
Still another way to use a function that returns a composite type is to
call it as a table function, as described in <xref
linkend="xfunc-sql-table-functions">.
</para>
</sect2> </sect2>
<sect2 id="xfunc-output-parameters"> <sect2 id="xfunc-output-parameters">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment