value already exists. (This example assumes that the user is permitted by
policy to insert records which they are not allowed to see.) Another example
is where a user is allowed to insert into a table which references another,
otherwise hidden table. Existence can be determined by the user inserting
values into the referencing table, where success would indicate that the
value exists in the referenced table. These issues can be addressed by
carefully crafting policies to prevent users from being able to insert,
delete, or update records at all which might possibly indicate a value they
are not otherwise able to see, or by using generated values (e.g., surrogate
keys) instead of keys with external meanings.
</para>
<para>
Generally, the system will enforce filter conditions imposed using
security policies prior to qualifications that appear in user queries,
in order to prevent inadvertent exposure of the protected data to
user-defined functions which might not be trustworthy. However,
functions and operators marked by the system (or the system
administrator) as <literal>LEAKPROOF</literal> may be evaluated before
policy expressions, as they are assumed to be trustworthy.
</para>
<para>
Since policy expressions
are added to the user's query directly, they will be run with the rights of
the user running the overall query. Therefore, users who are using a given
policy must be able to access any tables or functions referenced in the
expression or they will simply receive a permission denied error when
attempting to query the table that has row-level security enabled.
This does not change how views
work, however. As with normal queries and views, permission checks and
policies for the tables which are referenced by a view will use the view
owner's rights and any policies which apply to the view owner, except if
the view is defined using the <literal>security_invoker</literal> option
(see <link linkend="sql-createview"><command>CREATE VIEW</command></link>).
</para>
<para>
No separate policy exists for <command>MERGE</command>. Instead, the policies
defined for <command>SELECT</command>, <command>INSERT</command>,
<command>UPDATE</command>, and <command>DELETE</command> are applied
while executing <command>MERGE</command>, depending on the actions that are
performed.
</para>
<para>
Additional discussion and practical examples can be found
in <xref linkend="ddl-rowsecurity"/>.
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
<command>CREATE POLICY</command> is a <productname>PostgreSQL</productname>
extension.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-alterpolicy"/></member>
<member><xref linkend="sql-droppolicy"/></member>
<member><xref linkend="sql-altertable"/></member>
</simplelist>
</refsect1>
</refentry>