Skip to content

Commit

Permalink
ANY and ALL contains their operators (#963)
Browse files Browse the repository at this point in the history
  • Loading branch information
SeanTroyUWO authored Sep 7, 2023
1 parent b02c3f8 commit e0afd4b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 20 deletions.
28 changes: 22 additions & 6 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,10 +419,18 @@ pub enum Expr {
pattern: Box<Expr>,
escape_char: Option<char>,
},
/// Any operation e.g. `1 ANY (1)` or `foo > ANY(bar)`, It will be wrapped in the right side of BinaryExpr
AnyOp(Box<Expr>),
/// ALL operation e.g. `1 ALL (1)` or `foo > ALL(bar)`, It will be wrapped in the right side of BinaryExpr
AllOp(Box<Expr>),
/// Any operation e.g. `foo > ANY(bar)`, comparison operator is one of [=, >, <, =>, =<, !=]
AnyOp {
left: Box<Expr>,
compare_op: BinaryOperator,
right: Box<Expr>,
},
/// ALL operation e.g. `foo > ALL(bar)`, comparison operator is one of [=, >, <, =>, =<, !=]
AllOp {
left: Box<Expr>,
compare_op: BinaryOperator,
right: Box<Expr>,
},
/// Unary operation e.g. `NOT foo`
UnaryOp { op: UnaryOperator, expr: Box<Expr> },
/// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
Expand Down Expand Up @@ -724,8 +732,16 @@ impl fmt::Display for Expr {
pattern
),
},
Expr::AnyOp(expr) => write!(f, "ANY({expr})"),
Expr::AllOp(expr) => write!(f, "ALL({expr})"),
Expr::AnyOp {
left,
compare_op,
right,
} => write!(f, "{left} {compare_op} ANY({right})"),
Expr::AllOp {
left,
compare_op,
right,
} => write!(f, "{left} {compare_op} ALL({right})"),
Expr::UnaryOp { op, expr } => {
if op == &UnaryOperator::PGPostfixFactorial {
write!(f, "{expr}{op}")
Expand Down
32 changes: 24 additions & 8 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1782,16 +1782,32 @@ impl<'a> Parser<'a> {
let right = self.parse_subexpr(precedence)?;
self.expect_token(&Token::RParen)?;

let right = match keyword {
Keyword::ALL => Box::new(Expr::AllOp(Box::new(right))),
Keyword::ANY => Box::new(Expr::AnyOp(Box::new(right))),
_ => unreachable!(),
if !matches!(
op,
BinaryOperator::Gt
| BinaryOperator::Lt
| BinaryOperator::GtEq
| BinaryOperator::LtEq
| BinaryOperator::Eq
| BinaryOperator::NotEq
) {
return parser_err!(format!(
"Expected one of [=, >, <, =>, =<, !=] as comparison operator, found: {op}"
));

Check failure on line 1796 in src/parser/mod.rs

View workflow job for this annotation

GitHub Actions / compile

unexpected end of macro invocation

Check failure on line 1796 in src/parser/mod.rs

View workflow job for this annotation

GitHub Actions / docs

unexpected end of macro invocation

Check failure on line 1796 in src/parser/mod.rs

View workflow job for this annotation

GitHub Actions / lint

unexpected end of macro invocation

Check failure on line 1796 in src/parser/mod.rs

View workflow job for this annotation

GitHub Actions / compile-no-std

unexpected end of macro invocation

Check failure on line 1796 in src/parser/mod.rs

View workflow job for this annotation

GitHub Actions / test (stable)

unexpected end of macro invocation

Check failure on line 1796 in src/parser/mod.rs

View workflow job for this annotation

GitHub Actions / test (beta)

unexpected end of macro invocation

Check failure on line 1796 in src/parser/mod.rs

View workflow job for this annotation

GitHub Actions / test (nightly)

unexpected end of macro invocation
};

Ok(Expr::BinaryOp {
left: Box::new(expr),
op,
right,
Ok(match keyword {
Keyword::ALL => Expr::AllOp {
left: Box::new(expr),
compare_op: op,
right: Box::new(right),
},
Keyword::ANY => Expr::AnyOp {
left: Box::new(expr),
compare_op: op,
right: Box::new(right),
},
_ => unreachable!(),
})
} else {
Ok(Expr::BinaryOp {
Expand Down
12 changes: 6 additions & 6 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1558,10 +1558,10 @@ fn parse_bitwise_ops() {
fn parse_binary_any() {
let select = verified_only_select("SELECT a = ANY(b)");
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
SelectItem::UnnamedExpr(Expr::AnyOp {
left: Box::new(Expr::Identifier(Ident::new("a"))),
op: BinaryOperator::Eq,
right: Box::new(Expr::AnyOp(Box::new(Expr::Identifier(Ident::new("b"))))),
compare_op: BinaryOperator::Eq,
right: Box::new(Expr::Identifier(Ident::new("b"))),
}),
select.projection[0]
);
Expand All @@ -1571,10 +1571,10 @@ fn parse_binary_any() {
fn parse_binary_all() {
let select = verified_only_select("SELECT a = ALL(b)");
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
SelectItem::UnnamedExpr(Expr::AllOp {
left: Box::new(Expr::Identifier(Ident::new("a"))),
op: BinaryOperator::Eq,
right: Box::new(Expr::AllOp(Box::new(Expr::Identifier(Ident::new("b"))))),
compare_op: BinaryOperator::Eq,
right: Box::new(Expr::Identifier(Ident::new("b"))),
}),
select.projection[0]
);
Expand Down

0 comments on commit e0afd4b

Please sign in to comment.