Improve the CREATE POLICY documentation.
authorDean Rasheed
Wed, 27 Sep 2017 16:10:35 +0000 (17:10 +0100)
committerDean Rasheed
Wed, 27 Sep 2017 16:10:35 +0000 (17:10 +0100)
Provide a correct description of how multiple policies are combined,
clarify when SELECT permissions are required, mention SELECT FOR
UPDATE/SHARE, and do some other more minor tidying up.

Reviewed by Stephen Frost

Discussion: https://postgr.es/m/CAEZATCVrxyYbOFU8XbGHicz%2BmXPYzw%3DhfNL2XTphDt-53TomQQ%40mail.gmail.com

Back-patch to 9.5.

doc/src/sgml/ref/create_policy.sgml

index 89d27879b1e30e1cb380cbb9ccecde4f4b67b088..0c5cd06518acd8cb3b92decaf66f45f88109cbfe 100644 (file)
@@ -72,20 +72,17 @@ CREATE POLICY name ON 
   
    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
-   statement, they will be combined using OR (although ON CONFLICT DO
-   UPDATE and INSERT policies are not combined in this way, but
-   rather enforced as noted at each stage of ON CONFLICT execution).
+   roles, unless otherwise specified.
   
 
   
-   For commands that can have both USING
-   and WITH CHECK policies (ALL
+   For policies that can have both USING
+   and WITH CHECK expressions (ALL
    and UPDATE), if no WITH CHECK
-   policy is defined, then the USING policy will be used
-   both for which rows are visible (normal USING case)
-   and for which rows will be allowed to be added (WITH
-   CHECK case).
+   expression is defined, then the USING expression will be
+   used both to determine which rows are visible (normal
+   USING case) and which new rows will be allowed to be
+   added (WITH CHECK case).
   
 
   
@@ -182,7 +179,7 @@ CREATE POLICY name ON 
 
   
 
 
    Per-Command Policies
 
    
@@ -195,8 +192,7 @@ CREATE POLICY name ON 
          to all commands, regardless of the type of command.  If an
          ALL policy exists and more specific policies
          exist, then both the ALL policy and the more
-         specific policy (or policies) will be combined using
-         OR, as usual for overlapping policies.
+         specific policy (or policies) will be applied.
          Additionally, ALL policies will be applied to
          both the selection side of a query and the modification side, using
          the USING expression for both cases if only
@@ -265,11 +261,12 @@ CREATE POLICY name ON 
       
        
          Using UPDATE for a policy means that it will apply
-         to UPDATE commands (or auxiliary ON
-         CONFLICT DO UPDATE clauses of INSERT
-         commands).  Since UPDATE involves pulling an
-         existing record and then making changes to some portion (but
-         possibly not all) of the record, UPDATE
+         to UPDATESELECT FOR UPDATE
+         and SELECT FOR SHARE commands, as well as
+         auxiliary ON CONFLICT DO UPDATE clauses of
+         INSERT commands.  Since UPDATE
+         involves pulling an existing record and replacing it with a new
+         modified record, UPDATE
          policies accept both a USING expression and
          a WITH CHECK expression.
          The USING expression determines which records
@@ -278,22 +275,6 @@ CREATE POLICY name ON 
          modified rows are allowed to be stored back into the relation.
        
 
-       
-         When an UPDATE command is used with a
-         WHERE clause or a RETURNING
-         clause, SELECT rights are also required on the
-         relation being updated and the appropriate SELECT
-         and ALL policies will be combined (using OR for any
-         overlapping SELECT related policies found) with the
-         USING clause of the UPDATE policy
-         using AND.  Therefore, in order for a user to be able to
-         UPDATE specific rows, the user must have access
-         to the row(s) through a SELECT
-         or ALL policy and the row(s) must pass
-         the UPDATE policy's USING
-         expression.
-       
-
        
          Any rows whose updated values do not pass the
          WITH CHECK expression will cause an error, and the
@@ -303,21 +284,33 @@ CREATE POLICY name ON 
        
 
        
-         Note, however, that INSERT with ON CONFLICT
-         DO UPDATE requires that an UPDATE policy
-         USING expression always be enforced as a
-         WITH CHECK expression.  This
-         UPDATE policy must always pass when the
-         UPDATE path is taken.  Any existing row that
-         necessitates that the UPDATE path be taken must
-         pass the (UPDATE or ALL)
-         USING qualifications (combined using OR), which
-         are always enforced as WITH CHECK
-         options in this context.  (The UPDATE path will
-         never be silently avoided; an error will be thrown
-         instead.)  Finally, the final row appended to the relation must pass
-         any WITH CHECK options that a conventional
-         UPDATE is required to pass.
+         Typically an UPDATE command also needs to read
+         data from columns in the relation being updated (e.g., in a
+         WHERE clause or a RETURNING
+         clause, or in an expression on the right hand side of the
+         SET clause).  In this case,
+         SELECT rights are also required on the relation
+         being updated, and the appropriate SELECT or
+         ALL policies will be applied in addition to
+         the UPDATE policies.  Thus the user must have
+         access to the row(s) being updated through a SELECT
+         or ALL policy in addition to being granted
+         permission to update the row(s) via an UPDATE
+         or ALL policy.
+       
+
+       
+         When an INSERT command has an auxiliary
+         ON CONFLICT DO UPDATE clause, if the
+         UPDATE path is taken, the row to be updated is
+         first checked against the USING expressions of
+         any UPDATE policies, and then the new updated row
+         is checked against the WITH CHECK expressions.
+         Note, however, that unlike a standalone UPDATE
+         command, if the existing row does not pass the
+         USING expressions, an error will be thrown (the
+         UPDATE path will never be silently
+         avoided).
        
       
      
@@ -336,19 +329,18 @@ CREATE POLICY name ON 
        
 
        
-         When a DELETE command is used with a
-         WHERE clause or a RETURNING
-         clause, SELECT rights are also required on the
-         relation being updated and the appropriate SELECT
-         and ALL policies will be combined (using OR for any
-         overlapping SELECT related policies found) with the
-         USING clause of the DELETE policy
-         using AND.  Therefore, in order for a user to be able to
-         DELETE specific rows, the user must have access
-         to the row(s) through a SELECT
-         or ALL policy and the row(s) must pass
-         the DELETE policy's USING
-         expression.
+         In most cases a DELETE command also needs to read
+         data from columns in the relation that it is deleting from (e.g.,
+         in a WHERE clause or a
+         RETURNING clause). In this case,
+         SELECT rights are also required on the relation,
+         and the appropriate SELECT or
+         ALL policies will be applied in addition to
+         the DELETE policies.  Thus the user must have
+         access to the row(s) being deleted through a SELECT
+         or ALL policy in addition to being granted
+         permission to delete the row(s) via a DELETE or
+         ALL policy.
        
 
        
@@ -362,6 +354,60 @@ CREATE POLICY name ON 
 
    
   
+
+  
+   Application of Multiple Policies
+
+   
+    When multiple policies of different command types apply to the same command
+    (for example, SELECT and UPDATE
+    policies applied to an UPDATE 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 AND operator.
+   
+
+   
+    When multiple policies of the same command type apply to the same command,
+    then at least one of the policies must grant access to the relation.  Thus
+    the expressions from all the policies of that type are combined using the
+    OR operator.  If there are no applicable policies, then
+    access is denied.
+   
+
+   
+    Note that, for the purposes of combining multiple policies,
+    ALL policies are treated as having the same type as
+    whichever other type of policy is being applied.
+   
+
+   
+    For example, in an UPDATE command requiring both
+    SELECT and UPDATE permissions, if
+    there are multiple applicable policies of each type, they will be combined
+    as follows:
+
+
+(
+  expression from SELECT/ALL policy 1
+  OR
+  expression from SELECT/ALL policy 2
+  OR
+  ...
+)
+AND
+(
+  expression from UPDATE/ALL policy 1
+  OR
+  expression from UPDATE/ALL policy 2
+  OR
+  ...
+)
+
+   
+
+