is not marked
<literal>LEAKPROOF</literal>. The <xref linkend="app-psql"/> program's
<command><link linkend="app-psql-meta-command-dao">\dAo+</link></command>
meta-command is useful to list operator families and determine which of
their operators are marked as leakproof.
</para>
<para>
It is important to understand that even a view created with the
<literal>security_barrier</literal> option is intended to be secure only
in the limited sense that the contents of the invisible tuples will not be
passed to possibly-insecure functions. The user may well have other means
of making inferences about the unseen data; for example, they can see the
query plan using <command>EXPLAIN</command>, or measure the run time of
queries against the view. A malicious attacker might be able to infer
something about the amount of unseen data, or even gain some information
about the data distribution or most common values (since these things may
affect the run time of the plan; or even, since they are also reflected in
the optimizer statistics, the choice of plan). If these types of "covert
channel" attacks are of concern, it is probably unwise to grant any access
to the data at all.
</para>
</sect1>
<sect1 id="rules-status">
<title>Rules and Command Status</title>
<para>
The <productname>PostgreSQL</productname> server returns a command
status string, such as <literal>INSERT 149592 1</literal>, for each
command it receives. This is simple enough when there are no rules
involved, but what happens when the query is rewritten by rules?
</para>
<para>
Rules affect the command status as follows:
<itemizedlist>
<listitem>
<para>
If there is no unconditional <literal>INSTEAD</literal> rule for the query, then
the originally given query will be executed, and its command
status will be returned as usual. (But note that if there were
any conditional <literal>INSTEAD</literal> rules, the negation of their qualifications
will have been added to the original query. This might reduce the
number of rows it processes, and if so the reported status will
be affected.)
</para>
</listitem>
<listitem>
<para>
If there is any unconditional <literal>INSTEAD</literal> rule for the query, then
the original query will not be executed at all. In this case,
the server will return the command status for the last query
that was inserted by an <literal>INSTEAD</literal> rule (conditional or
unconditional) and is of the same command type
(<command>INSERT</command>, <command>UPDATE</command>, or
<command>DELETE</command>) as the original query. If no query
meeting those requirements is added by any rule, then the
returned command status shows the original query type and
zeroes for the row-count and OID fields.
</para>
</listitem>
</itemizedlist>
</para>
<para>
The programmer can ensure that any desired <literal>INSTEAD</literal> rule is the one
that sets the command status in the second case, by giving it the
alphabetically last rule name among the active rules, so that it
gets applied last.
</para>
</sect1>
<sect1 id="rules-triggers">
<title>Rules Versus Triggers</title>
<indexterm zone="rules-triggers">
<primary>rule</primary>
<secondary sortas="Trigger">compared with triggers</secondary>
</indexterm>
<indexterm zone="rules-triggers">
<primary>trigger</primary>
<secondary sortas="Regeln">compared with rules</secondary>
</indexterm>
<para>
Many things that can be done using triggers can also be
implemented using the <productname>PostgreSQL</productname>
rule system. One of the things that cannot be implemented by
rules are some kinds of constraints, especially foreign keys. It is possible
to place a qualified rule that rewrites a command to <literal>NOTHING</literal>