I am using PostgreSQL 10.1, going right to the point...
Lets say I have a TABLE:
CREATE TABLE public.document (
id
Try following:
Instead of writing the query into the USING(...)
clause put the query into a STABLE
function with a very high cost.
By doing so the function should not be called very often now - ideally only once per query lifetime, because the cost of calling the function seems now very high to Postgres. Marking the function as STABLE
tells Postgres that the result of the function doesn't change during a single query lifetime. I think that is correct for your query, isn't it?
Read more about about this two parameters here.
Like this:
CREATE OR REPLACE FUNCTION check_permission () RETURNS BOOLEAN AS $$
SELECT EXISTS (
SELECT 1 FROM public.user WHERE (is_current_user) AND ('r' = ANY(privileges))
)
$$ LANGUAGE SQL STABLE COST 100000;
And the policy now:
CREATE POLICY document_policy ON public.document FOR SELECT
USING (check_permission());
Hopefully this will give you better performance. But be aware, this only works correctly if it is OK to mark the function as STABLE
. If your function could return different results during a single query lifetime then this wouldn't work correctly and you would end up with weird results.