Skip to content

Commit 43c4ada

Browse files
MazterQyoumcheshkov
authored andcommitted
feat: Support ANY/ALL subquery (#42)
1 parent 9c14c52 commit 43c4ada

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

src/ast/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,9 @@ pub enum Expr {
385385
/// A parenthesized subquery `(SELECT ...)`, used in expression like
386386
/// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
387387
Subquery(Box<Query>),
388+
/// An ANY/ALL subquery `op ANY(SELECT ...)`, used in expression like
389+
/// `SELECT x = ANY(subquery) AS c`
390+
AnyAllSubquery(Box<Query>),
388391
/// The `LISTAGG` function `SELECT LISTAGG(...) WITHIN GROUP (ORDER BY ...)`
389392
ListAgg(ListAgg),
390393
/// The `ARRAY_AGG` function `SELECT ARRAY_AGG(... ORDER BY ...)`
@@ -581,6 +584,7 @@ impl fmt::Display for Expr {
581584
}
582585
Expr::Exists(s) => write!(f, "EXISTS ({})", s),
583586
Expr::Subquery(s) => write!(f, "({})", s),
587+
Expr::AnyAllSubquery(s) => write!(f, "{}", s),
584588
Expr::ArraySubquery(s) => write!(f, "ARRAY({})", s),
585589
Expr::ListAgg(listagg) => write!(f, "{}", listagg),
586590
Expr::ArrayAgg(arrayagg) => write!(f, "{}", arrayagg),

src/parser.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -1248,14 +1248,20 @@ impl<'a> Parser<'a> {
12481248
};
12491249

12501250
if let Some(op) = regular_binary_operator {
1251-
if let Some(keyword) = self.parse_one_of_keywords(&[Keyword::ANY, Keyword::ALL]) {
1251+
if let Some(keyword) =
1252+
self.parse_one_of_keywords(&[Keyword::ANY, Keyword::SOME, Keyword::ALL])
1253+
{
12521254
self.expect_token(&Token::LParen)?;
1253-
let right = self.parse_subexpr(precedence)?;
1255+
let right = if let Ok(query) = self.parse_query() {
1256+
Expr::AnyAllSubquery(Box::new(query))
1257+
} else {
1258+
self.parse_subexpr(precedence)?
1259+
};
12541260
self.expect_token(&Token::RParen)?;
12551261

12561262
let right = match keyword {
12571263
Keyword::ALL => Box::new(Expr::AllOp(Box::new(right))),
1258-
Keyword::ANY => Box::new(Expr::AnyOp(Box::new(right))),
1264+
Keyword::ANY | Keyword::SOME => Box::new(Expr::AnyOp(Box::new(right))),
12591265
_ => unreachable!(),
12601266
};
12611267

tests/sqlparser_common.rs

+52
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,11 @@ fn parse_binary_any() {
11491149
);
11501150
}
11511151

1152+
#[test]
1153+
fn parse_select_some() {
1154+
one_statement_parses_to("SELECT a = SOME(b)", "SELECT a = ANY(b)");
1155+
}
1156+
11521157
#[test]
11531158
fn parse_binary_all() {
11541159
let select = verified_only_select("SELECT a = ALL(b)");
@@ -1162,6 +1167,53 @@ fn parse_binary_all() {
11621167
);
11631168
}
11641169

1170+
#[test]
1171+
fn parse_binary_any_subquery() {
1172+
let select = verified_only_select("SELECT a <> ANY(SELECT b FROM c)");
1173+
assert_eq!(
1174+
SelectItem::UnnamedExpr(Expr::BinaryOp {
1175+
left: Box::new(Expr::Identifier(Ident::new("a"))),
1176+
op: BinaryOperator::NotEq,
1177+
right: Box::new(Expr::AnyOp(Box::new(Expr::AnyAllSubquery(Box::new(
1178+
Query {
1179+
with: None,
1180+
body: SetExpr::Select(Box::new(Select {
1181+
distinct: false,
1182+
top: None,
1183+
projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident::new(
1184+
"b"
1185+
)))],
1186+
into: None,
1187+
from: vec![TableWithJoins {
1188+
relation: TableFactor::Table {
1189+
name: ObjectName(vec![Ident::new("c")]),
1190+
alias: None,
1191+
args: vec![],
1192+
with_hints: vec![],
1193+
},
1194+
joins: vec![]
1195+
}],
1196+
lateral_views: vec![],
1197+
selection: None,
1198+
group_by: vec![],
1199+
cluster_by: vec![],
1200+
distribute_by: vec![],
1201+
sort_by: vec![],
1202+
having: None,
1203+
qualify: None,
1204+
})),
1205+
order_by: vec![],
1206+
limit: None,
1207+
offset: None,
1208+
fetch: None,
1209+
lock: None,
1210+
}
1211+
))))),
1212+
}),
1213+
select.projection[0]
1214+
);
1215+
}
1216+
11651217
#[test]
11661218
fn parse_logical_xor() {
11671219
let sql = "SELECT true XOR true, false XOR false, true XOR false, false XOR true";

0 commit comments

Comments
 (0)