JayEye
JayEye

Reputation: 497

PostgreSQL row-level security involving a view or a select with join

(suggestions for a better or more-descriptive title are welcome).

I wonder if the following is possible in PostgreSQL using RLS (or any other mechanism). I want a user to be able to update certain rows of a table if its username matches a column in another table. In the example that follows, I want user nene, who appears as column u in table t0, to be able to update columns a and p in table t2. What I want to express is to apply a policy to the rows in t2 that would be matched by the following select statement: SELECT a, p FROM t2 INNER JOIN t1 ON (t2.t1id = t1.id) INNER JOIN t0 ON (t1.t0id = t0.id) WHERE t0.u = 'nene';

Is this possible? Any suggestions on how to proceed? An obvious workaround would be to duplicate the username on table t2, but that adds extraneous information on t2 and requires additional constraints to enforce.

Here are my three tables (in the real situation there are many more fields, and table t1 cannot be factored out of the problem; I left it in the example because needing two joins may change the solution space).

Upvotes: 11

Views: 6891

Answers (1)

Sergey Gershkovich
Sergey Gershkovich

Reputation: 422

Try

CREATE POLICY t2_policy_update ON t2 FOR UPDATE
USING (

  EXISTS (
    SELECT * 
    FROM t1 INNER JOIN t0 ON (t1.t0id = t0.id) 
    WHERE 
      t0.u = session_user AND 
      t1id = t1.id
  )

)

Upvotes: 17

Related Questions