Files
windmill/backend/migrations
Ruben FiszelandClaude Opus 4.8 e9fd4e7554 perf(rls): wrap session GUC reads in RLS policies for per-statement InitPlan (GIT-919) (#10110)
* perf(rls): wrap session GUC reads in RLS policies for per-statement InitPlan

RLS policies read current_setting('session.user' / 'session.groups' /
'session.pgroups' / 'session.folders_read' / 'session.folders_write')
directly inside their USING / WITH CHECK predicates. Postgres treats those
unwrapped calls as potentially row-varying and re-evaluates them once per
scanned row, on the read path of every workspace-scoped table.

The GUCs are set with SET LOCAL (set_config(..., true)) in
set_session_context(), so they are constant for the duration of a statement.
Wrapping each session-derived subexpression in a scalar sub-select lets the
planner hoist it to a one-time InitPlan (evaluated once per statement, reused
for every row) — same rows in, same rows out, N per-row GUC lookups collapse
to 1. Array-producing subexpressions keep an explicit ::text[] cast on the
sub-select so `= ANY (...)` / `?|` stay in their array-operand form rather
than being reparsed as a row-returning subquery.

The consolidating migration recreates every existing policy (across ~30 prior
migrations) whose predicate reads a session GUC, by deparsing the current
predicate and substituting the wrapped forms; the down migration is the exact
inverse (byte-identical round-trip). The adding-a-trigger skill documents the
wrapped form so new trigger tables inherit it.

Surfaced by pgrls (PERF001).

Fixes GIT-919

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(adding-a-trigger): fix RLS example cast placement for = any context

The `= any(...)` example put the ::text[] cast inside the sub-select, which
Postgres parses as a row-returning subquery and rejects at CREATE POLICY with
`operator does not exist: text = text[]`. Move the cast outside the sub-select
(matching the migration's canonical form) so the operand stays in array form,
and note why.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 08:56:05 +02:00
..
2022-05-05 04:25:58 +02:00
2022-05-05 04:25:58 +02:00
2022-05-05 04:25:58 +02:00
2022-05-05 04:25:58 +02:00
2022-05-05 04:25:58 +02:00
2022-05-05 04:25:58 +02:00
2022-05-05 04:25:58 +02:00
2022-11-26 19:39:37 +01:00
v2
2023-11-22 18:29:51 +01:00
v2
2023-11-22 18:29:51 +01:00