codekingpro/portable-devtools
114k
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 16.3 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">3CREATE 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-level11 security policy for a table. Note that row-level security must be12 enabled on the table (using <code class="command">ALTER TABLE ... ENABLE ROW LEVEL13 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 rows16 that match the relevant policy expression. Existing table rows are17 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 specified20 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 the22 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 row24 then that row is inserted or updated, while if false or null is returned25 then an error occurs.26 </p><p>27 For <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and28 <code class="command">MERGE</code> statements,29 <code class="literal">WITH CHECK</code> expressions are enforced after30 <code class="literal">BEFORE</code> triggers are fired, and before any actual data31 modifications are made. Thus a <code class="literal">BEFORE ROW</code> trigger may32 modify the data to be inserted, affecting the result of the security33 policy check. <code class="literal">WITH CHECK</code> expressions are enforced34 before any other constraints.35 </p><p>36 Policy names are per-table. Therefore, one policy name can be used for many37 different tables and have a definition for each table which is appropriate to38 that table.39 </p><p>40 Policies can be applied for specific commands or for specific roles. The41 default for newly created policies is that they apply for all commands and42 roles, unless otherwise specified. Multiple policies may apply to a single43 command; see below for more details.44 <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 types45 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 be51 used both to determine which rows are visible (normal52 <code class="literal">USING</code> case) and which new rows will be allowed to be53 added (<code class="literal">WITH CHECK</code> case).54 </p><p>55 If row-level security is enabled for a table, but no applicable policies56 exist, a <span class="quote">“<span class="quote">default deny</span>”</span> policy is assumed, so that no rows will57 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 the60 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 the63 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 will67 be combined together using the Boolean <span class="quote">“<span class="quote">OR</span>”</span> operator. By creating68 permissive policies, administrators can add to the set of records69 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 will73 be combined together using the Boolean <span class="quote">“<span class="quote">AND</span>”</span> operator. By creating74 restrictive policies, administrators can reduce the set of records75 which can be accessed as all restrictive policies must be passed for76 each record.77 </p><p>78 Note that there needs to be at least one permissive policy to grant79 access to records before restrictive policies can be usefully used to80 reduce that access. If only restrictive policies exist, then no records81 will be accessible. When a mix of permissive and restrictive policies82 are present, a record is only accessible if at least one of the83 permissive policies passes, in addition to all the restrictive84 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 are87 <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 is94 <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 (returning97 <code class="type">boolean</code>). The conditional expression cannot contain98 any aggregate or window functions. This expression will be added99 to queries that refer to the table if row-level security is enabled.100 Rows for which the expression returns true will be visible. Any101 rows for which the expression returns false or null will not be102 visible to the user (in a <code class="command">SELECT</code>), and will not be103 available for modification (in an <code class="command">UPDATE</code>104 or <code class="command">DELETE</code>). Such rows are silently suppressed; no error105 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 (returning108 <code class="type">boolean</code>). The conditional expression cannot contain109 any aggregate or window functions. This expression will be used in110 <code class="command">INSERT</code> and <code class="command">UPDATE</code> queries against111 the table if row-level security is enabled. Only rows for which the112 expression evaluates to true will be allowed. An error will be thrown113 if the expression evaluates to false or null for any of the records114 inserted or any of the records that result from the update. Note that115 the <em class="replaceable"><code>check_expression</code></em> is116 evaluated against the proposed new contents of the row, not the117 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 apply120 to all commands, regardless of the type of command. If an121 <code class="literal">ALL</code> policy exists and more specific policies122 exist, then both the <code class="literal">ALL</code> policy and the more123 specific policy (or policies) will be applied.124 Additionally, <code class="literal">ALL</code> policies will be applied to125 both the selection side of a query and the modification side, using126 the <code class="literal">USING</code> expression for both cases if only127 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 the130 <code class="literal">ALL</code> policy will be applicable both to what the131 <code class="literal">UPDATE</code> will be able to select as rows to be132 updated (applying the <code class="literal">USING</code> expression),133 and to the resulting updated rows, to check if they are permitted134 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> expression136 otherwise). If an <code class="command">INSERT</code>137 or <code class="command">UPDATE</code> command attempts to add rows to the138 table that do not pass the <code class="literal">ALL</code>139 policy's <code class="literal">WITH CHECK</code> expression, the entire140 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 apply143 to <code class="literal">SELECT</code> queries and whenever144 <code class="literal">SELECT</code> permissions are required on the relation the145 policy is defined for. The result is that only those records from the146 relation that pass the <code class="literal">SELECT</code> policy will be147 returned during a <code class="literal">SELECT</code> query, and that queries148 that require <code class="literal">SELECT</code> permissions, such as149 <code class="literal">UPDATE</code>, will also only see those records150 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">WITH152 CHECK</code> expression, as it only applies in cases where153 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 apply156 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 do159 not pass this policy will result in a policy violation error, and the160 entire <code class="literal">INSERT</code> command will be aborted.161 An <code class="literal">INSERT</code> policy cannot have162 a <code class="literal">USING</code> expression, as it only applies in cases163 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 DO166 UPDATE</code> checks <code class="literal">INSERT</code> policies'167 <code class="literal">WITH CHECK</code> expressions only for rows appended168 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 apply171 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 as173 auxiliary <code class="literal">ON CONFLICT DO UPDATE</code> clauses of174 <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 new178 modified record, <code class="literal">UPDATE</code>179 policies accept both a <code class="literal">USING</code> expression and180 a <code class="literal">WITH CHECK</code> expression.181 The <code class="literal">USING</code> expression determines which records182 the <code class="literal">UPDATE</code> command will see to operate against,183 while the <code class="literal">WITH CHECK</code> expression defines which184 modified rows are allowed to be stored back into the relation.185 </p><p>186 Any rows whose updated values do not pass the187 <code class="literal">WITH CHECK</code> expression will cause an error, and the188 entire command will be aborted. If only a <code class="literal">USING</code>189 clause is specified, then that clause will be used for both190 <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 read193 data from columns in the relation being updated (e.g., in a194 <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 the196 <code class="literal">SET</code> clause). In this case,197 <code class="literal">SELECT</code> rights are also required on the relation198 being updated, and the appropriate <code class="literal">SELECT</code> or199 <code class="literal">ALL</code> policies will be applied in addition to200 the <code class="literal">UPDATE</code> policies. Thus the user must have201 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 granted203 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 auxiliary207 <code class="literal">ON CONFLICT DO UPDATE</code> clause, if the208 <code class="literal">UPDATE</code> path is taken, the row to be updated is209 first checked against the <code class="literal">USING</code> expressions of210 any <code class="literal">UPDATE</code> policies, and then the new updated row211 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 the214 <code class="literal">USING</code> expressions, an error will be thrown (the215 <code class="literal">UPDATE</code> path will <span class="emphasis"><em>never</em></span> be silently216 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 apply219 to <code class="literal">DELETE</code> commands. Only rows that pass this220 policy will be seen by a <code class="literal">DELETE</code> command. There can221 be rows that are visible through a <code class="literal">SELECT</code> that are222 not available for deletion, if they do not pass the223 <code class="literal">USING</code> expression for224 the <code class="literal">DELETE</code> policy.225 </p><p>226 In most cases a <code class="literal">DELETE</code> command also needs to read227 data from columns in the relation that it is deleting from (e.g.,228 in a <code class="literal">WHERE</code> clause or a229 <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> or232 <code class="literal">ALL</code> policies will be applied in addition to233 the <code class="literal">DELETE</code> policies. Thus the user must have234 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 granted236 permission to delete the row(s) via a <code class="literal">DELETE</code> or237 <code class="literal">ALL</code> policy.238 </p><p>239 A <code class="literal">DELETE</code> policy cannot have a <code class="literal">WITH240 CHECK</code> expression, as it only applies in cases where241 records are being deleted from the relation, so that there is no242 new row to check.243 </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>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 & 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 & 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> clause252 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 command255 (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 user257 must have both types of permissions (for example, permission to select rows258 from the relation as well as permission to update them). Thus the259 expressions for one type of policy are combined with the expressions for260 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> policy264 granting access to the relation, and all of the265 <code class="literal">RESTRICTIVE</code> policies must pass. Thus all the266 <code class="literal">PERMISSIVE</code> policy expressions are combined using267 <code class="literal">OR</code>, all the <code class="literal">RESTRICTIVE</code> policy268 expressions are combined using <code class="literal">AND</code>, and the results are269 combined using <code class="literal">AND</code>. If there are no270 <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 as274 whichever other type of policy is being applied.275 </p><p>276 For example, in an <code class="literal">UPDATE</code> command requiring both277 <code class="literal">SELECT</code> and <code class="literal">UPDATE</code> permissions, if278 there are multiple applicable policies of each type, they will be combined279 as follows:280 281</p><pre class="programlisting">282<em class="replaceable"><code>expression</code></em> from RESTRICTIVE SELECT/ALL policy 1283AND284<em class="replaceable"><code>expression</code></em> from RESTRICTIVE SELECT/ALL policy 2285AND286...287AND288(289 <em class="replaceable"><code>expression</code></em> from PERMISSIVE SELECT/ALL policy 1290 OR291 <em class="replaceable"><code>expression</code></em> from PERMISSIVE SELECT/ALL policy 2292 OR293 ...294)295AND296<em class="replaceable"><code>expression</code></em> from RESTRICTIVE UPDATE/ALL policy 1297AND298<em class="replaceable"><code>expression</code></em> from RESTRICTIVE UPDATE/ALL policy 2299AND300...301AND302(303 <em class="replaceable"><code>expression</code></em> from PERMISSIVE UPDATE/ALL policy 1304 OR305 <em class="replaceable"><code>expression</code></em> from PERMISSIVE UPDATE/ALL policy 2306 OR307 ...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 tables313 in the database, they are not applied when the system is performing internal314 referential integrity checks or validating constraints. This means there are315 indirect ways to determine that a given value exists. An example of this is316 attempting to insert a duplicate value into a column that is a primary key317 or has a unique constraint. If the insert fails then the user can infer that318 the value already exists. (This example assumes that the user is permitted by319 policy to insert records which they are not allowed to see.) Another example320 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 inserting322 values into the referencing table, where success would indicate that the323 value exists in the referenced table. These issues can be addressed by324 carefully crafting policies to prevent users from being able to insert,325 delete, or update records at all which might possibly indicate a value they326 are not otherwise able to see, or by using generated values (e.g., surrogate327 keys) instead of keys with external meanings.328 </p><p>329 Generally, the system will enforce filter conditions imposed using330 security policies prior to qualifications that appear in user queries,331 in order to prevent inadvertent exposure of the protected data to332 user-defined functions which might not be trustworthy. However,333 functions and operators marked by the system (or the system334 administrator) as <code class="literal">LEAKPROOF</code> may be evaluated before335 policy expressions, as they are assumed to be trustworthy.336 </p><p>337 Since policy expressions338 are added to the user's query directly, they will be run with the rights of339 the user running the overall query. Therefore, users who are using a given340 policy must be able to access any tables or functions referenced in the341 expression or they will simply receive a permission denied error when342 attempting to query the table that has row-level security enabled.343 This does not change how views344 work, however. As with normal queries and views, permission checks and345 policies for the tables which are referenced by a view will use the view346 owner's rights and any policies which apply to the view owner, except if347 the view is defined using the <code class="literal">security_invoker</code> option348 (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 policies351 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 applied353 while executing <code class="command">MERGE</code>, depending on the actions that are354 performed.355 </p><p>356 Additional discussion and practical examples can be found357 in <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</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 16.3 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE PROCEDURE</td></tr></table></div></body></html>