time=0.057..1286.455 rows=479829.00 loops=1)
Foreign File: /usr/share/dict/words
Foreign File Size: 4953699
Planning time: 0.128 ms
Execution time: 1431.679 ms
</programlisting>
Using the materialized view:
<programlisting>
Limit (cost=0.29..1.06 rows=10 width=10) (actual time=187.222..188.257 rows=10.00 loops=1)
-> Index Scan using wrd_trgm on wrd (cost=0.29..37020.87 rows=479829 width=10) (actual time=187.219..188.252 rows=10.00 loops=1)
Order By: (word <-> 'caterpiler'::text)
Index Searches: 1
Planning time: 0.196 ms
Execution time: 198.640 ms
</programlisting>
If you can tolerate periodic update of the remote data to the local
database, the performance benefit can be substantial.
</para>
</sect1>
<sect1 id="rules-update">
<title>Rules on <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command></title>
<indexterm zone="rules-update">
<primary>rule</primary>
<secondary sortas="INSERT">for INSERT</secondary>
</indexterm>
<indexterm zone="rules-update">
<primary>rule</primary>
<secondary sortas="UPDATE">for UPDATE</secondary>
</indexterm>
<indexterm zone="rules-update">
<primary>rule</primary>
<secondary sortas="DELETE">for DELETE</secondary>
</indexterm>
<para>
Rules that are defined on <command>INSERT</command>, <command>UPDATE</command>,
and <command>DELETE</command> are significantly different from the view rules
described in the previous sections. First, their <command>CREATE
RULE</command> command allows more:
<itemizedlist>
<listitem>
<para>
They are allowed to have no action.
</para>
</listitem>
<listitem>
<para>
They can have multiple actions.
</para>
</listitem>
<listitem>
<para>
They can be <literal>INSTEAD</literal> or <literal>ALSO</literal> (the default).
</para>
</listitem>
<listitem>
<para>
The pseudorelations <literal>NEW</literal> and <literal>OLD</literal> become useful.
</para>
</listitem>
<listitem>
<para>
They can have rule qualifications.
</para>
</listitem>
</itemizedlist>
Second, they don't modify the query tree in place. Instead they
create zero or more new query trees and can throw away the
original one.
</para>
<caution>
<para>
In many cases, tasks that could be performed by rules
on <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command> are better done
with triggers. Triggers are notationally a bit more complicated, but their
semantics are much simpler to understand. Rules tend to have surprising
results when the original query contains volatile functions: volatile
functions may get executed more times than expected in the process of
carrying out the rules.
</para>
<para>
Also, there are some cases that are not supported by these types of rules at
all, notably including <literal>WITH</literal> clauses in the original query and
multiple-assignment sub-<literal>SELECT</literal>s in the <literal>SET</literal> list
of <command>UPDATE</command> queries. This is because copying these constructs
into a rule query would result in multiple evaluations of the sub-query,
contrary to the express intent of the query's author.
</para>
</caution>
<sect2 id="rules-update-how">
<title>How Update Rules Work</title>
<para>
Keep the syntax:
<programlisting>
CREATE [ OR REPLACE ] RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable class="parameter">event</replaceable>
TO <replaceable class="parameter">table</replaceable> [ WHERE <replaceable class="parameter">condition</replaceable> ]
DO [ ALSO | INSTEAD ] { NOTHING | <replaceable class="parameter">command</replaceable> | ( <replaceable class="parameter">command</replaceable> ; <replaceable class="parameter">command</replaceable>