When multiple policies were set for a table, policies were determined by OR condition in PostgreSQL
9.6 and earlier. In PostgreSQL 10 it is possible to specify a policy with an AND condition. The AS
PERMISSIVE clause and the AS RESTRICTIVE clause can now be specified in the CREATE POLICY statement that create the policy. When specifying the AS PERMISSIVE clause, the restriction becomes loose (OR), and if AS RESTRICTIVE is specified, the limit becomes strict (AND). When designation is omitted, it becomes the same as in the previous version. Along with this, a column indicating condition specification has been added to the pg_policy catalog and the pg_policies catalog.
The author set multiple POLICY for the table and verified the effect. POLICY pol1 in PERMISSIVE mode and POLICY pol2, pol3 in RESTRICTIVE mode were prepared for the table poltbl1 and veryfied by combining them.
PDF page 63
Example 63Creating tables and POLICY (PERMISSIVE + RESTRICTIVE)
postgres=> CREATE TABLE poltbl1 (c1 NUMERIC, c2 VARCHAR(10), uname VARCHAR(10)) ;
CREATE TABLE
postgres=> ALTER TABLE poltbl1 ENABLE ROW LEVEL SECURITY ;
ALTER TABLE
postgres=> CREATE POLICY pol1 ON poltbl1 FOR ALL USING (uname = current_user) ;
CREATE POLICY
postgres=> CREATE POLICY pol2 ON poltbl1 AS RESTRICTIVE FOR ALL USING (c2 =
'data') ;
CREATE POLICY
postgres=> SELECT polname, polpermissive FROM pg_policy ;
polname | polpermissive
---------+---------------
pol1 | t
pol2 | f
(2 rows)
postgres=> SELECT tablename, policyname, permissive FROM pg_policies ;
tablename | policyname | permissive
-----------+------------+-------------
poltbl1 | pol1 | PERMISSIVE
poltbl1 | pol2 | RESTRICTIVE
(2 rows)
postgres=> \d poltbl1
Table "public.poltbl1"
Column | Type | Collation | Nullable | Default
--------+-----------------------+-----------+----------+---------
c1 | numeric | | |
c2 | character varying(10) | | |
uname | character varying(10) | | |
Policies:
POLICY "pol1"
USING (((uname)::name = CURRENT_USER))
POLICY "pol2" AS RESTRICTIVE
USING (((c2)::text = 'data'::text))
PDF page 64
In the above example, the setting of the table poltbl1 shows that POLICY pol2 is RESTRICTIVE.
Example 64Confirmation of execution plan (PERMISSIVE + RESTRICTIVE)
postgres=> EXPLAIN SELECT * FROM poltbl1 ;
QUERY PLAN
--------------------------------------------------------------------------
Seq Scan on poltbl1 (cost=0.00..20.50 rows=1 width=108)
Filter: (((c2)::text = 'data'::text) AND ((uname)::name = CURRENT_USER))
(2 rows)