diff --git a/__fixtures__/generated/generated.json b/__fixtures__/generated/generated.json index a9ad7570..557e5fcb 100644 --- a/__fixtures__/generated/generated.json +++ b/__fixtures__/generated/generated.json @@ -21256,6 +21256,12 @@ "misc/quotes_etc-28.sql": "DO $$\nBEGIN\n RAISE NOTICE 'Line one\\nLine two';\nEND;\n$$ LANGUAGE plpgsql", "misc/quotes_etc-29.sql": "CREATE USER MAPPING FOR local_user SERVER \"foreign_server\" OPTIONS (user 'remote_user', password 'secret123')", "misc/quotes_etc-30.sql": "CREATE USER MAPPING FOR local_user SERVER foreign_server OPTIONS (user 'remote_user', password 'secret123')", + "misc/policy-quoted-names-1.sql": "CREATE POLICY \"Users can view own data\" ON public.todos FOR SELECT TO authenticated USING (auth.uid() = user_id)", + "misc/policy-quoted-names-2.sql": "DROP POLICY \"Users can view own data\" ON public.todos", + "misc/policy-quoted-names-3.sql": "DROP POLICY IF EXISTS \"Users can view own data\" ON todos", + "misc/policy-quoted-names-4.sql": "COMMENT ON POLICY \"Users can view own data\" ON public.todos IS 'owner read'", + "misc/policy-quoted-names-5.sql": "COMMENT ON POLICY \"Users can view own data\" ON todos IS 'owner read'", + "misc/policy-quoted-names-6.sql": "ALTER POLICY \"Users can view own data\" ON public.todos RENAME TO \"Owners read\"", "misc/pg_catalog-1.sql": "SELECT json_object('{}')", "misc/pg_catalog-2.sql": "SELECT * FROM generate_series(1, 5)", "misc/pg_catalog-3.sql": "SELECT get_byte(E'\\\\xDEADBEEF'::bytea, 1)", diff --git a/__fixtures__/kitchen-sink/misc/policy-quoted-names.sql b/__fixtures__/kitchen-sink/misc/policy-quoted-names.sql new file mode 100644 index 00000000..a83eba92 --- /dev/null +++ b/__fixtures__/kitchen-sink/misc/policy-quoted-names.sql @@ -0,0 +1,7 @@ +-- Policy names that need quoting (Supabase-style names with spaces) +CREATE POLICY "Users can view own data" ON public.todos FOR SELECT TO authenticated USING (auth.uid() = user_id); +DROP POLICY "Users can view own data" ON public.todos; +DROP POLICY IF EXISTS "Users can view own data" ON todos; +COMMENT ON POLICY "Users can view own data" ON public.todos IS 'owner read'; +COMMENT ON POLICY "Users can view own data" ON todos IS 'owner read'; +ALTER POLICY "Users can view own data" ON public.todos RENAME TO "Owners read"; diff --git a/packages/deparser/__tests__/kitchen-sink/misc-policy-quoted-names.test.ts b/packages/deparser/__tests__/kitchen-sink/misc-policy-quoted-names.test.ts new file mode 100644 index 00000000..1ea0db41 --- /dev/null +++ b/packages/deparser/__tests__/kitchen-sink/misc-policy-quoted-names.test.ts @@ -0,0 +1,14 @@ + +import { FixtureTestUtils } from '../../test-utils'; +const fixtures = new FixtureTestUtils(); + +it('misc-policy-quoted-names', async () => { + await fixtures.runFixtureTests([ + "misc/policy-quoted-names-1.sql", + "misc/policy-quoted-names-2.sql", + "misc/policy-quoted-names-3.sql", + "misc/policy-quoted-names-4.sql", + "misc/policy-quoted-names-5.sql", + "misc/policy-quoted-names-6.sql" +]); +}); diff --git a/packages/deparser/src/deparser.ts b/packages/deparser/src/deparser.ts index 94c7f625..70b14361 100644 --- a/packages/deparser/src/deparser.ts +++ b/packages/deparser/src/deparser.ts @@ -4699,7 +4699,7 @@ export class Deparser implements DeparserVisitor { if (objList && (objList as any).List && (objList as any).List.items) { const items = (objList as any).List.items.map((item: any) => { if (item.String && item.String.sval) { - return item.String.sval; + return QuoteUtils.quoteIdentifier(item.String.sval); } return this.visit(item, context); }); @@ -7156,7 +7156,12 @@ export class Deparser implements DeparserVisitor { } } else if (node.objtype === 'OBJECT_POLICY') { // Handle POLICY syntax: COMMENT ON POLICY policy_name ON table_name IS 'comment' - if (objectParts.length === 2) { + if (objectParts.length === 3) { + const [schema, table, policy] = objectParts; + output.push(policy); + output.push('ON'); + output.push(`${schema}.${table}`); + } else if (objectParts.length === 2) { const [table, policy] = objectParts; output.push(policy); output.push('ON');