]> begriffs open source - ai-pg/blob - full-docs/src/sgml/html/sql-createpolicy.html
PG 18 docs from https://ftp.postgresql.org/pub/source/v18.0/postgresql-18.0-docs...
[ai-pg] / full-docs / src / sgml / html / sql-createpolicy.html
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!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 18.0 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">
3 CREATE POLICY <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em>
4     [ AS { PERMISSIVE | RESTRICTIVE } ]
5     [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
6     [ TO { <em class="replaceable"><code>role_name</code></em> | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
7     [ USING ( <em class="replaceable"><code>using_expression</code></em> ) ]
8     [ WITH CHECK ( <em class="replaceable"><code>check_expression</code></em> ) ]
9 </pre></div><div class="refsect1" id="id-1.9.3.75.5"><h2>Description</h2><p>
10    The <code class="command">CREATE POLICY</code> command defines a new row-level
11    security policy for a table.  Note that row-level security must be
12    enabled on the table (using <code class="command">ALTER TABLE ... ENABLE ROW LEVEL
13    SECURITY</code>) in order for created policies to be applied.
14   </p><p>
15    A policy grants the permission to select, insert, update, or delete rows
16    that match the relevant policy expression.  Existing table rows are
17    checked against the expression specified in <code class="literal">USING</code>,
18    while new rows that would be created via <code class="literal">INSERT</code>
19    or <code class="literal">UPDATE</code> are checked against the expression specified
20    in <code class="literal">WITH CHECK</code>.  When a <code class="literal">USING</code>
21    expression returns true for a given row then that row is visible to the
22    user, while if false or null is returned then the row is not visible.
23    When a <code class="literal">WITH CHECK</code> expression returns true for a row
24    then that row is inserted or updated, while if false or null is returned
25    then an error occurs.
26   </p><p>
27    For <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
28    <code class="command">MERGE</code> statements,
29    <code class="literal">WITH CHECK</code> expressions are enforced after
30    <code class="literal">BEFORE</code> triggers are fired, and before any actual data
31    modifications are made.  Thus a <code class="literal">BEFORE ROW</code> trigger may
32    modify the data to be inserted, affecting the result of the security
33    policy check.  <code class="literal">WITH CHECK</code> expressions are enforced
34    before any other constraints.
35   </p><p>
36    Policy names are per-table.  Therefore, one policy name can be used for many
37    different tables and have a definition for each table which is appropriate to
38    that table.
39   </p><p>
40    Policies can be applied for specific commands or for specific roles.  The
41    default for newly created policies is that they apply for all commands and
42    roles, unless otherwise specified.  Multiple policies may apply to a single
43    command; see below for more details.
44    <a class="xref" href="sql-createpolicy.html#SQL-CREATEPOLICY-SUMMARY" title="Table 300. Policies Applied by Command Type">Table 300</a> summarizes how the different types
45    of policy apply to specific commands.
46   </p><p>
47    For policies that can have both <code class="literal">USING</code>
48    and <code class="literal">WITH CHECK</code> expressions (<code class="literal">ALL</code>
49    and <code class="literal">UPDATE</code>), if no <code class="literal">WITH CHECK</code>
50    expression is defined, then the <code class="literal">USING</code> expression will be
51    used both to determine which rows are visible (normal
52    <code class="literal">USING</code> case) and which new rows will be allowed to be
53    added (<code class="literal">WITH CHECK</code> case).
54   </p><p>
55    If row-level security is enabled for a table, but no applicable policies
56    exist, a <span class="quote">“<span class="quote">default deny</span>”</span> policy is assumed, so that no rows will
57    be visible or updatable.
58   </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>
59       The name of the policy to be created.  This must be distinct from the
60       name of any other policy for the table.
61      </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
62       The name (optionally schema-qualified) of the table the
63       policy applies to.
64      </p></dd><dt><span class="term"><code class="literal">PERMISSIVE</code></span></dt><dd><p>
65       Specify that the policy is to be created as a permissive policy.
66       All permissive policies which are applicable to a given query will
67       be combined together using the Boolean <span class="quote">“<span class="quote">OR</span>”</span> operator.  By creating
68       permissive policies, administrators can add to the set of records
69       which can be accessed.  Policies are permissive by default.
70      </p></dd><dt><span class="term"><code class="literal">RESTRICTIVE</code></span></dt><dd><p>
71       Specify that the policy is to be created as a restrictive policy.
72       All restrictive policies which are applicable to a given query will
73       be combined together using the Boolean <span class="quote">“<span class="quote">AND</span>”</span> operator.  By creating
74       restrictive policies, administrators can reduce the set of records
75       which can be accessed as all restrictive policies must be passed for
76       each record.
77      </p><p>
78       Note that there needs to be at least one permissive policy to grant
79       access to records before restrictive policies can be usefully used to
80       reduce that access. If only restrictive policies exist, then no records
81       will be accessible. When a mix of permissive and restrictive policies
82       are present, a record is only accessible if at least one of the
83       permissive policies passes, in addition to all the restrictive
84       policies.
85      </p></dd><dt><span class="term"><em class="replaceable"><code>command</code></em></span></dt><dd><p>
86       The command to which the policy applies.  Valid options are
87       <code class="command">ALL</code>, <code class="command">SELECT</code>,
88       <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
89       and <code class="command">DELETE</code>.
90       <code class="command">ALL</code> is the default.
91       See below for specifics regarding how these are applied.
92      </p></dd><dt><span class="term"><em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
93       The role(s) to which the policy is to be applied.  The default is
94       <code class="literal">PUBLIC</code>, which will apply the policy to all roles.
95      </p></dd><dt><span class="term"><em class="replaceable"><code>using_expression</code></em></span></dt><dd><p>
96       Any <acronym class="acronym">SQL</acronym> conditional expression (returning
97       <code class="type">boolean</code>).  The conditional expression cannot contain
98       any aggregate or window functions.  This expression will be added
99       to queries that refer to the table if row-level security is enabled.
100       Rows for which the expression returns true will be visible.  Any
101       rows for which the expression returns false or null will not be
102       visible to the user (in a <code class="command">SELECT</code>), and will not be
103       available for modification (in an <code class="command">UPDATE</code>
104       or <code class="command">DELETE</code>).  Such rows are silently suppressed; no error
105       is reported.
106      </p></dd><dt><span class="term"><em class="replaceable"><code>check_expression</code></em></span></dt><dd><p>
107       Any <acronym class="acronym">SQL</acronym> conditional expression (returning
108       <code class="type">boolean</code>).  The conditional expression cannot contain
109       any aggregate or window functions.  This expression will be used in
110       <code class="command">INSERT</code> and <code class="command">UPDATE</code> queries against
111       the table if row-level security is enabled.  Only rows for which the
112       expression evaluates to true will be allowed.  An error will be thrown
113       if the expression evaluates to false or null for any of the records
114       inserted or any of the records that result from the update.  Note that
115       the <em class="replaceable"><code>check_expression</code></em> is
116       evaluated against the proposed new contents of the row, not the
117       original contents.
118      </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>
119          Using <code class="literal">ALL</code> for a policy means that it will apply
120          to all commands, regardless of the type of command.  If an
121          <code class="literal">ALL</code> policy exists and more specific policies
122          exist, then both the <code class="literal">ALL</code> policy and the more
123          specific policy (or policies) will be applied.
124          Additionally, <code class="literal">ALL</code> policies will be applied to
125          both the selection side of a query and the modification side, using
126          the <code class="literal">USING</code> expression for both cases if only
127          a <code class="literal">USING</code> expression has been defined.
128        </p><p>
129          As an example, if an <code class="literal">UPDATE</code> is issued, then the
130          <code class="literal">ALL</code> policy will be applicable both to what the
131          <code class="literal">UPDATE</code> will be able to select as rows to be
132          updated (applying the <code class="literal">USING</code> expression),
133          and to the resulting updated rows, to check if they are permitted
134          to be added to the table (applying the <code class="literal">WITH CHECK</code>
135          expression, if defined, and the <code class="literal">USING</code> expression
136          otherwise).  If an <code class="command">INSERT</code>
137          or <code class="command">UPDATE</code> command attempts to add rows to the
138          table that do not pass the <code class="literal">ALL</code>
139          policy's <code class="literal">WITH CHECK</code> expression, the entire
140          command will be aborted.
141        </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>
142          Using <code class="literal">SELECT</code> for a policy means that it will apply
143          to <code class="literal">SELECT</code> queries and whenever
144          <code class="literal">SELECT</code> permissions are required on the relation the
145          policy is defined for.  The result is that only those records from the
146          relation that pass the <code class="literal">SELECT</code> policy will be
147          returned during a <code class="literal">SELECT</code> query, and that queries
148          that require <code class="literal">SELECT</code> permissions, such as
149          <code class="literal">UPDATE</code>, will also only see those records
150          that are allowed by the <code class="literal">SELECT</code> policy.
151          A <code class="literal">SELECT</code> policy cannot have a <code class="literal">WITH
152          CHECK</code> expression, as it only applies in cases where
153          records are being retrieved from the relation.
154        </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>
155          Using <code class="literal">INSERT</code> for a policy means that it will apply
156          to <code class="literal">INSERT</code> commands and <code class="literal">MERGE</code>
157          commands that contain <code class="literal">INSERT</code> actions.
158          Rows being inserted that do
159          not pass this policy will result in a policy violation error, and the
160          entire <code class="literal">INSERT</code> command will be aborted.
161          An <code class="literal">INSERT</code> policy cannot have
162          a <code class="literal">USING</code> expression, as it only applies in cases
163          where records are being added to the relation.
164        </p><p>
165          Note that <code class="literal">INSERT</code> with <code class="literal">ON CONFLICT DO
166          UPDATE</code> checks <code class="literal">INSERT</code> policies'
167          <code class="literal">WITH CHECK</code> expressions only for rows appended
168          to the relation by the <code class="literal">INSERT</code> path.
169        </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>
170          Using <code class="literal">UPDATE</code> for a policy means that it will apply
171          to <code class="literal">UPDATE</code>, <code class="literal">SELECT FOR UPDATE</code>
172          and <code class="literal">SELECT FOR SHARE</code> commands, as well as
173          auxiliary <code class="literal">ON CONFLICT DO UPDATE</code> clauses of
174          <code class="literal">INSERT</code> commands.
175          <code class="literal">MERGE</code> commands containing <code class="literal">UPDATE</code>
176          actions are affected as well.  Since <code class="literal">UPDATE</code>
177          involves pulling an existing record and replacing it with a new
178          modified record, <code class="literal">UPDATE</code>
179          policies accept both a <code class="literal">USING</code> expression and
180          a <code class="literal">WITH CHECK</code> expression.
181          The <code class="literal">USING</code> expression determines which records
182          the <code class="literal">UPDATE</code> command will see to operate against,
183          while the <code class="literal">WITH CHECK</code> expression defines which
184          modified rows are allowed to be stored back into the relation.
185        </p><p>
186          Any rows whose updated values do not pass the
187          <code class="literal">WITH CHECK</code> expression will cause an error, and the
188          entire command will be aborted.  If only a <code class="literal">USING</code>
189          clause is specified, then that clause will be used for both
190          <code class="literal">USING</code> and <code class="literal">WITH CHECK</code> cases.
191        </p><p>
192          Typically an <code class="literal">UPDATE</code> command also needs to read
193          data from columns in the relation being updated (e.g., in a
194          <code class="literal">WHERE</code> clause or a <code class="literal">RETURNING</code>
195          clause, or in an expression on the right hand side of the
196          <code class="literal">SET</code> clause).  In this case,
197          <code class="literal">SELECT</code> rights are also required on the relation
198          being updated, and the appropriate <code class="literal">SELECT</code> or
199          <code class="literal">ALL</code> policies will be applied in addition to
200          the <code class="literal">UPDATE</code> policies.  Thus the user must have
201          access to the row(s) being updated through a <code class="literal">SELECT</code>
202          or <code class="literal">ALL</code> policy in addition to being granted
203          permission to update the row(s) via an <code class="literal">UPDATE</code>
204          or <code class="literal">ALL</code> policy.
205        </p><p>
206          When an <code class="literal">INSERT</code> command has an auxiliary
207          <code class="literal">ON CONFLICT DO UPDATE</code> clause, if the
208          <code class="literal">UPDATE</code> path is taken, the row to be updated is
209          first checked against the <code class="literal">USING</code> expressions of
210          any <code class="literal">UPDATE</code> policies, and then the new updated row
211          is checked against the <code class="literal">WITH CHECK</code> expressions.
212          Note, however, that unlike a standalone <code class="literal">UPDATE</code>
213          command, if the existing row does not pass the
214          <code class="literal">USING</code> expressions, an error will be thrown (the
215          <code class="literal">UPDATE</code> path will <span class="emphasis"><em>never</em></span> be silently
216          avoided).
217        </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>
218          Using <code class="literal">DELETE</code> for a policy means that it will apply
219          to <code class="literal">DELETE</code> commands.  Only rows that pass this
220          policy will be seen by a <code class="literal">DELETE</code> command.  There can
221          be rows that are visible through a <code class="literal">SELECT</code> that are
222          not available for deletion, if they do not pass the
223          <code class="literal">USING</code> expression for
224          the <code class="literal">DELETE</code> policy.
225        </p><p>
226          In most cases a <code class="literal">DELETE</code> command also needs to read
227          data from columns in the relation that it is deleting from (e.g.,
228          in a <code class="literal">WHERE</code> clause or a
229          <code class="literal">RETURNING</code> clause). In this case,
230          <code class="literal">SELECT</code> rights are also required on the relation,
231          and the appropriate <code class="literal">SELECT</code> or
232          <code class="literal">ALL</code> policies will be applied in addition to
233          the <code class="literal">DELETE</code> policies.  Thus the user must have
234          access to the row(s) being deleted through a <code class="literal">SELECT</code>
235          or <code class="literal">ALL</code> policy in addition to being granted
236          permission to delete the row(s) via a <code class="literal">DELETE</code> or
237          <code class="literal">ALL</code> policy.
238        </p><p>
239          A <code class="literal">DELETE</code> policy cannot have a <code class="literal">WITH
240          CHECK</code> expression, as it only applies in cases where
241          records are being deleted from the relation, so that there is no
242          new row to check.
243        </p></dd></dl></div><div class="table" id="SQL-CREATEPOLICY-SUMMARY"><p class="title"><strong>Table 300. 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>
244         New row <a href="#ftn.RLS-SELECT-PRIV" class="footnote"><sup class="footnote" id="RLS-SELECT-PRIV">[a]</sup></a>
245        </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>
246         Existing &amp; new rows <a href="sql-createpolicy.html#ftn.RLS-SELECT-PRIV" class="footnoteref"><sup class="footnoteref">[a]</sup></a>
247        </td><td>—</td><td>Existing row</td><td>New row</td><td>—</td></tr><tr><td><code class="command">DELETE</code></td><td>
248         Existing row <a href="sql-createpolicy.html#ftn.RLS-SELECT-PRIV" class="footnoteref"><sup class="footnoteref">[a]</sup></a>
249        </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>
250           If read access is required to the existing or new row (for example,
251           a <code class="literal">WHERE</code> or <code class="literal">RETURNING</code> clause
252           that refers to columns from the relation).
253          </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>
254     When multiple policies of different command types apply to the same command
255     (for example, <code class="literal">SELECT</code> and <code class="literal">UPDATE</code>
256     policies applied to an <code class="literal">UPDATE</code> command), then the user
257     must have both types of permissions (for example, permission to select rows
258     from the relation as well as permission to update them).  Thus the
259     expressions for one type of policy are combined with the expressions for
260     the other type of policy using the <code class="literal">AND</code> operator.
261    </p><p>
262     When multiple policies of the same command type apply to the same command,
263     then there must be at least one <code class="literal">PERMISSIVE</code> policy
264     granting access to the relation, and all of the
265     <code class="literal">RESTRICTIVE</code> policies must pass.  Thus all the
266     <code class="literal">PERMISSIVE</code> policy expressions are combined using
267     <code class="literal">OR</code>, all the <code class="literal">RESTRICTIVE</code> policy
268     expressions are combined using <code class="literal">AND</code>, and the results are
269     combined using <code class="literal">AND</code>.  If there are no
270     <code class="literal">PERMISSIVE</code> policies, then access is denied.
271    </p><p>
272     Note that, for the purposes of combining multiple policies,
273     <code class="literal">ALL</code> policies are treated as having the same type as
274     whichever other type of policy is being applied.
275    </p><p>
276     For example, in an <code class="literal">UPDATE</code> command requiring both
277     <code class="literal">SELECT</code> and <code class="literal">UPDATE</code> permissions, if
278     there are multiple applicable policies of each type, they will be combined
279     as follows:
280
281 </p><pre class="programlisting">
282 <em class="replaceable"><code>expression</code></em> from RESTRICTIVE SELECT/ALL policy 1
283 AND
284 <em class="replaceable"><code>expression</code></em> from RESTRICTIVE SELECT/ALL policy 2
285 AND
286 ...
287 AND
288 (
289   <em class="replaceable"><code>expression</code></em> from PERMISSIVE SELECT/ALL policy 1
290   OR
291   <em class="replaceable"><code>expression</code></em> from PERMISSIVE SELECT/ALL policy 2
292   OR
293   ...
294 )
295 AND
296 <em class="replaceable"><code>expression</code></em> from RESTRICTIVE UPDATE/ALL policy 1
297 AND
298 <em class="replaceable"><code>expression</code></em> from RESTRICTIVE UPDATE/ALL policy 2
299 AND
300 ...
301 AND
302 (
303   <em class="replaceable"><code>expression</code></em> from PERMISSIVE UPDATE/ALL policy 1
304   OR
305   <em class="replaceable"><code>expression</code></em> from PERMISSIVE UPDATE/ALL policy 2
306   OR
307   ...
308 )
309 </pre></div></div><div class="refsect1" id="id-1.9.3.75.7"><h2>Notes</h2><p>
310    You must be the owner of a table to create or change policies for it.
311   </p><p>
312    While policies will be applied for explicit queries against tables
313    in the database, they are not applied when the system is performing internal
314    referential integrity checks or validating constraints.  This means there are
315    indirect ways to determine that a given value exists.  An example of this is
316    attempting to insert a duplicate value into a column that is a primary key
317    or has a unique constraint.  If the insert fails then the user can infer that
318    the value already exists. (This example assumes that the user is permitted by
319    policy to insert records which they are not allowed to see.)  Another example
320    is where a user is allowed to insert into a table which references another,
321    otherwise hidden table.  Existence can be determined by the user inserting
322    values into the referencing table, where success would indicate that the
323    value exists in the referenced table.  These issues can be addressed by
324    carefully crafting policies to prevent users from being able to insert,
325    delete, or update records at all which might possibly indicate a value they
326    are not otherwise able to see, or by using generated values (e.g., surrogate
327    keys) instead of keys with external meanings.
328   </p><p>
329    Generally, the system will enforce filter conditions imposed using
330    security policies prior to qualifications that appear in user queries,
331    in order to prevent inadvertent exposure of the protected data to
332    user-defined functions which might not be trustworthy.  However,
333    functions and operators marked by the system (or the system
334    administrator) as <code class="literal">LEAKPROOF</code> may be evaluated before
335    policy expressions, as they are assumed to be trustworthy.
336   </p><p>
337    Since policy expressions
338    are added to the user's query directly, they will be run with the rights of
339    the user running the overall query.  Therefore, users who are using a given
340    policy must be able to access any tables or functions referenced in the
341    expression or they will simply receive a permission denied error when
342    attempting to query the table that has row-level security enabled.
343    This does not change how views
344    work, however.  As with normal queries and views, permission checks and
345    policies for the tables which are referenced by a view will use the view
346    owner's rights and any policies which apply to the view owner, except if
347    the view is defined using the <code class="literal">security_invoker</code> option
348    (see <a class="link" href="sql-createview.html" title="CREATE VIEW"><code class="command">CREATE VIEW</code></a>).
349   </p><p>
350    No separate policy exists for <code class="command">MERGE</code>. Instead, the policies
351    defined for <code class="command">SELECT</code>, <code class="command">INSERT</code>,
352    <code class="command">UPDATE</code>, and <code class="command">DELETE</code> are applied
353    while executing <code class="command">MERGE</code>, depending on the actions that are
354    performed.
355   </p><p>
356    Additional discussion and practical examples can be found
357    in <a class="xref" href="ddl-rowsecurity.html" title="5.9. Row Security Policies">Section 5.9</a>.
358   </p></div><div class="refsect1" id="id-1.9.3.75.8"><h2>Compatibility</h2><p>
359    <code class="command">CREATE POLICY</code> is a <span class="productname">PostgreSQL</span>
360    extension.
361   </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 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE PROCEDURE</td></tr></table></div></body></html>