Skip to content

Commit 8f207db

Browse files
authored
Support 'SET ROLE' statement (#455)
1 parent 7480e89 commit 8f207db

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

src/ast/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,16 @@ pub enum Statement {
841841
/// deleted along with the dropped table
842842
purge: bool,
843843
},
844+
/// SET [ SESSION | LOCAL ] ROLE role_name
845+
///
846+
/// Note: this is a PostgreSQL-specific statement,
847+
/// but may also compatible with other SQL.
848+
SetRole {
849+
local: bool,
850+
// SESSION is the default if neither SESSION nor LOCAL appears.
851+
session: bool,
852+
role_name: Option<Ident>,
853+
},
844854
/// SET <variable>
845855
///
846856
/// Note: this is not a standard SQL statement, but it is supported by at
@@ -1453,6 +1463,24 @@ impl fmt::Display for Statement {
14531463
if *cascade { " CASCADE" } else { "" },
14541464
if *purge { " PURGE" } else { "" }
14551465
),
1466+
Statement::SetRole {
1467+
local,
1468+
session,
1469+
role_name,
1470+
} => {
1471+
write!(
1472+
f,
1473+
"SET {local}{session}ROLE",
1474+
local = if *local { "LOCAL " } else { "" },
1475+
session = if *session { "SESSION " } else { "" },
1476+
)?;
1477+
if let Some(role_name) = role_name {
1478+
write!(f, " {}", role_name)?;
1479+
} else {
1480+
f.write_str(" NONE")?;
1481+
}
1482+
Ok(())
1483+
}
14561484
Statement::SetVariable {
14571485
local,
14581486
variable,

src/parser.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3116,7 +3116,19 @@ impl<'a> Parser<'a> {
31163116
self.parse_one_of_keywords(&[Keyword::SESSION, Keyword::LOCAL, Keyword::HIVEVAR]);
31173117
if let Some(Keyword::HIVEVAR) = modifier {
31183118
self.expect_token(&Token::Colon)?;
3119+
} else if self.parse_keyword(Keyword::ROLE) {
3120+
let role_name = if self.parse_keyword(Keyword::NONE) {
3121+
None
3122+
} else {
3123+
Some(self.parse_identifier()?)
3124+
};
3125+
return Ok(Statement::SetRole {
3126+
local: modifier == Some(Keyword::LOCAL),
3127+
session: modifier == Some(Keyword::SESSION),
3128+
role_name,
3129+
});
31193130
}
3131+
31203132
let variable = self.parse_identifier()?;
31213133
if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
31223134
let mut values = vec![];

tests/sqlparser_postgres.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,45 @@ fn parse_set() {
855855
);
856856
}
857857

858+
#[test]
859+
fn parse_set_role() {
860+
let stmt = pg_and_generic().verified_stmt("SET SESSION ROLE NONE");
861+
assert_eq!(
862+
stmt,
863+
Statement::SetRole {
864+
local: false,
865+
session: true,
866+
role_name: None,
867+
}
868+
);
869+
870+
let stmt = pg_and_generic().verified_stmt("SET LOCAL ROLE \"rolename\"");
871+
assert_eq!(
872+
stmt,
873+
Statement::SetRole {
874+
local: true,
875+
session: false,
876+
role_name: Some(Ident {
877+
value: "rolename".to_string(),
878+
quote_style: Some('\"'),
879+
}),
880+
}
881+
);
882+
883+
let stmt = pg_and_generic().verified_stmt("SET ROLE 'rolename'");
884+
assert_eq!(
885+
stmt,
886+
Statement::SetRole {
887+
local: false,
888+
session: false,
889+
role_name: Some(Ident {
890+
value: "rolename".to_string(),
891+
quote_style: Some('\''),
892+
}),
893+
}
894+
);
895+
}
896+
858897
#[test]
859898
fn parse_show() {
860899
let stmt = pg_and_generic().verified_stmt("SHOW a a");

0 commit comments

Comments
 (0)