b, c</literal>, the join tree is just
a list of the <literal>FROM</literal> items, because we are allowed to join them in
any order. But when <literal>JOIN</literal> expressions, particularly outer joins,
are used, we have to join in the order shown by the joins.
In that case, the join tree shows the structure of the <literal>JOIN</literal> expressions. The
restrictions associated with particular <literal>JOIN</literal> clauses (from <literal>ON</literal> or
<literal>USING</literal> expressions) are stored as qualification expressions attached
to those join-tree nodes. It turns out to be convenient to store
the top-level <literal>WHERE</literal> expression as a qualification attached to the
top-level join-tree item, too. So really the join tree represents
both the <literal>FROM</literal> and <literal>WHERE</literal> clauses of a <command>SELECT</command>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
the others
</term>
<listitem>
<para>
The other parts of the query tree like the <literal>ORDER BY</literal>
clause aren't of interest here. The rule system
substitutes some entries there while applying rules, but that
doesn't have much to do with the fundamentals of the rule
system.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</sect1>
<sect1 id="rules-views">
<title>Views and the Rule System</title>
<indexterm zone="rules-views">
<primary>rule</primary>
<secondary>and views</secondary>
</indexterm>
<indexterm zone="rules-views">
<primary>view</primary>
<secondary>implementation through rules</secondary>
</indexterm>
<para>
Views in <productname>PostgreSQL</productname> are implemented
using the rule system. A view is basically an empty table (having no
actual storage) with an <literal>ON SELECT DO INSTEAD</literal> rule.
Conventionally, that rule is named <literal>_RETURN</literal>.
So a view like
<programlisting>
CREATE VIEW myview AS SELECT * FROM mytab;
</programlisting>
is very nearly the same thing as
<programlisting>
CREATE TABLE myview (<replaceable>same column list as mytab</replaceable>);
CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD
SELECT * FROM mytab;
</programlisting>
although you can't actually write that, because tables are not
allowed to have <literal>ON SELECT</literal> rules.
</para>
<para>
A view can also have other kinds of <literal>DO INSTEAD</literal>
rules, allowing <command>INSERT</command>, <command>UPDATE</command>,
or <command>DELETE</command> commands to be performed on the view
despite its lack of underlying storage.
This is discussed further below, in
<xref linkend="rules-views-update"/>.
</para>
<sect2 id="rules-select">
<title>How <command>SELECT</command> Rules Work</title>
<indexterm zone="rules-select">
<primary>rule</primary>
<secondary sortas="SELECT">for SELECT</secondary>
</indexterm>
<para>
Rules <literal>ON SELECT</literal> are applied to all queries as the last step, even
if the command given is an <command>INSERT</command>,
<command>UPDATE</command> or <command>DELETE</command>. And they
have different semantics from rules on the other command types in that they modify the
query tree in place instead of creating a new one. So
<command>SELECT</command> rules are described first.
</para>
<para>
Currently, there can be only one action in an <literal>ON SELECT</literal> rule, and it must
be an unconditional <command>SELECT</command> action that is <literal>INSTEAD</literal>. This restriction was
required to make rules safe enough to open them for ordinary users, and
it restricts <literal>ON SELECT</literal> rules to act like views.
</para>
<para>
The examples for this chapter are two join views that do some
calculations and some more views using them in