Skip to content

Commit 6ed3a4e

Browse files
authored
feat: Support expression in SET statement (#7)
1 parent db22343 commit 6ed3a4e

File tree

6 files changed

+34
-50
lines changed

6 files changed

+34
-50
lines changed

src/ast/mod.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,32 +1738,15 @@ impl fmt::Display for ShowStatementFilter {
17381738
}
17391739
}
17401740

1741-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1742-
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1743-
pub enum SetVariableValue {
1744-
Ident(Ident),
1745-
Literal(Value),
1746-
}
1747-
17481741
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
17491742
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17501743
pub struct SetVariableKeyValue {
17511744
pub key: Ident,
1752-
pub value: Vec<SetVariableValue>,
1745+
pub value: Vec<Expr>,
17531746
pub local: bool,
17541747
pub hivevar: bool,
17551748
}
17561749

1757-
impl fmt::Display for SetVariableValue {
1758-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1759-
use SetVariableValue::*;
1760-
match self {
1761-
Ident(ident) => write!(f, "{}", ident),
1762-
Literal(literal) => write!(f, "{}", literal),
1763-
}
1764-
}
1765-
}
1766-
17671750
/// Sqlite specific syntax
17681751
///
17691752
/// https://sqlite.org/lang_conflict.html

src/dialect/mysql.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl Dialect for MySqlDialect {
2424
|| ('A'..='Z').contains(&ch)
2525
|| ch == '_'
2626
|| ch == '$'
27+
|| ch == '@'
2728
|| ('\u{0080}'..='\u{ffff}').contains(&ch)
2829
}
2930

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ define_keywords!(
292292
MONTH,
293293
MSCK,
294294
MULTISET,
295+
NAMES,
295296
NATIONAL,
296297
NATURAL,
297298
NCHAR,

src/parser.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2585,9 +2585,7 @@ impl<'a> Parser<'a> {
25852585
_ => (),
25862586
}
25872587

2588-
let variable = self.parse_identifier()?;
2589-
2590-
if variable.value.eq_ignore_ascii_case("NAMES") {
2588+
if self.parse_one_of_keywords(&[Keyword::NAMES]).is_some() {
25912589
let charset_name = self.parse_literal_string()?;
25922590
let collation_name = if self.parse_one_of_keywords(&[Keyword::COLLATE]).is_some() {
25932591
Some(self.parse_literal_string()?)
@@ -2599,8 +2597,6 @@ impl<'a> Parser<'a> {
25992597
charset_name,
26002598
collation_name,
26012599
});
2602-
} else {
2603-
self.prev_token();
26042600
}
26052601

26062602
if let Some(Keyword::HIVEVAR) = modifier {
@@ -2613,12 +2609,12 @@ impl<'a> Parser<'a> {
26132609
let mut values = vec![];
26142610

26152611
loop {
2616-
let token = self.peek_token();
2617-
let value = match (self.parse_value(), token) {
2618-
(Ok(value), _) => SetVariableValue::Literal(value),
2619-
(Err(_), Token::Word(ident)) => SetVariableValue::Ident(ident.to_ident()),
2620-
(Err(_), unexpected) => self.expected("variable value", unexpected)?,
2612+
let value = if let Ok(expr) = self.parse_expr() {
2613+
expr
2614+
} else {
2615+
self.expected("variable value", self.peek_token())?
26212616
};
2617+
26222618
values.push(value);
26232619

26242620
if self.consume_token(&Token::Comma) {
@@ -2643,12 +2639,12 @@ impl<'a> Parser<'a> {
26432639
let mut values = vec![];
26442640

26452641
if self.consume_token(&Token::Eq) || self.parse_keyword(Keyword::TO) {
2646-
let token = self.peek_token();
2647-
let value = match (self.parse_value(), token) {
2648-
(Ok(value), _) => SetVariableValue::Literal(value),
2649-
(Err(_), Token::Word(ident)) => SetVariableValue::Ident(ident.to_ident()),
2650-
(Err(_), unexpected) => self.expected("variable value", unexpected)?,
2642+
let value = if let Ok(expr) = self.parse_expr() {
2643+
expr
2644+
} else {
2645+
self.expected("variable value", self.peek_token())?
26512646
};
2647+
26522648
values.push(value);
26532649

26542650
key_values.push(SetVariableKeyValue {

tests/sqlparser_mysql.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,41 +129,37 @@ fn parse_set_transaction() {
129129

130130
#[test]
131131
fn parse_set_variables() {
132-
let stmt = mysql_and_generic().verified_stmt("SET autocommit = 1, sql_mode = 'test'");
133-
134132
assert_eq!(
135-
stmt,
133+
mysql_and_generic().verified_stmt("SET autocommit = 1, sql_mode = 'test'"),
136134
Statement::SetVariable {
137135
key_values: [
138136
SetVariableKeyValue {
139137
local: false,
140138
hivevar: false,
141139
key: "autocommit".into(),
142-
value: vec![SetVariableValue::Literal(number("1"))],
140+
value: vec![Expr::Value(Value::Number("1".into(), false))],
143141
},
144142
SetVariableKeyValue {
145143
local: false,
146144
hivevar: false,
147145
key: "sql_mode".into(),
148-
value: vec![SetVariableValue::Literal(Value::SingleQuotedString(
149-
"test".into()
150-
))],
146+
value: vec![Expr::Value(Value::SingleQuotedString("test".into()))],
151147
}
152148
]
153149
.to_vec()
154150
}
155151
);
156152

157-
let stmt = mysql_and_generic().verified_stmt("SET LOCAL autocommit = 1");
153+
mysql_and_generic().verified_stmt("SET sql_mode = CONCAT(@@sql_mode, ',STRICT_TRANS_TABLES')");
158154

159155
assert_eq!(
160-
stmt,
156+
mysql_and_generic().verified_stmt("SET LOCAL autocommit = 1"),
161157
Statement::SetVariable {
162158
key_values: [SetVariableKeyValue {
163159
local: true,
164160
hivevar: false,
165161
key: "autocommit".into(),
166-
value: vec![SetVariableValue::Literal(number("1"))],
162+
value: vec![Expr::Value(Value::Number("1".into(), false))],
167163
},]
168164
.to_vec()
169165
}

tests/sqlparser_postgres.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,10 @@ fn parse_set() {
368368
Statement::SetVariable {
369369
key_values: [SetVariableKeyValue {
370370
key: "a".into(),
371-
value: vec![SetVariableValue::Ident("b".into())],
371+
value: vec![Expr::Identifier(Ident {
372+
value: "b".into(),
373+
quote_style: None
374+
})],
372375
local: false,
373376
hivevar: false,
374377
}]
@@ -384,9 +387,7 @@ fn parse_set() {
384387
local: false,
385388
hivevar: false,
386389
key: "a".into(),
387-
value: vec![SetVariableValue::Literal(Value::SingleQuotedString(
388-
"b".into()
389-
))],
390+
value: vec![Expr::Value(Value::SingleQuotedString("b".into()))],
390391
}]
391392
.to_vec()
392393
}
@@ -400,7 +401,7 @@ fn parse_set() {
400401
local: false,
401402
hivevar: false,
402403
key: "a".into(),
403-
value: vec![SetVariableValue::Literal(number("0"))],
404+
value: vec![Expr::Value(Value::Number("0".into(), false))],
404405
}]
405406
.to_vec()
406407
}
@@ -414,7 +415,10 @@ fn parse_set() {
414415
local: false,
415416
hivevar: false,
416417
key: "a".into(),
417-
value: vec![SetVariableValue::Ident("DEFAULT".into())],
418+
value: vec![Expr::Identifier(Ident {
419+
value: "DEFAULT".into(),
420+
quote_style: None
421+
})],
418422
}]
419423
.to_vec()
420424
}
@@ -428,7 +432,10 @@ fn parse_set() {
428432
local: true,
429433
hivevar: false,
430434
key: "a".into(),
431-
value: vec![SetVariableValue::Ident("b".into())],
435+
value: vec![Expr::Identifier(Ident {
436+
value: "b".into(),
437+
quote_style: None
438+
})],
432439
}]
433440
.to_vec()
434441
}

0 commit comments

Comments
 (0)