summaryrefslogtreecommitdiffstats
path: root/doc/src/sgml/html/sql-createpolicy.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/html/sql-createpolicy.html')
-rw-r--r--doc/src/sgml/html/sql-createpolicy.html361
1 files changed, 361 insertions, 0 deletions
diff --git a/doc/src/sgml/html/sql-createpolicy.html b/doc/src/sgml/html/sql-createpolicy.html
new file mode 100644
index 0000000..15c9e9c
--- /dev/null
+++ b/doc/src/sgml/html/sql-createpolicy.html
@@ -0,0 +1,361 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE POLICY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY" /><link rel="next" href="sql-createprocedure.html" title="CREATE PROCEDURE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE POLICY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 16.2 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createprocedure.html" title="CREATE PROCEDURE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEPOLICY"><div class="titlepage"></div><a id="id-1.9.3.75.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE POLICY</span></h2><p>CREATE POLICY — define a new row-level security policy for a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE POLICY <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em>
+ [ AS { PERMISSIVE | RESTRICTIVE } ]
+ [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
+ [ TO { <em class="replaceable"><code>role_name</code></em> | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
+ [ USING ( <em class="replaceable"><code>using_expression</code></em> ) ]
+ [ WITH CHECK ( <em class="replaceable"><code>check_expression</code></em> ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.75.5"><h2>Description</h2><p>
+ The <code class="command">CREATE POLICY</code> command defines a new row-level
+ security policy for a table. Note that row-level security must be
+ enabled on the table (using <code class="command">ALTER TABLE ... ENABLE ROW LEVEL
+ SECURITY</code>) in order for created policies to be applied.
+ </p><p>
+ A policy grants the permission to select, insert, update, or delete rows
+ that match the relevant policy expression. Existing table rows are
+ checked against the expression specified in <code class="literal">USING</code>,
+ while new rows that would be created via <code class="literal">INSERT</code>
+ or <code class="literal">UPDATE</code> are checked against the expression specified
+ in <code class="literal">WITH CHECK</code>. When a <code class="literal">USING</code>
+ expression returns true for a given row then that row is visible to the
+ user, while if false or null is returned then the row is not visible.
+ When a <code class="literal">WITH CHECK</code> expression returns true for a row
+ then that row is inserted or updated, while if false or null is returned
+ then an error occurs.
+ </p><p>
+ For <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">MERGE</code> statements,
+ <code class="literal">WITH CHECK</code> expressions are enforced after
+ <code class="literal">BEFORE</code> triggers are fired, and before any actual data
+ modifications are made. Thus a <code class="literal">BEFORE ROW</code> trigger may
+ modify the data to be inserted, affecting the result of the security
+ policy check. <code class="literal">WITH CHECK</code> expressions are enforced
+ before any other constraints.
+ </p><p>
+ 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.
+ </p><p>
+ 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. Multiple policies may apply to a single
+ command; see below for more details.
+ <a class="xref" href="sql-createpolicy.html#SQL-CREATEPOLICY-SUMMARY" title="Table 292. Policies Applied by Command Type">Table 292</a> summarizes how the different types
+ of policy apply to specific commands.
+ </p><p>
+ For policies that can have both <code class="literal">USING</code>
+ and <code class="literal">WITH CHECK</code> expressions (<code class="literal">ALL</code>
+ and <code class="literal">UPDATE</code>), if no <code class="literal">WITH CHECK</code>
+ expression is defined, then the <code class="literal">USING</code> expression will be
+ used both to determine which rows are visible (normal
+ <code class="literal">USING</code> case) and which new rows will be allowed to be
+ added (<code class="literal">WITH CHECK</code> case).
+ </p><p>
+ If row-level security is enabled for a table, but no applicable policies
+ exist, a <span class="quote">“<span class="quote">default deny</span>”</span> policy is assumed, so that no rows will
+ be visible or updatable.
+ </p></div><div class="refsect1" id="id-1.9.3.75.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the policy to be created. This must be distinct from the
+ name of any other policy for the table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table the
+ policy applies to.
+ </p></dd><dt><span class="term"><code class="literal">PERMISSIVE</code></span></dt><dd><p>
+ Specify that the policy is to be created as a permissive policy.
+ All permissive policies which are applicable to a given query will
+ be combined together using the Boolean <span class="quote">“<span class="quote">OR</span>”</span> operator. By creating
+ permissive policies, administrators can add to the set of records
+ which can be accessed. Policies are permissive by default.
+ </p></dd><dt><span class="term"><code class="literal">RESTRICTIVE</code></span></dt><dd><p>
+ Specify that the policy is to be created as a restrictive policy.
+ All restrictive policies which are applicable to a given query will
+ be combined together using the Boolean <span class="quote">“<span class="quote">AND</span>”</span> operator. By creating
+ restrictive policies, administrators can reduce the set of records
+ which can be accessed as all restrictive policies must be passed for
+ each record.
+ </p><p>
+ Note that there needs to be at least one permissive policy to grant
+ access to records before restrictive policies can be usefully used to
+ reduce that access. If only restrictive policies exist, then no records
+ will be accessible. When a mix of permissive and restrictive policies
+ are present, a record is only accessible if at least one of the
+ permissive policies passes, in addition to all the restrictive
+ policies.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>command</code></em></span></dt><dd><p>
+ The command to which the policy applies. Valid options are
+ <code class="command">ALL</code>, <code class="command">SELECT</code>,
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ and <code class="command">DELETE</code>.
+ <code class="command">ALL</code> is the default.
+ See below for specifics regarding how these are applied.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
+ The role(s) to which the policy is to be applied. The default is
+ <code class="literal">PUBLIC</code>, which will apply the policy to all roles.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>using_expression</code></em></span></dt><dd><p>
+ Any <acronym class="acronym">SQL</acronym> conditional expression (returning
+ <code class="type">boolean</code>). The conditional expression cannot contain
+ any aggregate or window functions. This expression will be added
+ to queries that refer to the table if row-level security is enabled.
+ Rows for which the expression returns true will be visible. Any
+ rows for which the expression returns false or null will not be
+ visible to the user (in a <code class="command">SELECT</code>), and will not be
+ available for modification (in an <code class="command">UPDATE</code>
+ or <code class="command">DELETE</code>). Such rows are silently suppressed; no error
+ is reported.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>check_expression</code></em></span></dt><dd><p>
+ Any <acronym class="acronym">SQL</acronym> conditional expression (returning
+ <code class="type">boolean</code>). The conditional expression cannot contain
+ any aggregate or window functions. This expression will be used in
+ <code class="command">INSERT</code> and <code class="command">UPDATE</code> queries against
+ the table if row-level security is enabled. Only rows for which the
+ expression evaluates to true will be allowed. An error will be thrown
+ if the expression evaluates to false or null for any of the records
+ inserted or any of the records that result from the update. Note that
+ the <em class="replaceable"><code>check_expression</code></em> is
+ evaluated against the proposed new contents of the row, not the
+ original contents.
+ </p></dd></dl></div><div class="refsect2" id="id-1.9.3.75.6.3"><h3>Per-Command Policies</h3><div class="variablelist"><dl class="variablelist"><dt id="SQL-CREATEPOLICY-ALL"><span class="term"><code class="literal">ALL</code></span> <a href="#SQL-CREATEPOLICY-ALL" class="id_link">#</a></dt><dd><p>
+ Using <code class="literal">ALL</code> for a policy means that it will apply
+ to all commands, regardless of the type of command. If an
+ <code class="literal">ALL</code> policy exists and more specific policies
+ exist, then both the <code class="literal">ALL</code> policy and the more
+ specific policy (or policies) will be applied.
+ Additionally, <code class="literal">ALL</code> policies will be applied to
+ both the selection side of a query and the modification side, using
+ the <code class="literal">USING</code> expression for both cases if only
+ a <code class="literal">USING</code> expression has been defined.
+ </p><p>
+ As an example, if an <code class="literal">UPDATE</code> is issued, then the
+ <code class="literal">ALL</code> policy will be applicable both to what the
+ <code class="literal">UPDATE</code> will be able to select as rows to be
+ updated (applying the <code class="literal">USING</code> expression),
+ and to the resulting updated rows, to check if they are permitted
+ to be added to the table (applying the <code class="literal">WITH CHECK</code>
+ expression, if defined, and the <code class="literal">USING</code> expression
+ otherwise). If an <code class="command">INSERT</code>
+ or <code class="command">UPDATE</code> command attempts to add rows to the
+ table that do not pass the <code class="literal">ALL</code>
+ policy's <code class="literal">WITH CHECK</code> expression, the entire
+ command will be aborted.
+ </p></dd><dt id="SQL-CREATEPOLICY-SELECT"><span class="term"><code class="literal">SELECT</code></span> <a href="#SQL-CREATEPOLICY-SELECT" class="id_link">#</a></dt><dd><p>
+ Using <code class="literal">SELECT</code> for a policy means that it will apply
+ to <code class="literal">SELECT</code> queries and whenever
+ <code class="literal">SELECT</code> permissions are required on the relation the
+ policy is defined for. The result is that only those records from the
+ relation that pass the <code class="literal">SELECT</code> policy will be
+ returned during a <code class="literal">SELECT</code> query, and that queries
+ that require <code class="literal">SELECT</code> permissions, such as
+ <code class="literal">UPDATE</code>, will also only see those records
+ that are allowed by the <code class="literal">SELECT</code> policy.
+ A <code class="literal">SELECT</code> policy cannot have a <code class="literal">WITH
+ CHECK</code> expression, as it only applies in cases where
+ records are being retrieved from the relation.
+ </p></dd><dt id="SQL-CREATEPOLICY-INSERT"><span class="term"><code class="literal">INSERT</code></span> <a href="#SQL-CREATEPOLICY-INSERT" class="id_link">#</a></dt><dd><p>
+ Using <code class="literal">INSERT</code> for a policy means that it will apply
+ to <code class="literal">INSERT</code> commands and <code class="literal">MERGE</code>
+ commands that contain <code class="literal">INSERT</code> actions.
+ Rows being inserted that do
+ not pass this policy will result in a policy violation error, and the
+ entire <code class="literal">INSERT</code> command will be aborted.
+ An <code class="literal">INSERT</code> policy cannot have
+ a <code class="literal">USING</code> expression, as it only applies in cases
+ where records are being added to the relation.
+ </p><p>
+ Note that <code class="literal">INSERT</code> with <code class="literal">ON CONFLICT DO
+ UPDATE</code> checks <code class="literal">INSERT</code> policies'
+ <code class="literal">WITH CHECK</code> expressions only for rows appended
+ to the relation by the <code class="literal">INSERT</code> path.
+ </p></dd><dt id="SQL-CREATEPOLICY-UPDATE"><span class="term"><code class="literal">UPDATE</code></span> <a href="#SQL-CREATEPOLICY-UPDATE" class="id_link">#</a></dt><dd><p>
+ Using <code class="literal">UPDATE</code> for a policy means that it will apply
+ to <code class="literal">UPDATE</code>, <code class="literal">SELECT FOR UPDATE</code>
+ and <code class="literal">SELECT FOR SHARE</code> commands, as well as
+ auxiliary <code class="literal">ON CONFLICT DO UPDATE</code> clauses of
+ <code class="literal">INSERT</code> commands.
+ <code class="literal">MERGE</code> commands containing <code class="literal">UPDATE</code>
+ actions are affected as well. Since <code class="literal">UPDATE</code>
+ involves pulling an existing record and replacing it with a new
+ modified record, <code class="literal">UPDATE</code>
+ policies accept both a <code class="literal">USING</code> expression and
+ a <code class="literal">WITH CHECK</code> expression.
+ The <code class="literal">USING</code> expression determines which records
+ the <code class="literal">UPDATE</code> command will see to operate against,
+ while the <code class="literal">WITH CHECK</code> expression defines which
+ modified rows are allowed to be stored back into the relation.
+ </p><p>
+ Any rows whose updated values do not pass the
+ <code class="literal">WITH CHECK</code> expression will cause an error, and the
+ entire command will be aborted. If only a <code class="literal">USING</code>
+ clause is specified, then that clause will be used for both
+ <code class="literal">USING</code> and <code class="literal">WITH CHECK</code> cases.
+ </p><p>
+ Typically an <code class="literal">UPDATE</code> command also needs to read
+ data from columns in the relation being updated (e.g., in a
+ <code class="literal">WHERE</code> clause or a <code class="literal">RETURNING</code>
+ clause, or in an expression on the right hand side of the
+ <code class="literal">SET</code> clause). In this case,
+ <code class="literal">SELECT</code> rights are also required on the relation
+ being updated, and the appropriate <code class="literal">SELECT</code> or
+ <code class="literal">ALL</code> policies will be applied in addition to
+ the <code class="literal">UPDATE</code> policies. Thus the user must have
+ access to the row(s) being updated through a <code class="literal">SELECT</code>
+ or <code class="literal">ALL</code> policy in addition to being granted
+ permission to update the row(s) via an <code class="literal">UPDATE</code>
+ or <code class="literal">ALL</code> policy.
+ </p><p>
+ When an <code class="literal">INSERT</code> command has an auxiliary
+ <code class="literal">ON CONFLICT DO UPDATE</code> clause, if the
+ <code class="literal">UPDATE</code> path is taken, the row to be updated is
+ first checked against the <code class="literal">USING</code> expressions of
+ any <code class="literal">UPDATE</code> policies, and then the new updated row
+ is checked against the <code class="literal">WITH CHECK</code> expressions.
+ Note, however, that unlike a standalone <code class="literal">UPDATE</code>
+ command, if the existing row does not pass the
+ <code class="literal">USING</code> expressions, an error will be thrown (the
+ <code class="literal">UPDATE</code> path will <span class="emphasis"><em>never</em></span> be silently
+ avoided).
+ </p></dd><dt id="SQL-CREATEPOLICY-DELETE"><span class="term"><code class="literal">DELETE</code></span> <a href="#SQL-CREATEPOLICY-DELETE" class="id_link">#</a></dt><dd><p>
+ Using <code class="literal">DELETE</code> for a policy means that it will apply
+ to <code class="literal">DELETE</code> commands. Only rows that pass this
+ policy will be seen by a <code class="literal">DELETE</code> command. There can
+ be rows that are visible through a <code class="literal">SELECT</code> that are
+ not available for deletion, if they do not pass the
+ <code class="literal">USING</code> expression for
+ the <code class="literal">DELETE</code> policy.
+ </p><p>
+ In most cases a <code class="literal">DELETE</code> command also needs to read
+ data from columns in the relation that it is deleting from (e.g.,
+ in a <code class="literal">WHERE</code> clause or a
+ <code class="literal">RETURNING</code> clause). In this case,
+ <code class="literal">SELECT</code> rights are also required on the relation,
+ and the appropriate <code class="literal">SELECT</code> or
+ <code class="literal">ALL</code> policies will be applied in addition to
+ the <code class="literal">DELETE</code> policies. Thus the user must have
+ access to the row(s) being deleted through a <code class="literal">SELECT</code>
+ or <code class="literal">ALL</code> policy in addition to being granted
+ permission to delete the row(s) via a <code class="literal">DELETE</code> or
+ <code class="literal">ALL</code> policy.
+ </p><p>
+ A <code class="literal">DELETE</code> policy cannot have a <code class="literal">WITH
+ CHECK</code> expression, as it only applies in cases where
+ records are being deleted from the relation, so that there is no
+ new row to check.
+ </p></dd></dl></div><div class="table" id="SQL-CREATEPOLICY-SUMMARY"><p class="title"><strong>Table 292. Policies Applied by Command Type</strong></p><div class="table-contents"><table class="table" summary="Policies Applied by Command Type" border="1"><colgroup><col /><col /><col /><col class="update-using" /><col class="update-check" /><col /></colgroup><thead><tr><th rowspan="2">Command</th><th><code class="literal">SELECT/ALL policy</code></th><th><code class="literal">INSERT/ALL policy</code></th><th colspan="2"><code class="literal">UPDATE/ALL policy</code></th><th><code class="literal">DELETE/ALL policy</code></th></tr><tr><th><code class="literal">USING expression</code></th><th><code class="literal">WITH CHECK expression</code></th><th><code class="literal">USING expression</code></th><th><code class="literal">WITH CHECK expression</code></th><th><code class="literal">USING expression</code></th></tr></thead><tbody><tr><td><code class="command">SELECT</code></td><td>Existing row</td><td>—</td><td>—</td><td>—</td><td>—</td></tr><tr><td><code class="command">SELECT FOR UPDATE/SHARE</code></td><td>Existing row</td><td>—</td><td>Existing row</td><td>—</td><td>—</td></tr><tr><td><code class="command">INSERT</code> / <code class="command">MERGE ... THEN INSERT</code></td><td>—</td><td>New row</td><td>—</td><td>—</td><td>—</td></tr><tr><td><code class="command">INSERT ... RETURNING</code></td><td>
+ New row <a href="#ftn.RLS-SELECT-PRIV" class="footnote"><sup class="footnote" id="RLS-SELECT-PRIV">[a]</sup></a>
+ </td><td>New row</td><td>—</td><td>—</td><td>—</td></tr><tr><td><code class="command">UPDATE</code> / <code class="command">MERGE ... THEN UPDATE</code></td><td>
+ Existing &amp; new rows <a href="sql-createpolicy.html#ftn.RLS-SELECT-PRIV" class="footnoteref"><sup class="footnoteref">[a]</sup></a>
+ </td><td>—</td><td>Existing row</td><td>New row</td><td>—</td></tr><tr><td><code class="command">DELETE</code></td><td>
+ Existing row <a href="sql-createpolicy.html#ftn.RLS-SELECT-PRIV" class="footnoteref"><sup class="footnoteref">[a]</sup></a>
+ </td><td>—</td><td>—</td><td>—</td><td>Existing row</td></tr><tr><td><code class="command">ON CONFLICT DO UPDATE</code></td><td>Existing &amp; new rows</td><td>—</td><td>Existing row</td><td>New row</td><td>—</td></tr></tbody><tbody class="footnotes"><tr><td colspan="6"><div id="ftn.RLS-SELECT-PRIV" class="footnote"><p><a href="#RLS-SELECT-PRIV" class="para"><sup class="para">[a] </sup></a>
+ If read access is required to the existing or new row (for example,
+ a <code class="literal">WHERE</code> or <code class="literal">RETURNING</code> clause
+ that refers to columns from the relation).
+ </p></div></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="refsect2" id="id-1.9.3.75.6.4"><h3>Application of Multiple Policies</h3><p>
+ When multiple policies of different command types apply to the same command
+ (for example, <code class="literal">SELECT</code> and <code class="literal">UPDATE</code>
+ policies applied to an <code class="literal">UPDATE</code> command), then the user
+ must have both types of permissions (for example, permission to select rows
+ from the relation as well as permission to update them). Thus the
+ expressions for one type of policy are combined with the expressions for
+ the other type of policy using the <code class="literal">AND</code> operator.
+ </p><p>
+ When multiple policies of the same command type apply to the same command,
+ then there must be at least one <code class="literal">PERMISSIVE</code> policy
+ granting access to the relation, and all of the
+ <code class="literal">RESTRICTIVE</code> policies must pass. Thus all the
+ <code class="literal">PERMISSIVE</code> policy expressions are combined using
+ <code class="literal">OR</code>, all the <code class="literal">RESTRICTIVE</code> policy
+ expressions are combined using <code class="literal">AND</code>, and the results are
+ combined using <code class="literal">AND</code>. If there are no
+ <code class="literal">PERMISSIVE</code> policies, then access is denied.
+ </p><p>
+ Note that, for the purposes of combining multiple policies,
+ <code class="literal">ALL</code> policies are treated as having the same type as
+ whichever other type of policy is being applied.
+ </p><p>
+ For example, in an <code class="literal">UPDATE</code> command requiring both
+ <code class="literal">SELECT</code> and <code class="literal">UPDATE</code> permissions, if
+ there are multiple applicable policies of each type, they will be combined
+ as follows:
+
+</p><pre class="programlisting">
+<em class="replaceable"><code>expression</code></em> from RESTRICTIVE SELECT/ALL policy 1
+AND
+<em class="replaceable"><code>expression</code></em> from RESTRICTIVE SELECT/ALL policy 2
+AND
+...
+AND
+(
+ <em class="replaceable"><code>expression</code></em> from PERMISSIVE SELECT/ALL policy 1
+ OR
+ <em class="replaceable"><code>expression</code></em> from PERMISSIVE SELECT/ALL policy 2
+ OR
+ ...
+)
+AND
+<em class="replaceable"><code>expression</code></em> from RESTRICTIVE UPDATE/ALL policy 1
+AND
+<em class="replaceable"><code>expression</code></em> from RESTRICTIVE UPDATE/ALL policy 2
+AND
+...
+AND
+(
+ <em class="replaceable"><code>expression</code></em> from PERMISSIVE UPDATE/ALL policy 1
+ OR
+ <em class="replaceable"><code>expression</code></em> from PERMISSIVE UPDATE/ALL policy 2
+ OR
+ ...
+)
+</pre></div></div><div class="refsect1" id="id-1.9.3.75.7"><h2>Notes</h2><p>
+ You must be the owner of a table to create or change policies for it.
+ </p><p>
+ While policies will be applied for explicit queries against tables
+ in the database, 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 that is a 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 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.
+ </p><p>
+ 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 <code class="literal">LEAKPROOF</code> may be evaluated before
+ policy expressions, as they are assumed to be trustworthy.
+ </p><p>
+ 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 <code class="literal">security_invoker</code> option
+ (see <a class="link" href="sql-createview.html" title="CREATE VIEW"><code class="command">CREATE VIEW</code></a>).
+ </p><p>
+ No separate policy exists for <code class="command">MERGE</code>. Instead, the policies
+ defined for <code class="command">SELECT</code>, <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, and <code class="command">DELETE</code> are applied
+ while executing <code class="command">MERGE</code>, depending on the actions that are
+ performed.
+ </p><p>
+ Additional discussion and practical examples can be found
+ in <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a>.
+ </p></div><div class="refsect1" id="id-1.9.3.75.8"><h2>Compatibility</h2><p>
+ <code class="command">CREATE POLICY</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.75.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterpolicy.html" title="ALTER POLICY"><span class="refentrytitle">ALTER POLICY</span></a>, <a class="xref" href="sql-droppolicy.html" title="DROP POLICY"><span class="refentrytitle">DROP POLICY</span></a>, <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createprocedure.html" title="CREATE PROCEDURE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE OPERATOR FAMILY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 16.2 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE PROCEDURE</td></tr></table></div></body></html> \ No newline at end of file