Home Explore Blog CI



postgresql

11th chunk of `doc/src/sgml/rules.sgml`
7331ecaa582737513a947046ac6fb9b52ef7727af358698f0000000100000fa0
 <command>SELECT</command> from one view created a final
    query tree that is a join of 4 tables (<literal>unit</literal> was used twice with
    different names).
</para>

<para>
    The benefit of implementing views with the rule system is
    that the planner has all
    the information about which tables have to be scanned plus the
    relationships between these tables plus the restrictive
    qualifications from the views plus the qualifications from
    the original query
    in one single query tree. And this is still the situation
    when the original query is already a join over views.
    The planner has to decide which is
    the best path to execute the query, and the more information
    the planner has, the better this decision can be. And
    the rule system as implemented in <productname>PostgreSQL</productname>
    ensures that this is all information available about the query
    up to that point.
</para>
</sect2>

<sect2 id="rules-views-update">
<title>Updating a View</title>

<para>
    What happens if a view is named as the target relation for an
    <command>INSERT</command>, <command>UPDATE</command>,
    <command>DELETE</command>, or <command>MERGE</command>?  Doing the
    substitutions described above would give a query tree in which the result
    relation points at a subquery range-table entry, which will not
    work.  There are several ways in which <productname>PostgreSQL</productname>
    can support the appearance of updating a view, however.
    In order of user-experienced complexity those are: automatically substitute
    in the underlying table for the view, execute a user-defined trigger,
    or rewrite the query per a user-defined rule.
    These options are discussed below.
</para>

<para>
    If the subquery selects from a single base relation and is simple
    enough, the rewriter can automatically replace the subquery with the
    underlying base relation so that the <command>INSERT</command>,
    <command>UPDATE</command>, <command>DELETE</command>, or
    <command>MERGE</command> is applied to the base relation in the
    appropriate way.  Views that are <quote>simple enough</quote> for this
    are called <firstterm>automatically updatable</firstterm>.  For detailed
    information on the kinds of view that can be automatically updated, see
    <xref linkend="sql-createview"/>.
</para>

<para>
    Alternatively, the operation may be handled by a user-provided
    <literal>INSTEAD OF</literal> trigger on the view
    (see <xref linkend="sql-createtrigger"/>).
    Rewriting works slightly differently
    in this case.  For <command>INSERT</command>, the rewriter does
    nothing at all with the view, leaving it as the result relation
    for the query.  For <command>UPDATE</command>, <command>DELETE</command>,
    and <command>MERGE</command>, it's still necessary to expand the
    view query to produce the <quote>old</quote> rows that the command will
    attempt to update, delete, or merge.  So the view is expanded as normal,
    but another unexpanded range-table entry is added to the query
    to represent the view in its capacity as the result relation.
</para>

<para>
    The problem that now arises is how to identify the rows to be
    updated in the view. Recall that when the result relation
    is a table, a special <acronym>CTID</acronym> entry is added to the target
    list to identify the physical locations of the rows to be updated.
    This does not work if the result relation is a view, because a view
    does not have any <acronym>CTID</acronym>, since its rows do not have
    actual physical locations. Instead, for an <command>UPDATE</command>,
    <command>DELETE</command>, or <command>MERGE</command> operation, a
    special <literal>wholerow</literal> entry is added to the target list,
    which expands to include all columns from the view. The executor uses this
    value to supply the <quote>old</quote> row to the
    <literal>INSTEAD OF</literal> trigger. 

Title: Updating Views in PostgreSQL
Summary
This section discusses how PostgreSQL handles updates to views, including automatic substitution of the underlying table, user-defined triggers, and query rewriting. It explains the concept of 'automatically updatable' views and how the rewriter expands the view query to produce the old rows that the command will attempt to update, delete, or merge. The section also touches on the use of special entries, such as CTID and wholerow, to identify the rows to be updated in the view.