Skip to content

Commit 1998874

Browse files
yoavcloudayman-sigma
authored andcommitted
PostgreSQL: ALTER USER password option (apache#2142)
1 parent 8245ef6 commit 1998874

3 files changed

Lines changed: 63 additions & 4 deletions

File tree

src/ast/mod.rs

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

1014310143
/// Modifies the properties of a user
1014410144
///
10145-
/// Syntax:
10145+
/// [Snowflake Syntax:](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
1014610146
/// ```sql
1014710147
/// ALTER USER [ IF EXISTS ] [ <name> ] [ OPTIONS ]
1014810148
/// ```
1014910149
///
10150-
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
10150+
/// [PostgreSQL Syntax:](https://www.postgresql.org/docs/current/sql-alteruser.html)
10151+
/// ```sql
10152+
/// ALTER USER <role_specification> [ WITH ] option [ ... ]
10153+
/// ```
1015110154
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1015210155
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1015310156
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
@@ -10171,6 +10174,8 @@ pub struct AlterUser {
1017110174
pub unset_tag: Vec<String>,
1017210175
pub set_props: KeyValueOptions,
1017310176
pub unset_props: Vec<String>,
10177+
/// The following options are PostgreSQL-specific: <https://www.postgresql.org/docs/current/sql-alteruser.html>
10178+
pub password: Option<AlterUserPassword>,
1017410179
}
1017510180

1017610181
/// ```sql
@@ -10347,6 +10352,34 @@ impl fmt::Display for AlterUser {
1034710352
if !self.unset_props.is_empty() {
1034810353
write!(f, " UNSET {}", display_comma_separated(&self.unset_props))?;
1034910354
}
10355+
if let Some(password) = &self.password {
10356+
write!(f, " {}", password)?;
10357+
}
10358+
Ok(())
10359+
}
10360+
}
10361+
10362+
/// ```sql
10363+
/// ALTER USER <role_specification> [ WITH ] PASSWORD { 'password' | NULL }``
10364+
/// ```
10365+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10366+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10367+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10368+
pub struct AlterUserPassword {
10369+
pub encrypted: bool,
10370+
pub password: Option<String>,
10371+
}
10372+
10373+
impl Display for AlterUserPassword {
10374+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10375+
if self.encrypted {
10376+
write!(f, "ENCRYPTED ")?;
10377+
}
10378+
write!(f, "PASSWORD")?;
10379+
match &self.password {
10380+
None => write!(f, " NULL")?,
10381+
Some(password) => write!(f, " '{}'", value::escape_single_quote_string(password))?,
10382+
}
1035010383
Ok(())
1035110384
}
1035210385
}

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
@@ -17976,6 +17976,15 @@ fn test_parse_alter_user() {
1797617976
_ => unreachable!(),
1797717977
}
1797817978
verified_stmt("ALTER USER u1 SET DEFAULT_SECONDARY_ROLES=('ALL'), PASSWORD='secret', WORKLOAD_IDENTITY=(TYPE=AWS, ARN='arn:aws:iam::123456789:r1/')");
17979+
17980+
verified_stmt("ALTER USER u1 PASSWORD 'AAA'");
17981+
verified_stmt("ALTER USER u1 ENCRYPTED PASSWORD 'AAA'");
17982+
verified_stmt("ALTER USER u1 PASSWORD NULL");
17983+
17984+
one_statement_parses_to(
17985+
"ALTER USER u1 WITH PASSWORD 'AAA'",
17986+
"ALTER USER u1 PASSWORD 'AAA'",
17987+
);
1797917988
}
1798017989

1798117990
#[test]

0 commit comments

Comments
 (0)