aboutsummaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/catalogs.sgml100
-rw-r--r--doc/src/sgml/config.sgml40
-rw-r--r--doc/src/sgml/event-trigger.sgml18
-rw-r--r--doc/src/sgml/keywords.sgml7
-rw-r--r--doc/src/sgml/ref/allfiles.sgml3
-rw-r--r--doc/src/sgml/ref/alter_policy.sgml135
-rw-r--r--doc/src/sgml/ref/alter_role.sgml3
-rw-r--r--doc/src/sgml/ref/alter_table.sgml17
-rw-r--r--doc/src/sgml/ref/create_policy.sgml318
-rw-r--r--doc/src/sgml/ref/create_role.sgml20
-rw-r--r--doc/src/sgml/ref/drop_policy.sgml109
-rw-r--r--doc/src/sgml/reference.sgml3
12 files changed, 773 insertions, 0 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 68f84343520..76d64050618 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -239,6 +239,11 @@
</row>
<row>
+ <entry><link linkend="catalog-pg-rowsecurity"><structname>pg_rowsecurity</structname></link></entry>
+ <entry>table row-level security policies</entry>
+ </row>
+
+ <row>
<entry><link linkend="catalog-pg-seclabel"><structname>pg_seclabel</structname></link></entry>
<entry>security labels on database objects</entry>
</row>
@@ -1936,6 +1941,15 @@
</row>
<row>
+ <entry><structfield>relhasrowsecurity</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry>
+ True if table has row-security enabled; see
+ <link linkend="catalog-pg-rowsecurity"><structname>pg_rowsecurity</structname></link> catalog
+ </entry>
+ </row>
+
+ <row>
<entry><structfield>relhassubclass</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
@@ -5328,6 +5342,86 @@
</table>
</sect1>
+ <sect1 id="catalog-pg-rowsecurity">
+ <title><structname>pg_rowsecurity</structname></title>
+
+ <indexterm zone="catalog-pg-rowsecurity">
+ <primary>pg_rowsecurity</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_rowsecurity</structname> stores row-level
+ security policies for each table. A policy includes the kind of
+ command which it applies to (or all commands), the roles which it
+ applies to, the expression to be added as a security-barrier
+ qualification to queries which include the table and the expression
+ to be added as a with-check option for queries which attempt to add
+ new records to the table.
+ </para>
+
+ <table>
+
+ <title><structname>pg_rowsecurity</structname> Columns</title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>References</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>rsecpolname</structfield></entry>
+ <entry><type>name</type></entry>
+ <entry></entry>
+ <entry>The name of the row-security policy</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rsecrelid</structfield></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
+ <entry>The table to which the row-security policy belongs</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rseccmd</structfield></entry>
+ <entry><type>char</type></entry>
+ <entry></entry>
+ <entry>The command type to which the row-security policy is applied.</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rsecqual</structfield></entry>
+ <entry><type>pg_node_tree</type></entry>
+ <entry></entry>
+ <entry>The expression tree to be added to the security barrier qualifications for queries which use the table.</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rsecwithcheck</structfield></entry>
+ <entry><type>pg_node_tree</type></entry>
+ <entry></entry>
+ <entry>The expression tree to be added to the with check qualifications for queries which attempt to add rows to the table.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ <literal>pg_class.relhasrowsecurity</literal>
+ True if the table has row-security enabled.
+ Must be true if the table has a row-security policy in this catalog.
+ </para>
+ </note>
+
+ </sect1>
<sect1 id="catalog-pg-seclabel">
<title><structname>pg_seclabel</structname></title>
@@ -9133,6 +9227,12 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.relhastriggers</literal></entry>
<entry>True if table has (or once had) triggers</entry>
</row>
+ <row>
+ <entry><structfield>hasrowsecurity</structfield></entry>
+ <entry><type>boolean</type></entry>
+ <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.relhasrowsecurity</literal></entry>
+ <entry>True if table has row security enabled</entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 5be8fdcc252..70e47aaa3a1 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -5429,6 +5429,46 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
</listitem>
</varlistentry>
+ <varlistentry id="guc-row-security" xreflabel="row_security">
+ <term><varname>row_security</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>row_security</> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable controls if row security policies are to be applied
+ to queries which are run against tables that have row security enabled.
+ The default is 'on'. When set to 'on', all users, except superusers
+ and the owner of the table, will have the row policies for the table
+ applied to their queries. The table owner and superuser can request
+ that row policies be applied to their queries by setting this to
+ 'force'. Lastly, this can also be set to 'off' which will bypass row
+ policies for the table, if possible, and error if not.
+ </para>
+
+ <para>
+ For a user who is not a superuser and not the table owner to bypass
+ row policies for the table, they must have the BYPASSRLS role attribute.
+ If this is set to 'off' and the user queries a table which has row
+ policies enabled and the user does not have the right to bypass
+ row policies then a permission denied error will be returned.
+ </para>
+
+ <para>
+ The allowed values of <varname>row_security</> are
+ <literal>on</> (apply normally- not to superuser or table owner),
+ <literal>off</> (fail if row security would be applied), and
+ <literal>force</> (apply always- even to superuser and table owner).
+ </para>
+
+ <para>
+ For more information on row security policies,
+ see <xref linkend="SQL-CREATEPOLICY">.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-default-tablespace" xreflabel="default_tablespace">
<term><varname>default_tablespace</varname> (<type>string</type>)
<indexterm>
diff --git a/doc/src/sgml/event-trigger.sgml b/doc/src/sgml/event-trigger.sgml
index 3db8ef1a132..6f71a27855e 100644
--- a/doc/src/sgml/event-trigger.sgml
+++ b/doc/src/sgml/event-trigger.sgml
@@ -196,6 +196,12 @@
<entry align="center"><literal>-</literal></entry>
</row>
<row>
+ <entry align="left"><literal>ALTER POLICY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ </row>
+ <row>
<entry align="left"><literal>ALTER SCHEMA</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
@@ -352,6 +358,12 @@
<entry align="center"><literal>-</literal></entry>
</row>
<row>
+ <entry align="left"><literal>CREATE POLICY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ </row>
+ <row>
<entry align="left"><literal>CREATE RULE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
@@ -526,6 +538,12 @@
<entry align="center"><literal>X</literal></entry>
</row>
<row>
+ <entry align="left"><literal>DROP POLICY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ </row>
+ <row>
<entry align="left"><literal>DROP RULE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
diff --git a/doc/src/sgml/keywords.sgml b/doc/src/sgml/keywords.sgml
index 1c93b7c148d..b0dfd5ff75b 100644
--- a/doc/src/sgml/keywords.sgml
+++ b/doc/src/sgml/keywords.sgml
@@ -3423,6 +3423,13 @@
<entry>non-reserved</entry>
</row>
<row>
+ <entry><token>POLICY</token></entry>
+ <entry>non-reserved</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
<entry><token>PORTION</token></entry>
<entry></entry>
<entry>reserved</entry>
diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml
index b685e16a0fa..7aa3128090d 100644
--- a/doc/src/sgml/ref/allfiles.sgml
+++ b/doc/src/sgml/ref/allfiles.sgml
@@ -25,6 +25,7 @@ Complete list of usable sgml source files in this directory.
<!ENTITY alterOperator SYSTEM "alter_operator.sgml">
<!ENTITY alterOperatorClass SYSTEM "alter_opclass.sgml">
<!ENTITY alterOperatorFamily SYSTEM "alter_opfamily.sgml">
+<!ENTITY alterPolicy SYSTEM "alter_policy.sgml">
<!ENTITY alterRole SYSTEM "alter_role.sgml">
<!ENTITY alterRule SYSTEM "alter_rule.sgml">
<!ENTITY alterSchema SYSTEM "alter_schema.sgml">
@@ -69,6 +70,7 @@ Complete list of usable sgml source files in this directory.
<!ENTITY createOperator SYSTEM "create_operator.sgml">
<!ENTITY createOperatorClass SYSTEM "create_opclass.sgml">
<!ENTITY createOperatorFamily SYSTEM "create_opfamily.sgml">
+<!ENTITY createPolicy SYSTEM "create_policy.sgml">
<!ENTITY createRole SYSTEM "create_role.sgml">
<!ENTITY createRule SYSTEM "create_rule.sgml">
<!ENTITY createSchema SYSTEM "create_schema.sgml">
@@ -110,6 +112,7 @@ Complete list of usable sgml source files in this directory.
<!ENTITY dropOperatorClass SYSTEM "drop_opclass.sgml">
<!ENTITY dropOperatorFamily SYSTEM "drop_opfamily.sgml">
<!ENTITY dropOwned SYSTEM "drop_owned.sgml">
+<!ENTITY dropPolicy SYSTEM "drop_policy.sgml">
<!ENTITY dropRole SYSTEM "drop_role.sgml">
<!ENTITY dropRule SYSTEM "drop_rule.sgml">
<!ENTITY dropSchema SYSTEM "drop_schema.sgml">
diff --git a/doc/src/sgml/ref/alter_policy.sgml b/doc/src/sgml/ref/alter_policy.sgml
new file mode 100644
index 00000000000..37615fcab5d
--- /dev/null
+++ b/doc/src/sgml/ref/alter_policy.sgml
@@ -0,0 +1,135 @@
+<!--
+doc/src/sgml/ref/alter_policy.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-ALTERPOLICY">
+ <indexterm zone="sql-alterpolicy">
+ <primary>ALTER POLICY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER POLICY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER POLICY</refname>
+ <refpurpose>change the definition of a row-security policy</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER POLICY <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable>
+ [ RENAME TO <replaceable class="PARAMETER">new_name</replaceable> ]
+ [ TO { <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] ]
+ [ USING ( <replaceable class="parameter">expression</replaceable> ) ]
+ [ WITH CHECK ( <replaceable class="parameter">check_expression</replaceable> ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER POLICY</command> changes the <replaceable class="parameter">
+ definition</replaceable> of an existing row-security policy.
+ </para>
+
+ <para>
+ To use <command>ALTER POLICY</command>, you must own the table that
+ the policy applies to.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing policy to alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table that the
+ policy is on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the policy.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para>
+ The role to which the policy applies. Multiple roles can be specified at one time.
+ To apply the policy to all roles, use <literal>PUBLIC</literal>, which is also
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">expression</replaceable></term>
+ <listitem>
+ <para>
+ The USING expression for the policy. This expression will be added as a
+ security-barrier qualification to queries which use the table
+ automatically. If multiple policies are being applied for a given
+ table then they are all combined and added using OR. The USING
+ expression applies to records which are being retrived from the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">check_expression</replaceable></term>
+ <listitem>
+ <para>
+ The with-check expression for the policy. This expression will be
+ added as a WITH CHECK OPTION qualification to queries which use the
+ table automatically. If multiple policies are being applied for a
+ given table then they are all combined and added using OR. The WITH
+ CHECK expression applies to records which are being added to the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER POLICY</command> is a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createpolicy"></member>
+ <member><xref linkend="sql-droppolicy"></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml
index bcd46d5e4dc..0471daa1cce 100644
--- a/doc/src/sgml/ref/alter_role.sgml
+++ b/doc/src/sgml/ref/alter_role.sgml
@@ -32,6 +32,7 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replace
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
| CONNECTION LIMIT <replaceable class="PARAMETER">connlimit</replaceable>
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
| VALID UNTIL '<replaceable class="PARAMETER">timestamp</replaceable>'
@@ -142,6 +143,8 @@ ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATA
<term><literal>NOLOGIN</literal></term>
<term><literal>REPLICATION</literal></term>
<term><literal>NOREPLICATION</literal></term>
+ <term><literal>BYPASSRLS</literal></term>
+ <term><literal>NOBYPASSRLS</literal></term>
<term><literal>CONNECTION LIMIT</literal> <replaceable class="parameter">connlimit</replaceable></term>
<term><literal>PASSWORD</> <replaceable class="parameter">password</replaceable></term>
<term><literal>ENCRYPTED</></term>
diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index 5bbf4fb3595..1b35756c295 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -59,6 +59,8 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
ENABLE RULE <replaceable class="PARAMETER">rewrite_rule_name</replaceable>
ENABLE REPLICA RULE <replaceable class="PARAMETER">rewrite_rule_name</replaceable>
ENABLE ALWAYS RULE <replaceable class="PARAMETER">rewrite_rule_name</replaceable>
+ DISABLE ROW LEVEL SECURITY
+ ENABLE ROW LEVEL SECURITY
CLUSTER ON <replaceable class="PARAMETER">index_name</replaceable>
SET WITHOUT CLUSTER
SET WITH OIDS
@@ -421,6 +423,21 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
</varlistentry>
<varlistentry>
+ <term><literal>DISABLE</literal>/<literal>ENABLE ROW LEVEL SECURITY</literal></term>
+ <listitem>
+ <para>
+ These forms control the application of row security policies belonging
+ to the table. If enabled and no policies exist for the table, then a
+ default-deny policy is applied. Note that policies can exist for a table
+ even if row level security is disabled- in this case, the policies will
+ NOT be applied and the policies will be ignored.
+ See also
+ <xref linkend="SQL-CREATEPOLICY">.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><literal>CLUSTER ON</literal></term>
<listitem>
<para>
diff --git a/doc/src/sgml/ref/create_policy.sgml b/doc/src/sgml/ref/create_policy.sgml
new file mode 100644
index 00000000000..c6599eda1c0
--- /dev/null
+++ b/doc/src/sgml/ref/create_policy.sgml
@@ -0,0 +1,318 @@
+<!--
+doc/src/sgml/ref/create_policy.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-CREATEPOLICY">
+ <indexterm zone="sql-createpolicy">
+ <primary>CREATE POLICY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE POLICY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE POLICY</refname>
+ <refpurpose>define a new row-security policy for a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable>
+ [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
+ [ TO { <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] ]
+ [ USING ( <replaceable class="parameter">expression</replaceable> ) ]
+ [ WITH CHECK ( <replaceable class="parameter">check_expression</replaceable> ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The <command>CREATE POLICY</command> command defines a new row-security
+ policy for a table. Note that row-security must also be enabled on the
+ table using <command>ALTER TABLE</command> in order for created policies
+ to be applied.
+ </para>
+
+ <para>
+ A row-security policy is an expression which is added to the security-barrier
+ qualifications of queries which are run against the table the policy is on,
+ or an expression which is added to the with-check options for a table and
+ which is applied to rows which would be added to the table.
+ The security-barrier qualifications will always be evaluated prior to any
+ user-defined functions or user-provided WHERE clauses, while the with-check
+ expression will be evaluated against the rows which are going to be added to
+ the table. By adding policies to a table, a user can limit the rows which a
+ given user can select, insert, update, or delete. This capability is also
+ known as Row-Level Security or RLS.
+ </para>
+
+ <para>
+ Policy names are per-table, therefore one policy name can be used for many
+ different tables and have a definition for each table which is appropriate to
+ that table.
+ </para>
+
+ <para>
+ Policies can be applied for specific commands or for specific roles. The
+ default for newly created policies is that they apply for all commands and
+ roles, unless otherwise specified. If multiple policies apply to a given
+ query, they will be combined using OR.
+ </para>
+
+ <para>
+ Note that while row-security policies will be applied for explicit queries
+ against tables in the system, they are not applied when the system is
+ performing internal referential integrity checks or validating constraints.
+ This means there are indirect ways to determine that a given value exists.
+ An example of this is attempting to insert a duplicate value
+ into a column which is the primary key or has a unique constraint. If the
+ insert fails then the user can infer that the 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 which 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 (eg: surrogate keys) instead.
+ </para>
+
+ <para>
+ Regarding how policy expressions interact with the user: as the 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 RLS-enabled table. 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.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the policy to be created. This must be distinct from the
+ name of any other policy for the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table the
+ policy applies to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">command</replaceable></term>
+ <listitem>
+ <para>
+ The command to which the policy applies. Valid options are
+ <command>ALL</command>, <command>SELECT</command>,
+ <command>INSERT</command>, <command>UPDATE</command>,
+ and <command>DELETE</command>.
+ <command>ALL</command> is the default.
+ See below for specifics regarding how these are applied.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para>
+ The roles to which the policy is to be applied. The default is
+ <literal>PUBLIC</literal>, which will apply the policy to all roles.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">expression</replaceable></term>
+ <listitem>
+ <para>
+ Any <acronym>SQL</acronym> conditional expression (returning
+ <type>boolean</type>). The conditional expression cannot contain
+ any aggregate or window functions. This expression will be added
+ to queries to filter out the records which are visible to the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">check_expression</replaceable></term>
+ <listitem>
+ <para>
+ Any <acronym>SQL</acronym> conditional expression (returning
+ <type>boolean</type>). The condition expression cannot contain
+ any aggregate or window functions. This expression will be added
+ to queries which are attempting to add records to the table as
+ with-check options, and an error will be thrown if this condition
+ returns false for any records being added.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Per-Command policies</title>
+
+ <variablelist>
+
+ <varlistentry id="SQL-CREATEPOLICY-ALL">
+ <term><literal>ALL</></term>
+ <listitem>
+ <para>
+ Using <literal>ALL</literal> for a policy means that it will apply
+ to all commands, regardless of the type of command. If an
+ <literal>ALL</literal> policy exists and more specific policies
+ exist, then both the <literal>ALL</literal> policy and the more
+ specific policy (or policies) will be combined using
+ <literal>OR</literal>, as usual for overlapping policies.
+ Additionally, <literal>ALL</literal> policies will be applied to
+ both the selection side of a query and the modification side, using
+ the USING policy for both if only a USING policy has been defined.
+
+ As an example, if an <literal>UPDATE</literal> is issued, then the
+ <literal>ALL</literal> policy will be applicable to both what the
+ <literal>UPDATE</literal> will be able to select out as rows to be
+ updated (with the USING expression being applied), and it will be
+ applied to rows which result from the <literal>UPDATE</literal>
+ statement, to check if they are permitted to be added to the table
+ (using the WITH CHECK expression, if defined, and the USING expression
+ otherwise). If an INSERT or UPDATE command attempts to add rows to
+ the table which do not pass the <literal>ALL</literal> WITH CHECK
+ (or USING, if no WITH CHECK expression is defined) expression, the
+ command will error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="SQL-CREATEPOLICY-SELECT">
+ <term><literal>SELECT</></term>
+ <listitem>
+ <para>
+ Using <literal>SELECT</literal> for a policy means that it will apply
+ to <literal>SELECT</literal> commands. The result is that only those
+ records from the relation which pass the <literal>SELECT</literal>
+ policy will be returned, even if other records exist in the relation.
+ The <literal>SELECT</literal> policy only accepts the USING expression
+ as it only ever applies in cases where records are being retrived from
+ the relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="SQL-CREATEPOLICY-INSERT">
+ <term><literal>INSERT</></term>
+ <listitem>
+ <para>
+ Using <literal>INSERT</literal> for a policy means that it will apply
+ to <literal>INSERT</literal> commands. Rows being inserted which do
+ not pass this policy will result in a policy violation ERROR and the
+ entire <literal>INSERT</literal> command will be aborted. The
+ <literal>INSERT</literal> policy only accepts the WITH CHECK expression
+ as it only ever applies in cases where records are being added to the
+ relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="SQL-CREATEPOLICY-UPDATE">
+ <term><literal>DELETE</></term>
+ <listitem>
+ <para>
+ Using <literal>UPDATE</literal> for a policy means that it will apply
+ to <literal>UPDATE</literal> commands. As <literal>UPDATE</literal>
+ involves pulling an existing record and then making changes to some
+ portion (but possibly not all) of the record, the
+ <literal>UPDATE</literal> policy accepts both a USING expression and
+ a WITH CHECK expression. The USING expression will be used to
+ determine which records the <literal>UPDATE</literal> command will
+ see to operate against, while the <literal>WITH CHECK</literal>
+ expression defines what rows are allowed to be added back into the
+ relation (similar to the <literal>INSERT</literal> policy).
+ Any rows whose resulting values do not pass the
+ <literal>WITH CHECK</literal> expression will cause an ERROR and the
+ entire command will be aborted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="SQL-CREATEPOLICY-DELETE">
+ <term><literal>DELETE</></term>
+ <listitem>
+ <para>
+ Using <literal>DELETE</literal> for a policy means that it will apply
+ to <literal>DELETE</literal> commands. Only rows which pass this
+ policy will be seen by a <literal>DELETE</literal> command. Rows may
+ be visible through a <literal>SELECT</literal> which are not seen by a
+ <literal>DELETE</literal>, as they do not pass the USING expression
+ for the <literal>DELETE</literal>, and rows which are not visible
+ through the <literal>SELECT</literal> policy may be deleted if they
+ pass the <literal>DELETE</literal> USING policy. The
+ <literal>DELETE</literal> policy only accept the USING expression as
+ it only ever applies in cases where records are being extracted from
+ the relation for deletion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ You must be the owner of a table to create or change policies for it.
+ </para>
+
+ <para>
+ In order to maintain <firstterm>referential integrity</firstterm> between
+ two related tables, row-security policies are not applied when the system
+ performs checks on foreign key constraints.
+ </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>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_role.sgml b/doc/src/sgml/ref/create_role.sgml
index 641e3500c9a..ea260275114 100644
--- a/doc/src/sgml/ref/create_role.sgml
+++ b/doc/src/sgml/ref/create_role.sgml
@@ -32,6 +32,7 @@ CREATE ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
| CONNECTION LIMIT <replaceable class="PARAMETER">connlimit</replaceable>
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
| VALID UNTIL '<replaceable class="PARAMETER">timestamp</replaceable>'
@@ -191,6 +192,25 @@ CREATE ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
</varlistentry>
<varlistentry>
+ <term><literal>BYPASSRLS</literal></term>
+ <term><literal>NOBYPASSRLS</literal></term>
+ <listitem>
+ <para>
+ These clauses determine whether a role is allowed to bypass row-security
+ policies. A role having the <literal>BYPASSRLS</literal> attribute will
+ be allowed to bypass row-security policies by setting
+ <literal>row_security</literal> to
+ <literal>OFF</literal>. <literal>NOBYPASSRLS</literal> is the default.
+ Note that pg_dump will set <literal>row_security</literal> to
+ <literal>OFF</literal> by default, to ensure all contents of a table are
+ dumped out. If the user running pg_dump does not have appropriate
+ permissions, an error will be returned. The superuser and owner of the
+ table being dumped are considered to always have the right to bypass RLS.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><literal>CONNECTION LIMIT</literal> <replaceable class="parameter">connlimit</replaceable></term>
<listitem>
<para>
diff --git a/doc/src/sgml/ref/drop_policy.sgml b/doc/src/sgml/ref/drop_policy.sgml
new file mode 100644
index 00000000000..31ca9db220e
--- /dev/null
+++ b/doc/src/sgml/ref/drop_policy.sgml
@@ -0,0 +1,109 @@
+<!--
+doc/src/sgml/ref/drop_policy.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-DROPPOLICY">
+ <indexterm zone="sql-droppolicy">
+ <primary>DROP POLICY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP POLICY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP POLICY</refname>
+ <refpurpose>remove a row-security policy from a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP POLICY [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP POLICY</command> removes the specified row-security policy
+ from the table. Note that if the last policy is removed for a table and
+ the table still has ROW POLICY enabled via <command>ALTER TABLE</command>,
+ then the default-deny policy will be used. <command>ALTER TABLE</command>
+ can be used to disable row security for a table using
+ <literal>DISABLE ROW SECURITY</literal>, whether policies for the table
+ exist or not.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the policy does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the policy to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table that
+ the policy is on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To drop the row-security policy called <literal>p1</literal> on the
+ table named <literal>my_table</literal>:
+
+ <programlisting>
+ DROP POLICY p1 ON my_table;
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP POLICY</command> is a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createpolicy"></member>
+ <member><xref linkend="sql-alterpolicy"></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml
index 6ec126381c3..10c9a6d4030 100644
--- a/doc/src/sgml/reference.sgml
+++ b/doc/src/sgml/reference.sgml
@@ -53,6 +53,7 @@
&alterOperator;
&alterOperatorClass;
&alterOperatorFamily;
+ &alterPolicy;
&alterRole;
&alterRule;
&alterSchema;
@@ -97,6 +98,7 @@
&createOperator;
&createOperatorClass;
&createOperatorFamily;
+ &createPolicy;
&createRole;
&createRule;
&createSchema;
@@ -138,6 +140,7 @@
&dropOperatorClass;
&dropOperatorFamily;
&dropOwned;
+ &dropPolicy;
&dropRole;
&dropRule;
&dropSchema;