Skip to content

Commit

Permalink
Support all possible role specifications in GRANT/REVOKE
Browse files Browse the repository at this point in the history
  • Loading branch information
nene committed Nov 30, 2024
1 parent 8782a41 commit a3c97e6
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 6 deletions.
26 changes: 23 additions & 3 deletions src/cst/Dcl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { BaseNode, Keyword } from "./Base";
import { Identifier, ListExpr, EntityName, Expr, ParenExpr } from "./Expr";
import {
Identifier,
ListExpr,
EntityName,
Expr,
ParenExpr,
FuncCall,
} from "./Expr";
import { FunctionSignature } from "./Function";
import { StringLiteral } from "./Literal";

Expand All @@ -8,7 +15,9 @@ export type AllDclNodes =
| Privilege
| AllPrivileges
| GrantResource
| GrantedByClause;
| GrantedByClause
| GranteeGroup
| GranteePublic;

export type AllDclStatements =
| GrantRoleStmt
Expand Down Expand Up @@ -241,4 +250,15 @@ export interface RevokePrivilegeStmt extends BaseNode {
behaviorKw: Keyword<"CASCADE" | "RESTRICT">;
}

type Grantee = Identifier;
type Grantee = Identifier | FuncCall | GranteeGroup | GranteePublic;

export interface GranteeGroup extends BaseNode {
type: "grantee_group";
groupKw: Keyword<"GROUP">;
name: Identifier;
}

export interface GranteePublic extends BaseNode {
type: "grantee_public";
publicKw: Keyword<"PUBLIC">;
}
27 changes: 24 additions & 3 deletions src/parser.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -4754,7 +4754,7 @@ grant_role_stmt
grant_privilege_stmt
= kw:(GRANT __) privileges:((list$privilege / all_privileges) __)
onKw:(ON __) resource:(grant_resource __)
toKw:(TO __) roles:(list$role_specification)
toKw:(TO __) roles:(list$grantee)
withKw:(__ WITH __ GRANT __ OPTION)?
grantedBy:(__ granted_by_clause)? {
return loc({
Expand Down Expand Up @@ -4854,7 +4854,7 @@ grant_resource
}

granted_by_clause
= kw:(GRANTED __ BY __) role:role_specification {
= kw:(GRANTED __ BY __) role:grantee {
return loc({ type: "granted_by_clause", grantedByKw: read(kw), role });
}

Expand Down Expand Up @@ -4884,7 +4884,7 @@ revoke_privilege_stmt
= kw:(REVOKE __) grantOptionForKw:(GRANT __ OPTION __ FOR __)?
privileges:((list$privilege / all_privileges) __)
onKw:(ON __) resource:(grant_resource __)
fromKw:(FROM __) roles:list$role_specification
fromKw:(FROM __) roles:list$grantee
grantedBy:(__ granted_by_clause)?
behaviorKw:(__ (CASCADE / RESTRICT))? {
return loc({
Expand All @@ -4909,6 +4909,25 @@ revoke_privilege_stmt
* ------------------------------------------------------------------------------------ *
*/

grantee
= kw:GROUP name:(__ ident) {
return loc({ type: "grantee_group", groupKw: kw, name: read(name) });
}
/ kw:PUBLIC {
return loc({ type: "grantee_public", publicKw: kw });
}
/ name:grantee_fn_name {
return loc({ type: "func_call", name });
}
/ name:ident {
return name;
}

grantee_fn_name
= kw:(CURRENT_ROLE / CURRENT_USER / SESSION_USER) {
return loc(createIdentifier(kw.text, kw.text));
}

// user_name or CURRENT_USER, SESSION_USER, CURRENT_ROLE
role_specification
= paren_less_func_call / ident
Expand Down Expand Up @@ -7464,6 +7483,7 @@ list$expr_or_default = .
list$expr_or_explicit_alias = .
list$func_param = .
list$function_signature = .
list$grantee = .
list$grouping_element = .
list$ident = .
list$index_specification = .
Expand Down Expand Up @@ -8833,6 +8853,7 @@ PRIVILEGES = kw:"PRIVILEGES"i !ident_part { return loc(createK
PROCEDURE = kw:"PROCEDURE"i !ident_part { return loc(createKeyword(kw)); }
PROCEDURES = kw:"PROCEDURES"i !ident_part { return loc(createKeyword(kw)); }
PROJECT = kw:"PROJECT"i !ident_part { return loc(createKeyword(kw)); }
PUBLIC = kw:"PUBLIC"i !ident_part { return loc(createKeyword(kw)); }
QUALIFY = kw:"QUALIFY"i !ident_part { return loc(createKeyword(kw)); }
QUARTER = kw:"QUARTER"i !ident_part { return loc(createKeyword(kw)); }
QUERY = kw:"QUERY"i !ident_part { return loc(createKeyword(kw)); }
Expand Down
3 changes: 3 additions & 0 deletions src/showNode/dcl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,7 @@ export const dclMap: FullTransformMap<string, AllDclNodes> = {
node.grantedBy,
node.behaviorKw,
]),

grantee_group: (node) => show([node.groupKw, node.name]),
grantee_public: (node) => show([node.publicKw]),
};
7 changes: 7 additions & 0 deletions test/dcl/grant.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ describe("GRANT", () => {
it(`supports GRANTED BY clause`, () => {
testWc(`GRANT DELETE ON tbl TO johnny GRANTED BY happy_admin`);
});

["CURRENT_ROLE", "CURRENT_USER", "SESSION_USER", "PUBLIC", "GROUP foo"].forEach((role) => {
it(`supports granting to ${role}`, () => {
testWc(`GRANT SELECT ON tbl TO ${role}`);
testWc(`GRANT SELECT ON tbl TO foo GRANTED BY ${role}`);
});
});
});

dialect(["mysql", "mariadb", "sqlite"], () => {
Expand Down
7 changes: 7 additions & 0 deletions test/dcl/revoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ describe("REVOKE", () => {
testWc(`REVOKE DELETE ON tbl FROM johnny RESTRICT`);
testWc(`REVOKE DELETE ON tbl FROM johnny GRANTED BY foo CASCADE`);
});

["CURRENT_ROLE", "CURRENT_USER", "SESSION_USER", "PUBLIC", "GROUP foo"].forEach((role) => {
it(`supports revoking from ${role}`, () => {
testWc(`REVOKE SELECT ON tbl FROM ${role}`);
testWc(`REVOKE DELETE ON tbl FROM johnny GRANTED BY ${role}`);
});
});
});

dialect(["mysql", "mariadb", "sqlite"], () => {
Expand Down

0 comments on commit a3c97e6

Please sign in to comment.