585 lines
19 KiB
SQL
585 lines
19 KiB
SQL
-- ============================================================
|
|
-- Migration 051: RLS Performance Fixes
|
|
-- Addresses all Supabase linter warnings:
|
|
-- 1. auth_rls_initplan: wrap auth.uid() in (select auth.uid())
|
|
-- 2. multiple_permissive_policies: consolidate overlapping policies
|
|
-- ============================================================
|
|
|
|
-- ============================================================
|
|
-- PART 1: Fix auth_rls_initplan
|
|
-- Replace auth.uid() with (select auth.uid()) in ALL RLS policies
|
|
-- using a dynamic DO block that reads pg_policies catalog
|
|
-- ============================================================
|
|
|
|
DO $$
|
|
DECLARE
|
|
r record;
|
|
qual_new text;
|
|
check_new text;
|
|
cmd_parts text[];
|
|
sql_cmd text;
|
|
BEGIN
|
|
FOR r IN
|
|
SELECT
|
|
schemaname,
|
|
tablename,
|
|
policyname,
|
|
permissive,
|
|
roles,
|
|
cmd AS policy_cmd,
|
|
qual,
|
|
with_check
|
|
FROM pg_policies
|
|
WHERE schemaname = 'public'
|
|
AND (
|
|
qual ~ 'auth\.uid\(\)' AND qual !~ '\(\s*select\s+auth\.uid\(\)\s*\)'
|
|
OR
|
|
with_check ~ 'auth\.uid\(\)' AND with_check !~ '\(\s*select\s+auth\.uid\(\)\s*\)'
|
|
)
|
|
LOOP
|
|
-- Replace auth.uid() with (select auth.uid()) in USING clause
|
|
qual_new := r.qual;
|
|
IF qual_new IS NOT NULL THEN
|
|
-- Avoid double-wrapping: only replace bare auth.uid() not already in (select ...)
|
|
qual_new := regexp_replace(qual_new, '(?<!\(select )auth\.uid\(\)', '(select auth.uid())', 'gi');
|
|
END IF;
|
|
|
|
-- Replace auth.uid() with (select auth.uid()) in WITH CHECK clause
|
|
check_new := r.with_check;
|
|
IF check_new IS NOT NULL THEN
|
|
check_new := regexp_replace(check_new, '(?<!\(select )auth\.uid\(\)', '(select auth.uid())', 'gi');
|
|
END IF;
|
|
|
|
-- Drop old policy
|
|
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
|
|
r.policyname, r.schemaname, r.tablename);
|
|
|
|
-- Build CREATE POLICY command
|
|
sql_cmd := format('CREATE POLICY %I ON %I.%I', r.policyname, r.schemaname, r.tablename);
|
|
|
|
-- AS PERMISSIVE/RESTRICTIVE
|
|
IF r.permissive = 'false' THEN
|
|
sql_cmd := sql_cmd || ' AS RESTRICTIVE';
|
|
END IF;
|
|
|
|
-- FOR command
|
|
sql_cmd := sql_cmd || ' FOR ' || r.policy_cmd;
|
|
|
|
-- TO roles
|
|
sql_cmd := sql_cmd || ' TO ' || array_to_string(r.roles, ', ');
|
|
|
|
-- USING clause
|
|
IF qual_new IS NOT NULL THEN
|
|
sql_cmd := sql_cmd || ' USING (' || qual_new || ')';
|
|
END IF;
|
|
|
|
-- WITH CHECK clause
|
|
IF check_new IS NOT NULL THEN
|
|
sql_cmd := sql_cmd || ' WITH CHECK (' || check_new || ')';
|
|
END IF;
|
|
|
|
EXECUTE sql_cmd;
|
|
|
|
RAISE NOTICE 'Fixed initplan: %.% policy "%"', r.schemaname, r.tablename, r.policyname;
|
|
END LOOP;
|
|
END;
|
|
$$;
|
|
|
|
|
|
-- ============================================================
|
|
-- PART 2: Fix multiple_permissive_policies
|
|
-- Pattern A: Tables with "Org members can view X" (SELECT) +
|
|
-- "Editors can manage X" (FOR ALL) → drop the SELECT policy
|
|
-- since FOR ALL already covers SELECT.
|
|
-- Pattern B: Tables with "Platform admins full access" (FOR ALL) +
|
|
-- "Editors can manage X" (FOR ALL) → merge platform admin
|
|
-- check into the editors policy, drop the platform admin policy.
|
|
-- Pattern C: Tables with "Org members can view X" (SELECT) +
|
|
-- "Members can manage X" (FOR ALL) → same as Pattern A.
|
|
-- ============================================================
|
|
|
|
-- --------------------------------------------------------
|
|
-- Pattern A: Drop redundant SELECT-only policies
|
|
-- These tables have both "view" (SELECT) and "manage" (FOR ALL)
|
|
-- The FOR ALL already covers SELECT, making the view policy redundant
|
|
-- --------------------------------------------------------
|
|
|
|
-- sponsors
|
|
DROP POLICY IF EXISTS "Org members can view sponsors" ON public.sponsors;
|
|
|
|
-- sponsor_deliverables
|
|
DROP POLICY IF EXISTS "Org members can view sponsor deliverables" ON public.sponsor_deliverables;
|
|
|
|
-- sponsor_tiers
|
|
DROP POLICY IF EXISTS "Org members can view sponsor tiers" ON public.sponsor_tiers;
|
|
|
|
-- documents
|
|
DROP POLICY IF EXISTS "Org members can view documents" ON public.documents;
|
|
|
|
-- kanban_boards
|
|
DROP POLICY IF EXISTS "Org members can view boards" ON public.kanban_boards;
|
|
|
|
-- kanban_columns
|
|
DROP POLICY IF EXISTS "Org members can view columns" ON public.kanban_columns;
|
|
|
|
-- kanban_cards
|
|
DROP POLICY IF EXISTS "Org members can view cards" ON public.kanban_cards;
|
|
|
|
-- calendar_events
|
|
DROP POLICY IF EXISTS "Org members can view events" ON public.calendar_events;
|
|
|
|
-- events
|
|
DROP POLICY IF EXISTS "Org members can view events" ON public.events;
|
|
|
|
-- event_members
|
|
DROP POLICY IF EXISTS "Org members can view event members" ON public.event_members;
|
|
|
|
-- event_roles
|
|
DROP POLICY IF EXISTS "Org members can view event roles" ON public.event_roles;
|
|
|
|
-- event_departments
|
|
DROP POLICY IF EXISTS "Org members can view event departments" ON public.event_departments;
|
|
|
|
-- event_member_departments
|
|
DROP POLICY IF EXISTS "Org members can view member departments" ON public.event_member_departments;
|
|
|
|
-- event_task_columns
|
|
DROP POLICY IF EXISTS "Org members can view event task columns" ON public.event_task_columns;
|
|
|
|
-- event_tasks
|
|
DROP POLICY IF EXISTS "Org members can view event tasks" ON public.event_tasks;
|
|
|
|
-- department_dashboards
|
|
DROP POLICY IF EXISTS "Org members can view department dashboards" ON public.department_dashboards;
|
|
|
|
-- dashboard_panels
|
|
DROP POLICY IF EXISTS "Org members can view dashboard panels" ON public.dashboard_panels;
|
|
|
|
-- department_checklists
|
|
DROP POLICY IF EXISTS "Org members can view department checklists" ON public.department_checklists;
|
|
|
|
-- department_checklist_items
|
|
DROP POLICY IF EXISTS "Org members can view dept checklist items" ON public.department_checklist_items;
|
|
|
|
-- department_notes
|
|
DROP POLICY IF EXISTS "Org members can view department notes" ON public.department_notes;
|
|
|
|
-- checklist_items
|
|
DROP POLICY IF EXISTS "Org members can view checklist items" ON public.checklist_items;
|
|
|
|
-- budget_categories
|
|
DROP POLICY IF EXISTS "Org members can view budget categories" ON public.budget_categories;
|
|
|
|
-- budget_items
|
|
DROP POLICY IF EXISTS "Org members can view budget items" ON public.budget_items;
|
|
|
|
-- card_tags: "Users can view card tags" + "Members can manage card tags" (FOR ALL)
|
|
DROP POLICY IF EXISTS "Users can view card tags in their orgs" ON public.card_tags;
|
|
|
|
-- document_locks: "Anyone can delete expired locks" + "Users can delete their own locks"
|
|
-- Merge into single DELETE policy
|
|
DROP POLICY IF EXISTS "Anyone can delete expired locks" ON public.document_locks;
|
|
DROP POLICY IF EXISTS "Users can delete their own locks" ON public.document_locks;
|
|
CREATE POLICY "Users can delete locks" ON public.document_locks
|
|
FOR DELETE
|
|
USING (
|
|
user_id = (select auth.uid())
|
|
OR last_heartbeat < (now() - interval '2 minutes')
|
|
);
|
|
|
|
|
|
-- --------------------------------------------------------
|
|
-- Pattern B: Merge "Platform admins full access" into existing policies
|
|
-- For tables that have both "Editors can manage X" and
|
|
-- "Platform admins full access to X", we merge the admin check
|
|
-- into the editors policy using OR is_platform_admin(), then
|
|
-- drop the separate platform admin policy.
|
|
-- --------------------------------------------------------
|
|
|
|
-- Note: The is_platform_admin() function was already fixed in migration 039
|
|
-- to use (select auth.uid()). We just need to merge the policies.
|
|
|
|
-- For tables with platform admin policies, we need to update the
|
|
-- "Editors can manage" policy to include OR (select public.is_platform_admin())
|
|
-- then drop the platform admin policy.
|
|
|
|
-- calendar_events
|
|
DROP POLICY IF EXISTS "Platform admins full access to calendar_events" ON public.calendar_events;
|
|
DROP POLICY IF EXISTS "Editors can manage events" ON public.calendar_events;
|
|
CREATE POLICY "Editors can manage events" ON public.calendar_events
|
|
FOR ALL
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = calendar_events.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = calendar_events.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
-- documents
|
|
DROP POLICY IF EXISTS "Platform admins full access to documents" ON public.documents;
|
|
DROP POLICY IF EXISTS "Editors can manage documents" ON public.documents;
|
|
CREATE POLICY "Editors can manage documents" ON public.documents
|
|
FOR ALL
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = documents.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = documents.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
-- events
|
|
DROP POLICY IF EXISTS "Platform admins full access to events" ON public.events;
|
|
DROP POLICY IF EXISTS "Editors can manage events" ON public.events;
|
|
CREATE POLICY "Editors can manage events" ON public.events
|
|
FOR ALL
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = events.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = events.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
-- event_members
|
|
DROP POLICY IF EXISTS "Platform admins full access to event_members" ON public.event_members;
|
|
DROP POLICY IF EXISTS "Editors can manage event members" ON public.event_members;
|
|
CREATE POLICY "Editors can manage event members" ON public.event_members
|
|
FOR ALL
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.events e
|
|
JOIN public.org_members om ON om.org_id = e.org_id
|
|
WHERE e.id = event_members.event_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.events e
|
|
JOIN public.org_members om ON om.org_id = e.org_id
|
|
WHERE e.id = event_members.event_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
-- event_departments
|
|
DROP POLICY IF EXISTS "Platform admins full access to event_departments" ON public.event_departments;
|
|
DROP POLICY IF EXISTS "Editors can manage event departments" ON public.event_departments;
|
|
CREATE POLICY "Editors can manage event departments" ON public.event_departments
|
|
FOR ALL
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.events e
|
|
JOIN public.org_members om ON om.org_id = e.org_id
|
|
WHERE e.id = event_departments.event_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.events e
|
|
JOIN public.org_members om ON om.org_id = e.org_id
|
|
WHERE e.id = event_departments.event_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
-- kanban_boards
|
|
DROP POLICY IF EXISTS "Platform admins full access to kanban_boards" ON public.kanban_boards;
|
|
DROP POLICY IF EXISTS "Editors can manage boards" ON public.kanban_boards;
|
|
CREATE POLICY "Editors can manage boards" ON public.kanban_boards
|
|
FOR ALL
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = kanban_boards.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = kanban_boards.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
-- org_roles
|
|
DROP POLICY IF EXISTS "Platform admins full access to org_roles" ON public.org_roles;
|
|
-- org_roles has "Org members can view roles" + "Admins can manage roles"
|
|
DROP POLICY IF EXISTS "Org members can view roles" ON public.org_roles;
|
|
DROP POLICY IF EXISTS "Admins can manage roles" ON public.org_roles;
|
|
CREATE POLICY "Admins can manage roles" ON public.org_roles
|
|
FOR ALL
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = org_roles.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
AND om.role IN ('owner', 'admin')
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = org_roles.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
AND om.role IN ('owner', 'admin')
|
|
)
|
|
);
|
|
-- Org members still need to SELECT roles (for UI dropdowns etc)
|
|
CREATE POLICY "Org members can view roles" ON public.org_roles
|
|
FOR SELECT
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = org_roles.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
-- org_invites
|
|
DROP POLICY IF EXISTS "Platform admins full access to org_invites" ON public.org_invites;
|
|
-- org_invites has "Org members can view invites" + "Admins can manage invites"
|
|
DROP POLICY IF EXISTS "Org members can view invites" ON public.org_invites;
|
|
DROP POLICY IF EXISTS "Admins can manage invites" ON public.org_invites;
|
|
CREATE POLICY "Admins can manage invites" ON public.org_invites
|
|
FOR ALL
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = org_invites.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
AND om.role IN ('owner', 'admin')
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = org_invites.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
AND om.role IN ('owner', 'admin')
|
|
)
|
|
);
|
|
-- Org members still need to SELECT invites
|
|
CREATE POLICY "Org members can view invites" ON public.org_invites
|
|
FOR SELECT
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = org_invites.org_id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
-- organizations
|
|
DROP POLICY IF EXISTS "Platform admins full access to organizations" ON public.organizations;
|
|
-- organizations already has separate view/update/delete policies, platform admin just adds another FOR ALL
|
|
-- Merge into existing policies by adding OR is_platform_admin()
|
|
DROP POLICY IF EXISTS "Members can view their organizations" ON public.organizations;
|
|
CREATE POLICY "Members can view their organizations" ON public.organizations
|
|
FOR SELECT
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = organizations.id
|
|
AND om.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
DROP POLICY IF EXISTS "Owners and admins can update organizations" ON public.organizations;
|
|
CREATE POLICY "Owners and admins can update organizations" ON public.organizations
|
|
FOR UPDATE
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = organizations.id
|
|
AND om.user_id = (select auth.uid())
|
|
AND om.role IN ('owner', 'admin')
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = organizations.id
|
|
AND om.user_id = (select auth.uid())
|
|
AND om.role IN ('owner', 'admin')
|
|
)
|
|
);
|
|
|
|
DROP POLICY IF EXISTS "Owners can delete organizations" ON public.organizations;
|
|
CREATE POLICY "Owners can delete organizations" ON public.organizations
|
|
FOR DELETE
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om
|
|
WHERE om.org_id = organizations.id
|
|
AND om.user_id = (select auth.uid())
|
|
AND om.role = 'owner'
|
|
)
|
|
);
|
|
|
|
-- org_members
|
|
DROP POLICY IF EXISTS "Platform admins full access to org_members" ON public.org_members;
|
|
-- org_members has separate view/manage/delete policies + Allow member inserts
|
|
-- Just add platform admin to the view policy
|
|
DROP POLICY IF EXISTS "Members can view org members" ON public.org_members;
|
|
CREATE POLICY "Members can view org members" ON public.org_members
|
|
FOR SELECT
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om2
|
|
WHERE om2.org_id = org_members.org_id
|
|
AND om2.user_id = (select auth.uid())
|
|
)
|
|
);
|
|
|
|
DROP POLICY IF EXISTS "Owners and admins can manage members" ON public.org_members;
|
|
CREATE POLICY "Owners and admins can manage members" ON public.org_members
|
|
FOR UPDATE
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om2
|
|
WHERE om2.org_id = org_members.org_id
|
|
AND om2.user_id = (select auth.uid())
|
|
AND om2.role IN ('owner', 'admin')
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om2
|
|
WHERE om2.org_id = org_members.org_id
|
|
AND om2.user_id = (select auth.uid())
|
|
AND om2.role IN ('owner', 'admin')
|
|
)
|
|
);
|
|
|
|
DROP POLICY IF EXISTS "Owners and admins can delete members" ON public.org_members;
|
|
CREATE POLICY "Owners and admins can delete members" ON public.org_members
|
|
FOR DELETE
|
|
USING (
|
|
(select public.is_platform_admin())
|
|
OR EXISTS (
|
|
SELECT 1 FROM public.org_members om2
|
|
WHERE om2.org_id = org_members.org_id
|
|
AND om2.user_id = (select auth.uid())
|
|
AND om2.role IN ('owner', 'admin')
|
|
)
|
|
);
|
|
|
|
|
|
-- ============================================================
|
|
-- PART 3: Run the initplan fixer AGAIN after Part 2
|
|
-- Part 2 created new policies that may still use bare auth.uid()
|
|
-- in the USING/WITH CHECK from the original policy definitions.
|
|
-- This second pass catches any remaining bare auth.uid() calls.
|
|
-- ============================================================
|
|
|
|
DO $$
|
|
DECLARE
|
|
r record;
|
|
qual_new text;
|
|
check_new text;
|
|
sql_cmd text;
|
|
BEGIN
|
|
FOR r IN
|
|
SELECT
|
|
schemaname,
|
|
tablename,
|
|
policyname,
|
|
permissive,
|
|
roles,
|
|
cmd AS policy_cmd,
|
|
qual,
|
|
with_check
|
|
FROM pg_policies
|
|
WHERE schemaname = 'public'
|
|
AND (
|
|
qual ~ 'auth\.uid\(\)' AND qual !~ '\(\s*select\s+auth\.uid\(\)\s*\)'
|
|
OR
|
|
with_check ~ 'auth\.uid\(\)' AND with_check !~ '\(\s*select\s+auth\.uid\(\)\s*\)'
|
|
)
|
|
LOOP
|
|
qual_new := r.qual;
|
|
IF qual_new IS NOT NULL THEN
|
|
qual_new := regexp_replace(qual_new, '(?<!\(select )auth\.uid\(\)', '(select auth.uid())', 'gi');
|
|
END IF;
|
|
|
|
check_new := r.with_check;
|
|
IF check_new IS NOT NULL THEN
|
|
check_new := regexp_replace(check_new, '(?<!\(select )auth\.uid\(\)', '(select auth.uid())', 'gi');
|
|
END IF;
|
|
|
|
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
|
|
r.policyname, r.schemaname, r.tablename);
|
|
|
|
sql_cmd := format('CREATE POLICY %I ON %I.%I', r.policyname, r.schemaname, r.tablename);
|
|
|
|
IF r.permissive = 'false' THEN
|
|
sql_cmd := sql_cmd || ' AS RESTRICTIVE';
|
|
END IF;
|
|
|
|
sql_cmd := sql_cmd || ' FOR ' || r.policy_cmd;
|
|
sql_cmd := sql_cmd || ' TO ' || array_to_string(r.roles, ', ');
|
|
|
|
IF qual_new IS NOT NULL THEN
|
|
sql_cmd := sql_cmd || ' USING (' || qual_new || ')';
|
|
END IF;
|
|
|
|
IF check_new IS NOT NULL THEN
|
|
sql_cmd := sql_cmd || ' WITH CHECK (' || check_new || ')';
|
|
END IF;
|
|
|
|
EXECUTE sql_cmd;
|
|
|
|
RAISE NOTICE 'Fixed initplan (pass 2): %.% policy "%"', r.schemaname, r.tablename, r.policyname;
|
|
END LOOP;
|
|
END;
|
|
$$;
|