Skip to content

Commit f97efc2

Browse files
committed
Code review feedback
1 parent a39cade commit f97efc2

File tree

3 files changed

+93
-32
lines changed

3 files changed

+93
-32
lines changed

src/ast/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10131,6 +10131,14 @@ impl fmt::Display for MemberOf {
1013110131
}
1013210132
}
1013310133

10134+
/// Creates a user
10135+
///
10136+
/// Syntax:
10137+
/// ```sql
10138+
/// CREATE [OR REPLACE] USER [IF NOT EXISTS] <name> [OPTIONS]
10139+
/// ```
10140+
///
10141+
/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
1013410142
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1013510143
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1013610144
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]

src/parser/mod.rs

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4721,7 +4721,7 @@ impl<'a> Parser<'a> {
47214721
}
47224722
}
47234723

4724-
pub fn parse_create_user(&mut self, or_replace: bool) -> Result<Statement, ParserError> {
4724+
fn parse_create_user(&mut self, or_replace: bool) -> Result<Statement, ParserError> {
47254725
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
47264726
let name = self.parse_identifier()?;
47274727
let options = self.parse_key_value_options(false, &[Keyword::WITH, Keyword::TAG])?;
@@ -16683,43 +16683,38 @@ impl<'a> Parser<'a> {
1668316683
Ok(options)
1668416684
}
1668516685

16686-
// Parses a `KEY = VALUE` construct based on the specified key
16686+
/// Parses a `KEY = VALUE` construct based on the specified key
1668716687
pub(crate) fn parse_key_value_option(
1668816688
&mut self,
1668916689
key: Word,
1669016690
) -> Result<KeyValueOption, ParserError> {
1669116691
self.expect_token(&Token::Eq)?;
16692-
if self.parse_keyword(Keyword::TRUE) {
16693-
Ok(KeyValueOption {
16694-
option_name: key.value,
16695-
option_type: KeyValueOptionType::BOOLEAN,
16696-
value: "TRUE".to_string(),
16697-
})
16698-
} else if self.parse_keyword(Keyword::FALSE) {
16699-
Ok(KeyValueOption {
16692+
match self.next_token().token {
16693+
Token::SingleQuotedString(value) => Ok(KeyValueOption {
1670016694
option_name: key.value,
16701-
option_type: KeyValueOptionType::BOOLEAN,
16702-
value: "FALSE".to_string(),
16703-
})
16704-
} else {
16705-
match self.next_token().token {
16706-
Token::SingleQuotedString(value) => Ok(KeyValueOption {
16707-
option_name: key.value,
16708-
option_type: KeyValueOptionType::STRING,
16709-
value,
16710-
}),
16711-
Token::Word(word) => Ok(KeyValueOption {
16712-
option_name: key.value,
16713-
option_type: KeyValueOptionType::ENUM,
16714-
value: word.value,
16715-
}),
16716-
Token::Number(n, _) => Ok(KeyValueOption {
16695+
option_type: KeyValueOptionType::STRING,
16696+
value,
16697+
}),
16698+
Token::Word(word)
16699+
if word.keyword == Keyword::TRUE || word.keyword == Keyword::FALSE =>
16700+
{
16701+
Ok(KeyValueOption {
1671716702
option_name: key.value,
16718-
option_type: KeyValueOptionType::NUMBER,
16719-
value: n,
16720-
}),
16721-
_ => self.expected("expected option value", self.peek_token()),
16703+
option_type: KeyValueOptionType::BOOLEAN,
16704+
value: word.value.to_uppercase(),
16705+
})
1672216706
}
16707+
Token::Word(word) => Ok(KeyValueOption {
16708+
option_name: key.value,
16709+
option_type: KeyValueOptionType::ENUM,
16710+
value: word.value,
16711+
}),
16712+
Token::Number(n, _) => Ok(KeyValueOption {
16713+
option_name: key.value,
16714+
option_type: KeyValueOptionType::NUMBER,
16715+
value: n,
16716+
}),
16717+
_ => self.expected("expected option value", self.peek_token()),
1672316718
}
1672416719
}
1672516720
}

tests/sqlparser_common.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ extern crate core;
2727

2828
use helpers::attached_token::AttachedToken;
2929
use matches::assert_matches;
30+
use sqlparser::ast::helpers::key_value_options::*;
31+
use sqlparser::ast::helpers::key_value_options::{KeyValueOptions, KeyValueOptionsDelimiter};
3032
use sqlparser::ast::SelectItem::UnnamedExpr;
3133
use sqlparser::ast::TableFactor::{Pivot, Unpivot};
3234
use sqlparser::ast::*;
@@ -16259,13 +16261,69 @@ fn parse_notnull() {
1625916261

1626016262
#[test]
1626116263
fn parse_create_user() {
16262-
verified_stmt("CREATE USER u1");
16264+
let create = verified_stmt("CREATE USER u1");
16265+
match create {
16266+
Statement::CreateUser(stmt) => {
16267+
assert_eq!(stmt.name, Ident::new("u1"));
16268+
}
16269+
_ => unreachable!(),
16270+
}
1626316271
verified_stmt("CREATE OR REPLACE USER u1");
1626416272
verified_stmt("CREATE OR REPLACE USER IF NOT EXISTS u1");
1626516273
verified_stmt("CREATE OR REPLACE USER IF NOT EXISTS u1 PASSWORD='secret'");
1626616274
verified_stmt(
1626716275
"CREATE OR REPLACE USER IF NOT EXISTS u1 PASSWORD='secret' MUST_CHANGE_PASSWORD=TRUE",
1626816276
);
1626916277
verified_stmt("CREATE OR REPLACE USER IF NOT EXISTS u1 PASSWORD='secret' MUST_CHANGE_PASSWORD=TRUE TYPE=SERVICE TAG (t1='v1')");
16270-
verified_stmt("CREATE OR REPLACE USER IF NOT EXISTS u1 PASSWORD='secret' MUST_CHANGE_PASSWORD=TRUE TYPE=SERVICE WITH TAG (t1='v1', t2='v2')");
16278+
let create = verified_stmt("CREATE OR REPLACE USER IF NOT EXISTS u1 PASSWORD='secret' MUST_CHANGE_PASSWORD=TRUE TYPE=SERVICE WITH TAG (t1='v1', t2='v2')");
16279+
match create {
16280+
Statement::CreateUser(stmt) => {
16281+
assert_eq!(stmt.name, Ident::new("u1"));
16282+
assert_eq!(stmt.or_replace, true);
16283+
assert_eq!(stmt.if_not_exists, true);
16284+
assert_eq!(
16285+
stmt.options,
16286+
KeyValueOptions {
16287+
delimiter: KeyValueOptionsDelimiter::Space,
16288+
options: vec![
16289+
KeyValueOption {
16290+
option_name: "PASSWORD".to_string(),
16291+
value: "secret".to_string(),
16292+
option_type: KeyValueOptionType::STRING
16293+
},
16294+
KeyValueOption {
16295+
option_name: "MUST_CHANGE_PASSWORD".to_string(),
16296+
value: "TRUE".to_string(),
16297+
option_type: KeyValueOptionType::BOOLEAN
16298+
},
16299+
KeyValueOption {
16300+
option_name: "TYPE".to_string(),
16301+
value: "SERVICE".to_string(),
16302+
option_type: KeyValueOptionType::ENUM
16303+
},
16304+
],
16305+
},
16306+
);
16307+
assert_eq!(stmt.with_tags, true);
16308+
assert_eq!(
16309+
stmt.tags,
16310+
KeyValueOptions {
16311+
delimiter: KeyValueOptionsDelimiter::Comma,
16312+
options: vec![
16313+
KeyValueOption {
16314+
option_name: "t1".to_string(),
16315+
value: "v1".to_string(),
16316+
option_type: KeyValueOptionType::STRING
16317+
},
16318+
KeyValueOption {
16319+
option_name: "t2".to_string(),
16320+
value: "v2".to_string(),
16321+
option_type: KeyValueOptionType::STRING
16322+
},
16323+
]
16324+
}
16325+
);
16326+
}
16327+
_ => unreachable!(),
16328+
}
1627116329
}

0 commit comments

Comments
 (0)