Home Explore Blog CI



postgresql

4th chunk of `doc/src/sgml/rowtypes.sgml`
baa74bc30f7697a139eec9a6848aca2bd59ff6b4011bc1e50000000100000fa3

<programlisting>
SELECT c FROM inventory_item c;
</programlisting>
   This query produces a single composite-valued column, so we might get
   output like:
<programlisting>
           c
------------------------
 ("fuzzy dice",42,1.99)
(1 row)
</programlisting>
   Note however that simple names are matched to column names before table
   names, so this example works only because there is no column
   named <structfield>c</structfield> in the query's tables.
  </para>

  <para>
   The ordinary qualified-column-name
   syntax <replaceable>table_name</replaceable><literal>.</literal><replaceable>column_name</replaceable>
   can be understood as applying <link linkend="field-selection">field
   selection</link> to the composite value of the table's current row.
   (For efficiency reasons, it's not actually implemented that way.)
  </para>

  <para>
   When we write
<programlisting>
SELECT c.* FROM inventory_item c;
</programlisting>
   then, according to the SQL standard, we should get the contents of the
   table expanded into separate columns:
<programlisting>
    name    | supplier_id | price
------------+-------------+-------
 fuzzy dice |          42 |  1.99
(1 row)
</programlisting>
   as if the query were
<programlisting>
SELECT c.name, c.supplier_id, c.price FROM inventory_item c;
</programlisting>
   <productname>PostgreSQL</productname> will apply this expansion behavior to
   any composite-valued expression, although as shown <link
   linkend="rowtypes-accessing">above</link>, you need to write parentheses
   around the value that <literal>.*</literal> is applied to whenever it's not a
   simple table name.  For example, if <function>myfunc()</function> is a function
   returning a composite type with columns <structfield>a</structfield>,
   <structfield>b</structfield>, and <structfield>c</structfield>, then these two queries have the
   same result:
<programlisting>
SELECT (myfunc(x)).* FROM some_table;
SELECT (myfunc(x)).a, (myfunc(x)).b, (myfunc(x)).c FROM some_table;
</programlisting>
  </para>

  <tip>
   <para>
    <productname>PostgreSQL</productname> handles column expansion by
    actually transforming the first form into the second.  So, in this
    example, <function>myfunc()</function> would get invoked three times per row
    with either syntax.  If it's an expensive function you may wish to
    avoid that, which you can do with a query like:
<programlisting>
SELECT m.* FROM some_table, LATERAL myfunc(x) AS m;
</programlisting>
    Placing the function in
    a <literal>LATERAL</literal> <literal>FROM</literal> item keeps it from
    being invoked more than once per row.  <literal>m.*</literal> is still
    expanded into <literal>m.a, m.b, m.c</literal>, but now those variables
    are just references to the output of the <literal>FROM</literal> item.
    (The <literal>LATERAL</literal> keyword is optional here, but we show it
    to clarify that the function is getting <structfield>x</structfield>
    from <structname>some_table</structname>.)
   </para>
  </tip>

  <para>
   The <replaceable>composite_value</replaceable><literal>.*</literal> syntax results in
   column expansion of this kind when it appears at the top level of
   a <link linkend="queries-select-lists"><command>SELECT</command> output
   list</link>, a <link linkend="dml-returning"><literal>RETURNING</literal>
   list</link> in <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>/<command>MERGE</command>,
   a <link linkend="queries-values"><literal>VALUES</literal> clause</link>, or
   a <link linkend="sql-syntax-row-constructors">row constructor</link>.
   In all other contexts (including when nested inside one of those
   constructs), attaching <literal>.*</literal> to a composite value does not
   change the value, since it means <quote>all columns</quote> and so the
   same composite value is produced again.  For example,
   if <function>somefunc()</function> accepts a composite-valued argument,
   these queries

Title: Composite Types in PostgreSQL Queries
Summary
This section explains how composite types are handled in PostgreSQL queries. It demonstrates how to select entire composite columns and how the '*' notation expands composite values into separate columns. The text covers the behavior of qualified column names with composite types and how PostgreSQL applies expansion to composite-valued expressions. It also includes a tip on using LATERAL to optimize function calls when expanding composite columns. The section concludes by explaining the contexts where '.*' syntax results in column expansion and where it doesn't change the composite value.