Skip to content

Commit fbe910e

Browse files
iffyioayman-sigma
authored andcommitted
Support subquery expression in SET expressions (apache#1343)
1 parent 7ccedd4 commit fbe910e

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
@@ -1212,20 +1212,18 @@ impl<'a> Parser<'a> {
12121212
Ok(Expr::Value(self.parse_value()?))
12131213
}
12141214
Token::LParen => {
1215-
let expr =
1216-
if self.parse_keyword(Keyword::SELECT) || self.parse_keyword(Keyword::WITH) {
1217-
self.prev_token();
1218-
Expr::Subquery(self.parse_boxed_query()?)
1219-
} else if let Some(lambda) = self.try_parse_lambda() {
1220-
return Ok(lambda);
1221-
} else {
1222-
let exprs = self.parse_comma_separated(Parser::parse_expr)?;
1223-
match exprs.len() {
1224-
0 => unreachable!(), // parse_comma_separated ensures 1 or more
1225-
1 => Expr::Nested(Box::new(exprs.into_iter().next().unwrap())),
1226-
_ => Expr::Tuple(exprs),
1227-
}
1228-
};
1215+
let expr = if let Some(expr) = self.try_parse_expr_sub_query()? {
1216+
expr
1217+
} else if let Some(lambda) = self.try_parse_lambda() {
1218+
return Ok(lambda);
1219+
} else {
1220+
let exprs = self.parse_comma_separated(Parser::parse_expr)?;
1221+
match exprs.len() {
1222+
0 => unreachable!(), // parse_comma_separated ensures 1 or more
1223+
1 => Expr::Nested(Box::new(exprs.into_iter().next().unwrap())),
1224+
_ => Expr::Tuple(exprs),
1225+
}
1226+
};
12291227
self.expect_token(&Token::RParen)?;
12301228
if !self.consume_token(&Token::Period) {
12311229
Ok(expr)
@@ -1267,6 +1265,18 @@ impl<'a> Parser<'a> {
12671265
}
12681266
}
12691267

1268+
fn try_parse_expr_sub_query(&mut self) -> Result<Option<Expr>, ParserError> {
1269+
if self
1270+
.parse_one_of_keywords(&[Keyword::SELECT, Keyword::WITH])
1271+
.is_none()
1272+
{
1273+
return Ok(None);
1274+
}
1275+
self.prev_token();
1276+
1277+
Ok(Some(Expr::Subquery(self.parse_boxed_query()?)))
1278+
}
1279+
12701280
fn try_parse_lambda(&mut self) -> Option<Expr> {
12711281
if !self.dialect.supports_lambda_functions() {
12721282
return None;
@@ -8723,7 +8733,9 @@ impl<'a> Parser<'a> {
87238733

87248734
let mut values = vec![];
87258735
loop {
8726-
let value = if let Ok(expr) = self.parse_expr() {
8736+
let value = if let Some(expr) = self.try_parse_expr_sub_query()? {
8737+
expr
8738+
} else if let Ok(expr) = self.parse_expr() {
87278739
expr
87288740
} else {
87298741
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
@@ -7136,9 +7136,39 @@ fn parse_set_variable() {
71367136
_ => unreachable!(),
71377137
}
71387138

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

0 commit comments

Comments
 (0)