Skip to content

Commit 2322226

Browse files
committed
PostgreSQL: ALTER USER password option
1 parent 24e1283 commit 2322226

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

src/ast/mod.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10108,12 +10108,15 @@ impl fmt::Display for CreateUser {
1010810108

1010910109
/// Modifies the properties of a user
1011010110
///
10111-
/// Syntax:
10111+
/// [Snowflake Syntax]:
1011210112
/// ```sql
1011310113
/// ALTER USER [ IF EXISTS ] [ <name> ] [ OPTIONS ]
1011410114
/// ```
1011510115
///
10116-
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
10116+
/// [PostgreSQL Syntax]:(https://www.postgresql.org/docs/current/sql-alteruser.html)
10117+
/// ```sql
10118+
/// ALTER USER <role_specification> [ WITH ] option [ ... ]
10119+
/// ```
1011710120
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1011810121
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1011910122
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
@@ -10137,6 +10140,8 @@ pub struct AlterUser {
1013710140
pub unset_tag: Vec<String>,
1013810141
pub set_props: KeyValueOptions,
1013910142
pub unset_props: Vec<String>,
10143+
/// The following options are PostgreSQL-specific: <https://www.postgresql.org/docs/current/sql-alteruser.html>
10144+
pub password: Option<AlterUserPassword>,
1014010145
}
1014110146

1014210147
/// ```sql
@@ -10313,6 +10318,34 @@ impl fmt::Display for AlterUser {
1031310318
if !self.unset_props.is_empty() {
1031410319
write!(f, " UNSET {}", display_comma_separated(&self.unset_props))?;
1031510320
}
10321+
if let Some(password) = &self.password {
10322+
write!(f, " {}", password)?;
10323+
}
10324+
Ok(())
10325+
}
10326+
}
10327+
10328+
/// ```sql
10329+
/// ALTER USER <role_specification> [ WITH ] PASSWORD { 'password' | NULL }``
10330+
/// ```
10331+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10332+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10333+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10334+
pub struct AlterUserPassword {
10335+
pub encrypted: bool,
10336+
pub password: Option<String>,
10337+
}
10338+
10339+
impl Display for AlterUserPassword {
10340+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10341+
write!(f, "PASSWORD")?;
10342+
if self.encrypted {
10343+
write!(f, " ENCRYPTED")?;
10344+
}
10345+
match &self.password {
10346+
None => write!(f, " NULL")?,
10347+
Some(password) => write!(f, " '{}'", value::escape_single_quote_string(password))?,
10348+
}
1031610349
Ok(())
1031710350
}
1031810351
}

src/parser/alter.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use crate::{
2121
helpers::key_value_options::{KeyValueOptions, KeyValueOptionsDelimiter},
2222
AlterConnectorOwner, AlterPolicyOperation, AlterRoleOperation, AlterUser,
2323
AlterUserAddMfaMethodOtp, AlterUserAddRoleDelegation, AlterUserModifyMfaMethod,
24-
AlterUserRemoveRoleDelegation, AlterUserSetPolicy, Expr, MfaMethodKind, Password,
25-
ResetConfig, RoleOption, SetConfigValue, Statement, UserPolicyKind,
24+
AlterUserPassword, AlterUserRemoveRoleDelegation, AlterUserSetPolicy, Expr, MfaMethodKind,
25+
Password, ResetConfig, RoleOption, SetConfigValue, Statement, UserPolicyKind,
2626
},
2727
dialect::{MsSqlDialect, PostgreSqlDialect},
2828
keywords::Keyword,
@@ -150,6 +150,7 @@ impl Parser<'_> {
150150
pub fn parse_alter_user(&mut self) -> Result<Statement, ParserError> {
151151
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
152152
let name = self.parse_identifier()?;
153+
let _ = self.parse_keyword(Keyword::WITH);
153154
let rename_to = if self.parse_keywords(&[Keyword::RENAME, Keyword::TO]) {
154155
Some(self.parse_identifier()?)
155156
} else {
@@ -292,6 +293,24 @@ impl Parser<'_> {
292293
vec![]
293294
};
294295

296+
let encrypted = self.parse_keyword(Keyword::ENCRYPTED);
297+
let password = if self.parse_keyword(Keyword::PASSWORD) {
298+
if self.parse_keyword(Keyword::NULL) {
299+
Some(AlterUserPassword {
300+
encrypted,
301+
password: None,
302+
})
303+
} else {
304+
let password = self.parse_literal_string()?;
305+
Some(AlterUserPassword {
306+
encrypted,
307+
password: Some(password),
308+
})
309+
}
310+
} else {
311+
None
312+
};
313+
295314
Ok(Statement::AlterUser(AlterUser {
296315
if_exists,
297316
name,
@@ -311,6 +330,7 @@ impl Parser<'_> {
311330
unset_tag,
312331
set_props,
313332
unset_props,
333+
password,
314334
}))
315335
}
316336

tests/sqlparser_common.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17950,6 +17950,12 @@ fn test_parse_alter_user() {
1795017950
_ => unreachable!(),
1795117951
}
1795217952
verified_stmt("ALTER USER u1 SET DEFAULT_SECONDARY_ROLES=('ALL'), PASSWORD='secret', WORKLOAD_IDENTITY=(TYPE=AWS, ARN='arn:aws:iam::123456789:r1/')");
17953+
17954+
verified_stmt("ALTER USER u1 PASSWORD 'AAA'");
17955+
one_statement_parses_to(
17956+
"ALTER USER u1 WITH PASSWORD 'AAA'",
17957+
"ALTER USER u1 PASSWORD 'AAA'",
17958+
);
1795317959
}
1795417960

1795517961
#[test]

0 commit comments

Comments
 (0)