Skip to content

Commit ab76a07

Browse files
authored
PostgreSQL: ALTER USER password option (#2142)
1 parent 24e1283 commit ab76a07

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:](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
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+
if self.encrypted {
10342+
write!(f, "ENCRYPTED ")?;
10343+
}
10344+
write!(f, "PASSWORD")?;
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: 19 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,21 @@ impl Parser<'_> {
292293
vec![]
293294
};
294295

296+
let encrypted = self.parse_keyword(Keyword::ENCRYPTED);
297+
let password = if self.parse_keyword(Keyword::PASSWORD) {
298+
let password = if self.parse_keyword(Keyword::NULL) {
299+
None
300+
} else {
301+
Some(self.parse_literal_string()?)
302+
};
303+
Some(AlterUserPassword {
304+
encrypted,
305+
password,
306+
})
307+
} else {
308+
None
309+
};
310+
295311
Ok(Statement::AlterUser(AlterUser {
296312
if_exists,
297313
name,
@@ -311,6 +327,7 @@ impl Parser<'_> {
311327
unset_tag,
312328
set_props,
313329
unset_props,
330+
password,
314331
}))
315332
}
316333

tests/sqlparser_common.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17950,6 +17950,15 @@ 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+
verified_stmt("ALTER USER u1 ENCRYPTED PASSWORD 'AAA'");
17956+
verified_stmt("ALTER USER u1 PASSWORD NULL");
17957+
17958+
one_statement_parses_to(
17959+
"ALTER USER u1 WITH PASSWORD 'AAA'",
17960+
"ALTER USER u1 PASSWORD 'AAA'",
17961+
);
1795317962
}
1795417963

1795517964
#[test]

0 commit comments

Comments
 (0)