Re: Postgres trigger side-effect is occurring out of order with row-level security select policy

From: Carl Sverre <sverre(dot)carl(at)gmail(dot)com>
To: dean(dot)a(dot)rasheed(at)gmail(dot)com
Cc: "Charles Clavadetscher (SwissPUG)" <clavadetscher(at)swisspug(dot)org>, Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com>, pgsql-general(at)lists(dot)postgresql(dot)org
Subject: Re: Postgres trigger side-effect is occurring out of order with row-level security select policy
Date: 2018-10-02 19:12:32
Message-ID: CADUo9RGk8CAe=Zw9HaxamopikxGdV0YBRX83ep+Sv5hYQqrdnw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Dean,
Thank you for catching that bug, I have updated the StackOverflow answer to
account for that issue.

As for the optimization problem I mentioned, the issue seems to be that
running a function that acquires a snapshot for each row is much slower
than in-lining a nested loop over table b into the query. I have attached
a psql session that demonstrates the exact performance issue I am referring
to.

Carl Sverre

http://www.carlsverre.com

On Tue, Oct 2, 2018 at 1:28 AM Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>
wrote:

> On Mon, 1 Oct 2018 at 21:45, Carl Sverre <sverre(dot)carl(at)gmail(dot)com> wrote:
> > Dean,
> > Thank you for the pointer towards visibility/volatility. I think that
> completely explains the effect that I am seeing in my repro. I
> experimented with using a VOLATILE function for the SELECT RLS using
> statement and while it completely solves my issue, it incurs too high a
> cost for query execution due to the RLS policy no longer being inlined into
> the scan.
> >
> > I have documented your answer and my experimentation on the stack
> overflow answer:
> >
> https://stackoverflow.com/questions/52565720/postgres-trigger-side-effect-is-occurring-out-of-order-with-row-level-security-s
> >
>
> I had a quick look at that and found a bug in your implementation. The
> RLS check function is defined as follows:
>
> CREATE OR REPLACE FUNCTION rlsCheck(id text) RETURNS TABLE (id text) AS $$
> select * from b where b.id = id
> $$ LANGUAGE sql VOLATILE;
>
> which is incorrect because of the ambiguous reference to "id". That
> final "id" will, by default, refer to the table column b.id, not the
> parameter "id". Thus that function will return every row of b, and
> your check won't be doing what you want. That's also going to hurt
> performance, but you didn't provide enough information to diagnose the
> actual performance problem that you are seeing.
>
> In any case, the above needs to be written as
>
> CREATE OR REPLACE FUNCTION rlsCheck(text) RETURNS TABLE (id text) AS $$
> select id from b where b.id = $1
> $$ LANGUAGE sql VOLATILE;
>
> to work as expected.
>
> Regards,
> Dean
>

Attachment Content-Type Size
rls_performance_notes application/octet-stream 2.8 KB

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Martin Mueller 2018-10-02 20:38:36 metadata about creation and size of tables
Previous Message Francisco Olarte 2018-10-02 17:47:52 Re: pg_sleep() inside plpgsql block - pro & cons