<para>
Now we make a final demonstration of the
<productname>PostgreSQL</productname> rule system and its power.
Say you add some shoelaces with extraordinary colors to your
database:
<programlisting>
INSERT INTO shoelace VALUES ('sl9', 0, 'pink', 35.0, 'inch', 0.0);
INSERT INTO shoelace VALUES ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0);
</programlisting>
We would like to make a view to check which
<literal>shoelace</literal> entries do not fit any shoe in color.
The view for this is:
<programlisting>
CREATE VIEW shoelace_mismatch AS
SELECT * FROM shoelace WHERE NOT EXISTS
(SELECT shoename FROM shoe WHERE slcolor = sl_color);
</programlisting>
Its output is:
<programlisting>
SELECT * FROM shoelace_mismatch;
sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
---------+----------+----------+--------+---------+-----------
sl9 | 0 | pink | 35 | inch | 88.9
sl10 | 1000 | magenta | 40 | inch | 101.6
</programlisting>
</para>
<para>
Now we want to set it up so that mismatching shoelaces that are
not in stock are deleted from the database.
To make it a little harder for <productname>PostgreSQL</productname>,
we don't delete it directly. Instead we create one more view:
<programlisting>
CREATE VIEW shoelace_can_delete AS
SELECT * FROM shoelace_mismatch WHERE sl_avail = 0;
</programlisting>
and do it this way:
<programlisting>
DELETE FROM shoelace WHERE EXISTS
(SELECT * FROM shoelace_can_delete
WHERE sl_name = shoelace.sl_name);
</programlisting>
The results are:
<programlisting>
SELECT * FROM shoelace;
sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
---------+----------+----------+--------+---------+-----------
sl1 | 5 | black | 80 | cm | 80
sl2 | 6 | black | 100 | cm | 100
sl7 | 6 | brown | 60 | cm | 60
sl4 | 8 | black | 40 | inch | 101.6
sl3 | 10 | black | 35 | inch | 88.9
sl8 | 21 | brown | 40 | inch | 101.6
sl10 | 1000 | magenta | 40 | inch | 101.6
sl5 | 4 | brown | 1 | m | 100
sl6 | 20 | brown | 0.9 | m | 90
(9 rows)
</programlisting>
</para>
<para>
A <command>DELETE</command> on a view, with a subquery qualification that
in total uses 4 nesting/joined views, where one of them
itself has a subquery qualification containing a view
and where calculated view columns are used,
gets rewritten into
one single query tree that deletes the requested data
from a real table.
</para>
<para>
There are probably only a few situations out in the real world
where such a construct is necessary. But it makes you feel
comfortable that it works.
</para>
</sect2>
</sect1>
<sect1 id="rules-privileges">
<title>Rules and Privileges</title>
<indexterm zone="rules-privileges">
<primary>privilege</primary>
<secondary sortas="Regeln">with rules</secondary>
</indexterm>
<indexterm zone="rules-privileges">
<primary>privilege</primary>
<secondary sortas="Sichten">with views</secondary>
</indexterm>
<para>
Due to rewriting of queries by the <productname>PostgreSQL</productname>
rule system, other tables/views than those used in the original
query get accessed. When update rules are used, this can include write access
to tables.
</para>
<para>
Rewrite rules don't have a separate owner. The owner of
a relation (table or view) is automatically the owner of the
rewrite rules that are defined for it.
The <productname>PostgreSQL</productname> rule system changes the
behavior of the default access control system. With the exception of
<literal>SELECT</literal> rules associated with security invoker views
(see <link linkend="sql-createview"><command>CREATE