-
Notifications
You must be signed in to change notification settings - Fork 32
Description
Problem
When using pgschema plan against a database with RLS policies that reference functions in the public schema, pgschema reports changes even when the policies are semantically identical. This creates a perpetual diff that reappears after every apply.
Reproduction
- Create a function and policy:
CREATE FUNCTION public.auth_uid() RETURNS uuid AS $$
SELECT gen_random_uuid();
$$ LANGUAGE sql;
CREATE TABLE public.users (
id uuid PRIMARY KEY,
org_id uuid NOT NULL
);
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;
CREATE POLICY "select_own" ON public.users FOR SELECT
USING (org_id IN (SELECT auth_uid()));- Create a schema file with the same policy (using unqualified
auth_uid()):
CREATE POLICY "select_own" ON public.users FOR SELECT
USING (org_id IN (SELECT auth_uid()));-
Run
pgschema plan --schema public- it shows a modification even though nothing changed. -
Run
pgschema apply- applies the "change". -
Run
pgschema planagain - the same modification reappears.
Root Cause
There's a mismatch between how pgschema normalizes expressions and how PostgreSQL stores them:
| Stage | Expression |
|---|---|
| Schema file | auth_uid() |
| pgschema internal representation | public.auth_uid() (adds schema prefix) |
| DDL generated by pgschema | SELECT public.auth_uid() AS auth_uid |
| PostgreSQL stores (via pg_get_expr) | auth_uid() (strips public. since it's in search_path) |
When pgschema compares desired vs actual:
- Desired (after pgschema normalization):
public.auth_uid() - Actual (from pg_get_expr):
auth_uid() - Result: perpetual diff
Relation to Issue #218
This is similar to #218 ("Schema qualifiers stripped from column default expressions"), but in the opposite direction and for a different object type:
| Aspect | #218 | This Issue |
|---|---|---|
| Object type | Column defaults | Policy USING/WITH CHECK |
| Direction | pgschema was losing qualification | pgschema is adding qualification |
| Fix approach | Normalization during comparison | Same approach could work |
The #218 fix added normalization logic to treat ::public.status and ::status as equivalent during comparison. A similar normalization for function calls in policy expressions would resolve this issue.
Expected Behavior
pgschema plan should show no changes when the policy expressions are semantically equivalent, regardless of whether the function reference is schema-qualified.
Environment
- pgschema version: 1.5.1
- PostgreSQL version: 15.x (via Supabase local)
- Target schema:
public