<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.