mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-03 22:08:16 +00:00
Disambiguate CREATE ROLE ... USER and GROUP (#628)
This commit is contained in:
parent
2b21da2439
commit
6afd194e94
3 changed files with 56 additions and 8 deletions
|
@ -1117,6 +1117,7 @@ pub enum Statement {
|
|||
if_not_exists: bool,
|
||||
},
|
||||
/// CREATE ROLE
|
||||
/// See [postgres](https://www.postgresql.org/docs/current/sql-createrole.html)
|
||||
CreateRole {
|
||||
names: Vec<ObjectName>,
|
||||
if_not_exists: bool,
|
||||
|
@ -1132,7 +1133,9 @@ pub enum Statement {
|
|||
connection_limit: Option<Expr>,
|
||||
valid_until: Option<Expr>,
|
||||
in_role: Vec<Ident>,
|
||||
in_group: Vec<Ident>,
|
||||
role: Vec<Ident>,
|
||||
user: Vec<Ident>,
|
||||
admin: Vec<Ident>,
|
||||
// MSSQL
|
||||
authorization_owner: Option<ObjectName>,
|
||||
|
@ -2005,7 +2008,9 @@ impl fmt::Display for Statement {
|
|||
connection_limit,
|
||||
valid_until,
|
||||
in_role,
|
||||
in_group,
|
||||
role,
|
||||
user,
|
||||
admin,
|
||||
authorization_owner,
|
||||
} => {
|
||||
|
@ -2064,9 +2069,15 @@ impl fmt::Display for Statement {
|
|||
if !in_role.is_empty() {
|
||||
write!(f, " IN ROLE {}", display_comma_separated(in_role))?;
|
||||
}
|
||||
if !in_group.is_empty() {
|
||||
write!(f, " IN GROUP {}", display_comma_separated(in_group))?;
|
||||
}
|
||||
if !role.is_empty() {
|
||||
write!(f, " ROLE {}", display_comma_separated(role))?;
|
||||
}
|
||||
if !user.is_empty() {
|
||||
write!(f, " USER {}", display_comma_separated(user))?;
|
||||
}
|
||||
if !admin.is_empty() {
|
||||
write!(f, " ADMIN {}", display_comma_separated(admin))?;
|
||||
}
|
||||
|
|
|
@ -2109,7 +2109,9 @@ impl<'a> Parser<'a> {
|
|||
let mut connection_limit = None;
|
||||
let mut valid_until = None;
|
||||
let mut in_role = vec![];
|
||||
let mut roles = vec![];
|
||||
let mut in_group = vec![];
|
||||
let mut role = vec![];
|
||||
let mut user = vec![];
|
||||
let mut admin = vec![];
|
||||
|
||||
while let Some(keyword) = self.parse_one_of_keywords(&optional_keywords) {
|
||||
|
@ -2209,22 +2211,37 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
Keyword::IN => {
|
||||
if self.parse_keyword(Keyword::ROLE) || self.parse_keyword(Keyword::GROUP) {
|
||||
if self.parse_keyword(Keyword::ROLE) {
|
||||
if !in_role.is_empty() {
|
||||
parser_err!("Found multiple IN ROLE or IN GROUP")
|
||||
parser_err!("Found multiple IN ROLE")
|
||||
} else {
|
||||
in_role = self.parse_comma_separated(Parser::parse_identifier)?;
|
||||
Ok(())
|
||||
}
|
||||
} else if self.parse_keyword(Keyword::GROUP) {
|
||||
if !in_group.is_empty() {
|
||||
parser_err!("Found multiple IN GROUP")
|
||||
} else {
|
||||
in_group = self.parse_comma_separated(Parser::parse_identifier)?;
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
self.expected("ROLE or GROUP after IN", self.peek_token())
|
||||
}
|
||||
}
|
||||
Keyword::ROLE | Keyword::USER => {
|
||||
if !roles.is_empty() {
|
||||
parser_err!("Found multiple ROLE or USER")
|
||||
Keyword::ROLE => {
|
||||
if !role.is_empty() {
|
||||
parser_err!("Found multiple ROLE")
|
||||
} else {
|
||||
roles = self.parse_comma_separated(Parser::parse_identifier)?;
|
||||
role = self.parse_comma_separated(Parser::parse_identifier)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Keyword::USER => {
|
||||
if !user.is_empty() {
|
||||
parser_err!("Found multiple USER")
|
||||
} else {
|
||||
user = self.parse_comma_separated(Parser::parse_identifier)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -2254,7 +2271,9 @@ impl<'a> Parser<'a> {
|
|||
connection_limit,
|
||||
valid_until,
|
||||
in_role,
|
||||
role: roles,
|
||||
in_group,
|
||||
role,
|
||||
user,
|
||||
admin,
|
||||
authorization_owner,
|
||||
})
|
||||
|
|
|
@ -1807,7 +1807,9 @@ fn parse_create_role() {
|
|||
connection_limit,
|
||||
valid_until,
|
||||
in_role,
|
||||
in_group,
|
||||
role,
|
||||
user,
|
||||
admin,
|
||||
authorization_owner,
|
||||
}],
|
||||
|
@ -1833,13 +1835,29 @@ fn parse_create_role() {
|
|||
Some(Expr::Value(Value::SingleQuotedString("2025-01-01".into())))
|
||||
);
|
||||
assert_eq_vec(&["role1", "role2"], in_role);
|
||||
assert!(in_group.is_empty());
|
||||
assert_eq_vec(&["role3"], role);
|
||||
assert!(user.is_empty());
|
||||
assert_eq_vec(&["role4", "role5"], admin);
|
||||
assert_eq!(*authorization_owner, None);
|
||||
}
|
||||
err => panic!("Failed to parse CREATE ROLE test case: {:?}", err),
|
||||
}
|
||||
|
||||
let sql = "CREATE ROLE abc WITH USER foo, bar ROLE baz ";
|
||||
match pg().parse_sql_statements(sql).as_deref() {
|
||||
Ok(
|
||||
[Statement::CreateRole {
|
||||
names, user, role, ..
|
||||
}],
|
||||
) => {
|
||||
assert_eq_vec(&["abc"], names);
|
||||
assert_eq_vec(&["foo", "bar"], user);
|
||||
assert_eq_vec(&["baz"], role);
|
||||
}
|
||||
err => panic!("Failed to parse CREATE ROLE test case: {:?}", err),
|
||||
}
|
||||
|
||||
let negatables = vec![
|
||||
"BYPASSRLS",
|
||||
"CREATEDB",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue