Skip to content

Commit 759ab21

Browse files
authored
PostgreSQL: add GrantObjects::Types and Domains for GRANT ON TYPE/DOMAIN (#24)
`GRANT USAGE ON TYPE foo TO role` and `GRANT ON DOMAIN d TO role` are valid PostgreSQL grammar but failed to parse — `parse_grant_target` had no `TYPE` or `DOMAIN` keyword, and `GrantObjects` lacked variants to carry them. Add `GrantObjects::Types(Vec<ObjectName>)` and `GrantObjects::Domains(Vec<ObjectName>)`, along with their `Display` arms, the `Keyword::TYPE` / `Keyword::DOMAIN` arms in `parse_grant_deny_revoke_privileges_objects`, and round-trip tests in `parse_grant`. Verified: cargo fmt --all -- --check cargo clippy --all-targets --all-features -- -D warnings cargo test --all-features parse_grant
1 parent 6bfcc10 commit 759ab21

3 files changed

Lines changed: 63 additions & 0 deletions

File tree

src/ast/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7749,6 +7749,18 @@ pub enum GrantObjects {
77497749
/// Optional argument types for overloaded functions.
77507750
arg_types: Vec<DataType>,
77517751
},
7752+
7753+
/// Grant privileges on specific user-defined types (PostgreSQL).
7754+
///
7755+
/// For example:
7756+
/// `GRANT USAGE ON TYPE user_role TO app_user`
7757+
Types(Vec<ObjectName>),
7758+
7759+
/// Grant privileges on specific domains (PostgreSQL).
7760+
///
7761+
/// For example:
7762+
/// `GRANT USAGE ON DOMAIN email_addr TO app_user`
7763+
Domains(Vec<ObjectName>),
77527764
}
77537765

77547766
impl fmt::Display for GrantObjects {
@@ -7894,6 +7906,12 @@ impl fmt::Display for GrantObjects {
78947906
}
78957907
Ok(())
78967908
}
7909+
GrantObjects::Types(types) => {
7910+
write!(f, "TYPE {}", display_comma_separated(types))
7911+
}
7912+
GrantObjects::Domains(domains) => {
7913+
write!(f, "DOMAIN {}", display_comma_separated(domains))
7914+
}
78977915
}
78987916
}
78997917
}

src/parser/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17908,6 +17908,8 @@ impl<'a> Parser<'a> {
1790817908
Keyword::CONNECTION,
1790917909
Keyword::PROCEDURE,
1791017910
Keyword::FUNCTION,
17911+
Keyword::TYPE,
17912+
Keyword::DOMAIN,
1791117913
]);
1791217914
let objects =
1791317915
self.parse_comma_separated(|p| p.parse_object_name_inner(false, true));
@@ -17920,6 +17922,8 @@ impl<'a> Parser<'a> {
1792017922
Some(Keyword::VIEW) => Some(GrantObjects::Views(objects?)),
1792117923
Some(Keyword::USER) => Some(GrantObjects::Users(objects?)),
1792217924
Some(Keyword::CONNECTION) => Some(GrantObjects::Connections(objects?)),
17925+
Some(Keyword::TYPE) => Some(GrantObjects::Types(objects?)),
17926+
Some(Keyword::DOMAIN) => Some(GrantObjects::Domains(objects?)),
1792317927
kw @ (Some(Keyword::PROCEDURE) | Some(Keyword::FUNCTION)) => {
1792417928
if let Some(name) = objects?.first() {
1792517929
self.parse_grant_procedure_or_function(name, &kw)?

tests/sqlparser_common.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9878,6 +9878,47 @@ fn parse_grant() {
98789878
verified_stmt("GRANT ROLE role1 TO ROLE role2");
98799879
verified_stmt("GRANT ROLE role1 TO USER user");
98809880
verified_stmt("GRANT CREATE SCHEMA ON DATABASE db1 TO ROLE role1");
9881+
9882+
let sql_type = "GRANT USAGE ON TYPE user_role TO app_user";
9883+
match verified_stmt(sql_type) {
9884+
Statement::Grant(Grant {
9885+
privileges,
9886+
objects,
9887+
grantees,
9888+
..
9889+
}) => match (privileges, objects) {
9890+
(Privileges::Actions(actions), Some(GrantObjects::Types(types))) => {
9891+
assert_eq!(vec![Action::Usage], actions);
9892+
assert_eq_vec(&["user_role"], &types);
9893+
assert_eq_vec(&["app_user"], &grantees);
9894+
}
9895+
_ => unreachable!(),
9896+
},
9897+
_ => unreachable!(),
9898+
}
9899+
9900+
let sql_domain = "GRANT USAGE ON DOMAIN email_addr TO app_user";
9901+
match verified_stmt(sql_domain) {
9902+
Statement::Grant(Grant {
9903+
privileges,
9904+
objects,
9905+
grantees,
9906+
..
9907+
}) => match (privileges, objects) {
9908+
(Privileges::Actions(actions), Some(GrantObjects::Domains(domains))) => {
9909+
assert_eq!(vec![Action::Usage], actions);
9910+
assert_eq_vec(&["email_addr"], &domains);
9911+
assert_eq_vec(&["app_user"], &grantees);
9912+
}
9913+
_ => unreachable!(),
9914+
},
9915+
_ => unreachable!(),
9916+
}
9917+
9918+
verified_stmt("GRANT USAGE ON TYPE sc1.user_role TO ROLE role1");
9919+
verified_stmt("GRANT ALL ON TYPE t1, t2 TO role1");
9920+
verified_stmt("GRANT USAGE ON DOMAIN sc1.email_addr TO ROLE role1");
9921+
verified_stmt("GRANT ALL ON DOMAIN d1, d2 TO role1");
98819922
}
98829923

98839924
#[test]

0 commit comments

Comments
 (0)