Skip to content

Commit ab3a50b

Browse files
committed
Format CREATE/ALTER/DROP POLICY
1 parent d724670 commit ab3a50b

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

src/syntax/policy.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { AllPolicyNodes } from "sql-parser-cst";
2+
import { group, join } from "../print_utils";
3+
import { CstToDocMap } from "../CstToDocMap";
4+
5+
export const policyMap: CstToDocMap<AllPolicyNodes> = {
6+
create_policy_stmt: (print, node) =>
7+
group([
8+
print.spaced(["createPolicyKw", "name", "onKw", "table"]),
9+
node.clauses.length > 0 ? print.dynamicLine() : [],
10+
join(print.dynamicLine(), print("clauses")),
11+
]),
12+
13+
policy_permissive_clause: (print) =>
14+
group(print.spaced(["asKw", "permissiveKw"])),
15+
policy_restrictive_clause: (print) =>
16+
group(print.spaced(["asKw", "restrictiveKw"])),
17+
policy_command_clause: (print) => group(print.spaced(["forKw", "commandKw"])),
18+
policy_roles_clause: (print) => group(print.spaced(["toKw", "roles"])),
19+
policy_using_clause: (print) => group(print.spaced(["usingKw", "expr"])),
20+
policy_check_clause: (print) =>
21+
group(print.spaced(["withKw", "checkKw", "expr"])),
22+
23+
alter_policy_stmt: (print) =>
24+
group([
25+
print.spaced(["alterPolicyKw", "name", "onKw", "table"]),
26+
print.dynamicLine(),
27+
join(print.dynamicLine(), print("actions")),
28+
]),
29+
30+
drop_policy_stmt: (print) =>
31+
group(
32+
print.spaced([
33+
"dropPolicyKw",
34+
"ifExistsKw",
35+
"name",
36+
"onKw",
37+
"table",
38+
"behaviorKw",
39+
]),
40+
),
41+
};

src/syntax/transformMap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { mergeMap } from "./merge";
2222
import { otherClausesMap } from "./other_clauses";
2323
import { renameTableMap } from "./rename_table";
2424
import { roleMap } from "./role";
25+
import { policyMap } from "./policy";
2526
import { preparedStatementsMap } from "./prepared_statements";
2627
import { proceduralLanguageMap } from "./procedural_language";
2728
import { procedureMap } from "./procedure";
@@ -64,6 +65,7 @@ export const transformMap: CstToDocMap<Node> = {
6465
...insertMap,
6566
...mergeMap,
6667
...otherClausesMap,
68+
...policyMap,
6769
...preparedStatementsMap,
6870
...procClauseMap,
6971
...proceduralLanguageMap,

test/ddl/policy.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import dedent from "dedent-js";
2+
import { testPostgresql } from "../test_utils";
3+
4+
describe("policy", () => {
5+
describe("create policy", () => {
6+
it(`formats minimal CREATE POLICY`, async () => {
7+
await testPostgresql(dedent`
8+
CREATE POLICY be_kind_policy ON permissions
9+
`);
10+
});
11+
12+
it(`formats single-line short CREATE POLICY`, async () => {
13+
await testPostgresql(dedent`
14+
CREATE POLICY be_kind_policy ON permissions AS PERMISSIVE FOR SELECT
15+
`);
16+
});
17+
18+
it(`formats multi-line short CREATE POLICY (if user prefers)`, async () => {
19+
await testPostgresql(dedent`
20+
CREATE POLICY be_kind_policy ON permissions
21+
AS PERMISSIVE
22+
FOR SELECT
23+
`);
24+
});
25+
26+
it(`formats CREATE POLICY with all possible clauses`, async () => {
27+
await testPostgresql(dedent`
28+
CREATE POLICY be_kind_policy ON permissions
29+
AS RESTRICTIVE
30+
FOR SELECT
31+
TO johnny, sally
32+
USING (kind = 'public')
33+
WITH CHECK (kind = 'public')
34+
`);
35+
});
36+
});
37+
38+
describe("alter policy", () => {
39+
it(`formats ALTER POLICY .. RENAME`, async () => {
40+
await testPostgresql(dedent`
41+
ALTER POLICY be_kind ON users RENAME TO be_evil
42+
`);
43+
});
44+
45+
it(`formats ALTER POLICY .. altering of various clauses`, async () => {
46+
await testPostgresql(dedent`
47+
ALTER POLICY be_kind ON users
48+
TO johnny, sally
49+
USING (kind = 'public')
50+
WITH CHECK (kind = 'public')
51+
`);
52+
});
53+
});
54+
55+
describe("drop policy", () => {
56+
it(`formats basic DROP POLICY`, async () => {
57+
await testPostgresql(dedent`
58+
DROP POLICY be_kind ON admin
59+
`);
60+
});
61+
62+
it(`formats IF EXISTS and CASCADE/RESTRICT`, async () => {
63+
await testPostgresql(dedent`
64+
DROP POLICY IF EXISTS be_kind ON admin CASCADE
65+
`);
66+
});
67+
});
68+
});

0 commit comments

Comments
 (0)