appear only when
grant options have been explicitly granted to someone.
</para>
<para>
The <quote>Access privileges</quote> column
shows <literal>(none)</literal> when the object's privileges entry is
non-null but empty. This means that no privileges are granted at all,
even to the object's owner — a rare situation. (The owner still
has implicit grant options in this case, and so could re-grant her own
privileges; but she has none at the moment.)
</para>
</sect1>
<sect1 id="ddl-rowsecurity">
<title>Row Security Policies</title>
<indexterm zone="ddl-rowsecurity">
<primary>row-level security</primary>
</indexterm>
<indexterm zone="ddl-rowsecurity">
<primary>policy</primary>
</indexterm>
<para>
In addition to the SQL-standard <link linkend="ddl-priv">privilege
system</link> available through <xref linkend="sql-grant"/>,
tables can have <firstterm>row security policies</firstterm> that restrict,
on a per-user basis, which rows can be returned by normal queries
or inserted, updated, or deleted by data modification commands.
This feature is also known as <firstterm>Row-Level Security</firstterm>.
By default, tables do not have any policies, so that if a user has
access privileges to a table according to the SQL privilege system,
all rows within it are equally available for querying or updating.
</para>
<para>
When row security is enabled on a table (with
<link linkend="sql-altertable">ALTER TABLE ... ENABLE ROW LEVEL
SECURITY</link>), all normal access to the table for selecting rows or
modifying rows must be allowed by a row security policy. (However, the
table's owner is typically not subject to row security policies.) If no
policy exists for the table, a default-deny policy is used, meaning that
no rows are visible or can be modified. Operations that apply to the
whole table, such as <command>TRUNCATE</command> and <literal>REFERENCES</literal>,
are not subject to row security.
</para>
<para>
Row security policies can be specific to commands, or to roles, or to
both. A policy can be specified to apply to <literal>ALL</literal>
commands, or to <literal>SELECT</literal>, <literal>INSERT</literal>, <literal>UPDATE</literal>,
or <literal>DELETE</literal>. Multiple roles can be assigned to a given
policy, and normal role membership and inheritance rules apply.
</para>
<para>
To specify which rows are visible or modifiable according to a policy,
an expression is required that returns a Boolean result. This
expression will be evaluated for each row prior to any conditions or
functions coming from the user's query. (The only exceptions to this
rule are <literal>leakproof</literal> functions, which are guaranteed to
not leak information; the optimizer may choose to apply such functions
ahead of the row-security check.) Rows for which the expression does
not return <literal>true</literal> will not be processed. Separate expressions
may be specified to provide independent control over the rows which are
visible and the rows which are allowed to be modified. Policy
expressions are run as part of the query and with the privileges of the
user running the query, although security-definer functions can be used
to access data not available to the calling user.
</para>
<para>
Superusers and roles with the <literal>BYPASSRLS</literal> attribute always
bypass the row security system when accessing a table. Table owners
normally bypass row security as well, though a table owner can choose to
be subject to row security with <link linkend="sql-altertable">ALTER
TABLE ... FORCE ROW LEVEL SECURITY</link>.
</para>
<para>
Enabling and disabling row security, as well as adding policies to a
table, is always the privilege of the table owner only.
</para>
<para>
Policies are created using the <xref linkend="sql-createpolicy"/>