Skip to content

Commit 028ada8

Browse files
authored
Support subquery expression in SET expressions (#1343)
1 parent 845a1aa commit 028ada8

File tree

2 files changed

+57
-15
lines changed

2 files changed

+57
-15
lines changed

src/parser/mod.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,20 +1208,18 @@ impl<'a> Parser<'a> {
12081208
Ok(Expr::Value(self.parse_value()?))
12091209
}
12101210
Token::LParen => {
1211-
let expr =
1212-
if self.parse_keyword(Keyword::SELECT) || self.parse_keyword(Keyword::WITH) {
1213-
self.prev_token();
1214-
Expr::Subquery(self.parse_boxed_query()?)
1215-
} else if let Some(lambda) = self.try_parse_lambda() {
1216-
return Ok(lambda);
1217-
} else {
1218-
let exprs = self.parse_comma_separated(Parser::parse_expr)?;
1219-
match exprs.len() {
1220-
0 => unreachable!(), // parse_comma_separated ensures 1 or more
1221-
1 => Expr::Nested(Box::new(exprs.into_iter().next().unwrap())),
1222-
_ => Expr::Tuple(exprs),
1223-
}
1224-
};
1211+
let expr = if let Some(expr) = self.try_parse_expr_sub_query()? {
1212+
expr
1213+
} else if let Some(lambda) = self.try_parse_lambda() {
1214+
return Ok(lambda);
1215+
} else {
1216+
let exprs = self.parse_comma_separated(Parser::parse_expr)?;
1217+
match exprs.len() {
1218+
0 => unreachable!(), // parse_comma_separated ensures 1 or more
1219+
1 => Expr::Nested(Box::new(exprs.into_iter().next().unwrap())),
1220+
_ => Expr::Tuple(exprs),
1221+
}
1222+
};
12251223
self.expect_token(&Token::RParen)?;
12261224
if !self.consume_token(&Token::Period) {
12271225
Ok(expr)
@@ -1263,6 +1261,18 @@ impl<'a> Parser<'a> {
12631261
}
12641262
}
12651263

1264+
fn try_parse_expr_sub_query(&mut self) -> Result<Option<Expr>, ParserError> {
1265+
if self
1266+
.parse_one_of_keywords(&[Keyword::SELECT, Keyword::WITH])
1267+
.is_none()
1268+
{
1269+
return Ok(None);
1270+
}
1271+
self.prev_token();
1272+
1273+
Ok(Some(Expr::Subquery(self.parse_boxed_query()?)))
1274+
}
1275+
12661276
fn try_parse_lambda(&mut self) -> Option<Expr> {
12671277
if !self.dialect.supports_lambda_functions() {
12681278
return None;
@@ -8709,7 +8719,9 @@ impl<'a> Parser<'a> {
87098719

87108720
let mut values = vec![];
87118721
loop {
8712-
let value = if let Ok(expr) = self.parse_expr() {
8722+
let value = if let Some(expr) = self.try_parse_expr_sub_query()? {
8723+
expr
8724+
} else if let Ok(expr) = self.parse_expr() {
87138725
expr
87148726
} else {
87158727
self.expected("variable value", self.peek_token())?

tests/sqlparser_common.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7135,9 +7135,39 @@ fn parse_set_variable() {
71357135
_ => unreachable!(),
71367136
}
71377137

7138+
// Subquery expression
7139+
for (sql, canonical) in [
7140+
(
7141+
"SET (a) = (SELECT 22 FROM tbl1)",
7142+
"SET (a) = ((SELECT 22 FROM tbl1))",
7143+
),
7144+
(
7145+
"SET (a) = (SELECT 22 FROM tbl1, (SELECT 1 FROM tbl2))",
7146+
"SET (a) = ((SELECT 22 FROM tbl1, (SELECT 1 FROM tbl2)))",
7147+
),
7148+
(
7149+
"SET (a) = ((SELECT 22 FROM tbl1, (SELECT 1 FROM tbl2)))",
7150+
"SET (a) = ((SELECT 22 FROM tbl1, (SELECT 1 FROM tbl2)))",
7151+
),
7152+
(
7153+
"SET (a, b) = ((SELECT 22 FROM tbl1, (SELECT 1 FROM tbl2)), SELECT 33 FROM tbl3)",
7154+
"SET (a, b) = ((SELECT 22 FROM tbl1, (SELECT 1 FROM tbl2)), (SELECT 33 FROM tbl3))",
7155+
),
7156+
] {
7157+
multi_variable_dialects.one_statement_parses_to(sql, canonical);
7158+
}
7159+
71387160
let error_sqls = [
71397161
("SET (a, b, c) = (1, 2, 3", "Expected: ), found: EOF"),
71407162
("SET (a, b, c) = 1, 2, 3", "Expected: (, found: 1"),
7163+
(
7164+
"SET (a) = ((SELECT 22 FROM tbl1)",
7165+
"Expected: ), found: EOF",
7166+
),
7167+
(
7168+
"SET (a) = ((SELECT 22 FROM tbl1) (SELECT 22 FROM tbl1))",
7169+
"Expected: ), found: (",
7170+
),
71417171
];
71427172
for (sql, error) in error_sqls {
71437173
assert_eq!(

0 commit comments

Comments
 (0)