Skip to content

perf(rls): wrap RLS policy functions in (select ...) for per-statement evaluation#7

Open
dmitrymaranik wants to merge 1 commit into
getpact:mainfrom
dmitrymaranik:perf/wrap-rls-initplan
Open

perf(rls): wrap RLS policy functions in (select ...) for per-statement evaluation#7
dmitrymaranik wants to merge 1 commit into
getpact:mainfrom
dmitrymaranik:perf/wrap-rls-initplan

Conversation

@dmitrymaranik

Copy link
Copy Markdown

Closes #6.

The per-user / per-tenant RLS policies call their session function (auth.uid() / current_setting(...)) directly in USING/WITH CHECK, which Postgres re-evaluates once per row. This wraps each call in a scalar subquery so the planner evaluates it once per statement (an InitPlan) and caches it — the optimization Supabase documents for RLS.

  • Predicate-equivalent(select f()) returns the same value, so row visibility is unchanged.
  • Verified with the static analyzer that flagged it (pgrls): the PERF001 findings on these policies clear to 0 after the change, with nothing else altered.
  • Added as a new migration (0038_wrap_rls_perf_initplan.sql); the SQL is pgrls fix --rule PERF001 output.

Happy to adjust the migration filename/placement to your conventions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RLS perf: wrap current_setting() in (select …) so tenant_isolation evaluates per-statement

1 participant