<para>
You can create the illusion of an updatable view by defining
<literal>ON INSERT</literal>, <literal>ON UPDATE</literal>, and
<literal>ON DELETE</literal> rules (or any subset of those that's
sufficient for your purposes) to replace update actions on the view
with appropriate updates on other tables. If you want to support
<command>INSERT RETURNING</command> and so on, then be sure to put a suitable
<literal>RETURNING</literal> clause into each of these rules.
</para>
<para>
There is a catch if you try to use conditional rules for complex view
updates: there <emphasis>must</emphasis> be an unconditional
<literal>INSTEAD</literal> rule for each action you wish to allow
on the view. If the rule is conditional, or is not
<literal>INSTEAD</literal>, then the system will still reject
attempts to perform the update action, because it thinks it might
end up trying to perform the action on the dummy table of the view
in some cases. If you want to handle all the useful cases in
conditional rules, add an unconditional <literal>DO
INSTEAD NOTHING</literal> rule to ensure that the system
understands it will never be called on to update the dummy table.
Then make the conditional rules non-<literal>INSTEAD</literal>; in
the cases where they are applied, they add to the default
<literal>INSTEAD NOTHING</literal> action. (This method does not
currently work to support <literal>RETURNING</literal> queries, however.)
</para>
<note>
<para>
A view that is simple enough to be automatically updatable (see <xref
linkend="sql-createview"/>) does not require a user-created rule in
order to be updatable. While you can create an explicit rule anyway,
the automatic update transformation will generally outperform an
explicit rule.
</para>
<para>
Another alternative worth considering is to use <literal>INSTEAD OF</literal>
triggers (see <xref linkend="sql-createtrigger"/>) in place of rules.
</para>
</note>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
The name of a rule to create. This must be distinct from the
name of any other rule for the same table. Multiple rules on
the same table and same event type are applied in alphabetical
name order.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">event</replaceable></term>
<listitem>
<para>
The event is one of <literal>SELECT</literal>,
<literal>INSERT</literal>, <literal>UPDATE</literal>, or
<literal>DELETE</literal>. Note that an
<command>INSERT</command> containing an <literal>ON
CONFLICT</literal> clause cannot be used on tables that have
either <literal>INSERT</literal> or <literal>UPDATE</literal>
rules. Consider using an updatable view instead.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">table_name</replaceable></term>
<listitem>
<para>
The name (optionally schema-qualified) of the table or view the
rule applies to.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">condition</replaceable></term>
<listitem>
<para>
Any <acronym>SQL</acronym> conditional expression (returning
<type>boolean</type>). The condition expression cannot refer
to any tables except <literal>NEW</literal> and <literal>OLD</literal>, and
cannot contain aggregate functions.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>INSTEAD</option></term>
<listitem>
<para><literal>INSTEAD</literal> indicates that the commands should be
executed <emphasis>instead of</emphasis> the original command.
</para>
</listitem>