diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 176d36545..3657ee798 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -2924,6 +2924,15 @@ pub enum Set { /// MySQL-style /// SET a = 1, b = 2, ..; MultipleAssignments { assignments: Vec }, + /// Session authorization for Postgres/Redshift + /// + /// ```sql + /// SET SESSION AUTHORIZATION { user_name | DEFAULT } + /// ``` + /// + /// See + /// See + SetSessionAuthorization(SetSessionAuthorizationParam), /// MS-SQL session /// /// See @@ -2998,6 +3007,7 @@ impl Display for Set { modifier = context_modifier.map(|m| format!("{m}")).unwrap_or_default() ) } + Self::SetSessionAuthorization(kind) => write!(f, "SET SESSION AUTHORIZATION {kind}"), Self::SetSessionParam(kind) => write!(f, "SET {kind}"), Self::SetTransaction { modes, @@ -9818,6 +9828,42 @@ impl fmt::Display for TableObject { } } +/// Represents a SET SESSION AUTHORIZATION statement +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub struct SetSessionAuthorizationParam { + pub scope: ContextModifier, + pub kind: SetSessionAuthorizationParamKind, +} + +impl fmt::Display for SetSessionAuthorizationParam { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.kind) + } +} + +/// Represents the parameter kind for SET SESSION AUTHORIZATION +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub enum SetSessionAuthorizationParamKind { + /// Default authorization + Default, + + /// User name + User(Ident), +} + +impl fmt::Display for SetSessionAuthorizationParamKind { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SetSessionAuthorizationParamKind::Default => write!(f, "DEFAULT"), + SetSessionAuthorizationParamKind::User(name) => write!(f, "{}", name), + } + } +} + #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 9a01e510b..904ea9f1c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -13104,6 +13104,18 @@ impl<'a> Parser<'a> { session: false, } .into()); + } else if self.parse_keyword(Keyword::AUTHORIZATION) { + let auth_value = if self.parse_keyword(Keyword::DEFAULT) { + SetSessionAuthorizationParamKind::Default + } else { + let value = self.parse_identifier()?; + SetSessionAuthorizationParamKind::User(value) + }; + return Ok(Set::SetSessionAuthorization(SetSessionAuthorizationParam { + scope: scope.expect("SET ... AUTHORIZATION must have a scope"), + kind: auth_value, + }) + .into()); } if self.dialect.supports_comma_separated_set_assignments() { diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index f1ba5df04..4469c91ce 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -17632,3 +17632,28 @@ fn parse_generic_unary_ops() { ); } } + +#[test] +fn test_parse_set_session_authorization() { + let stmt = verified_stmt("SET SESSION AUTHORIZATION DEFAULT"); + assert_eq!( + stmt, + Statement::Set(Set::SetSessionAuthorization(SetSessionAuthorizationParam { + scope: ContextModifier::Session, + kind: SetSessionAuthorizationParamKind::Default, + })) + ); + + let stmt = verified_stmt("SET SESSION AUTHORIZATION 'username'"); + assert_eq!( + stmt, + Statement::Set(Set::SetSessionAuthorization(SetSessionAuthorizationParam { + scope: ContextModifier::Session, + kind: SetSessionAuthorizationParamKind::User(Ident { + value: "username".to_string(), + quote_style: Some('\''), + span: Span::empty(), + }), + })) + ); +}