Skip to content

Commit c3e9e07

Browse files
slhmyMazterQyou
authored andcommitted
Support 'SET ROLE' statement (apache#455)
1 parent ac5fc7c commit c3e9e07

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

src/ast/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,16 @@ pub enum Statement {
10131013
/// Note: this is a PostgreSQL-specific statement,
10141014
/// but may also compatible with other SQL.
10151015
Discard { object_type: DiscardObject },
1016+
/// SET [ SESSION | LOCAL ] ROLE role_name
1017+
///
1018+
/// Note: this is a PostgreSQL-specific statement,
1019+
/// but may also compatible with other SQL.
1020+
SetRole {
1021+
local: bool,
1022+
// SESSION is the default if neither SESSION nor LOCAL appears.
1023+
session: bool,
1024+
role_name: Option<Ident>,
1025+
},
10161026
/// SET <variable>
10171027
///
10181028
/// Note: this is not a standard SQL statement, but it is supported by at
@@ -1755,6 +1765,24 @@ impl fmt::Display for Statement {
17551765
write!(f, "DISCARD {object_type}", object_type = object_type)?;
17561766
Ok(())
17571767
}
1768+
Statement::SetRole {
1769+
local,
1770+
session,
1771+
role_name,
1772+
} => {
1773+
write!(
1774+
f,
1775+
"SET {local}{session}ROLE",
1776+
local = if *local { "LOCAL " } else { "" },
1777+
session = if *session { "SESSION " } else { "" },
1778+
)?;
1779+
if let Some(role_name) = role_name {
1780+
write!(f, " {}", role_name)?;
1781+
} else {
1782+
f.write_str(" NONE")?;
1783+
}
1784+
Ok(())
1785+
}
17581786
Statement::SetVariable { key_values } => {
17591787
f.write_str("SET ")?;
17601788

src/parser.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3681,6 +3681,17 @@ impl<'a> Parser<'a> {
36813681
.to_vec(),
36823682
});
36833683
}
3684+
} else if self.parse_keyword(Keyword::ROLE) {
3685+
let role_name = if self.parse_keyword(Keyword::NONE) {
3686+
None
3687+
} else {
3688+
Some(self.parse_identifier()?)
3689+
};
3690+
return Ok(Statement::SetRole {
3691+
local: modifier == Some(Keyword::LOCAL),
3692+
session: modifier == Some(Keyword::SESSION),
3693+
role_name,
3694+
});
36843695
}
36853696

36863697
let mut key_values: Vec<SetVariableKeyValue> = vec![];

tests/sqlparser_postgres.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,45 @@ fn parse_set() {
906906
);
907907
}
908908

909+
#[test]
910+
fn parse_set_role() {
911+
let stmt = pg_and_generic().verified_stmt("SET SESSION ROLE NONE");
912+
assert_eq!(
913+
stmt,
914+
Statement::SetRole {
915+
local: false,
916+
session: true,
917+
role_name: None,
918+
}
919+
);
920+
921+
let stmt = pg_and_generic().verified_stmt("SET LOCAL ROLE \"rolename\"");
922+
assert_eq!(
923+
stmt,
924+
Statement::SetRole {
925+
local: true,
926+
session: false,
927+
role_name: Some(Ident {
928+
value: "rolename".to_string(),
929+
quote_style: Some('\"'),
930+
}),
931+
}
932+
);
933+
934+
let stmt = pg_and_generic().verified_stmt("SET ROLE 'rolename'");
935+
assert_eq!(
936+
stmt,
937+
Statement::SetRole {
938+
local: false,
939+
session: false,
940+
role_name: Some(Ident {
941+
value: "rolename".to_string(),
942+
quote_style: Some('\''),
943+
}),
944+
}
945+
);
946+
}
947+
909948
#[test]
910949
fn parse_show() {
911950
let stmt = pg_and_generic().verified_stmt("SHOW a a");

0 commit comments

Comments
 (0)