mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-27 07:59:11 +00:00
add more consistency in ast (#523)
* add more consistency in ast * refactor styling
This commit is contained in:
parent
d981f70143
commit
c884fbc388
3 changed files with 43 additions and 15 deletions
|
@ -337,9 +337,9 @@ pub enum Expr {
|
||||||
results: Vec<Expr>,
|
results: Vec<Expr>,
|
||||||
else_result: Option<Box<Expr>>,
|
else_result: Option<Box<Expr>>,
|
||||||
},
|
},
|
||||||
/// An exists expression `EXISTS(SELECT ...)`, used in expressions like
|
/// An exists expression `[ NOT ] EXISTS(SELECT ...)`, used in expressions like
|
||||||
/// `WHERE EXISTS (SELECT ...)`.
|
/// `WHERE [ NOT ] EXISTS (SELECT ...)`.
|
||||||
Exists(Box<Query>),
|
Exists { subquery: Box<Query>, negated: bool },
|
||||||
/// A parenthesized subquery `(SELECT ...)`, used in expression like
|
/// A parenthesized subquery `(SELECT ...)`, used in expression like
|
||||||
/// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
|
/// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
|
||||||
Subquery(Box<Query>),
|
Subquery(Box<Query>),
|
||||||
|
@ -466,7 +466,12 @@ impl fmt::Display for Expr {
|
||||||
}
|
}
|
||||||
write!(f, " END")
|
write!(f, " END")
|
||||||
}
|
}
|
||||||
Expr::Exists(s) => write!(f, "EXISTS ({})", s),
|
Expr::Exists { subquery, negated } => write!(
|
||||||
|
f,
|
||||||
|
"{}EXISTS ({})",
|
||||||
|
if *negated { "NOT " } else { "" },
|
||||||
|
subquery
|
||||||
|
),
|
||||||
Expr::Subquery(s) => write!(f, "({})", s),
|
Expr::Subquery(s) => write!(f, "({})", s),
|
||||||
Expr::ListAgg(listagg) => write!(f, "{}", listagg),
|
Expr::ListAgg(listagg) => write!(f, "{}", listagg),
|
||||||
Expr::GroupingSets(sets) => {
|
Expr::GroupingSets(sets) => {
|
||||||
|
|
|
@ -426,7 +426,7 @@ impl<'a> Parser<'a> {
|
||||||
Keyword::CASE => self.parse_case_expr(),
|
Keyword::CASE => self.parse_case_expr(),
|
||||||
Keyword::CAST => self.parse_cast_expr(),
|
Keyword::CAST => self.parse_cast_expr(),
|
||||||
Keyword::TRY_CAST => self.parse_try_cast_expr(),
|
Keyword::TRY_CAST => self.parse_try_cast_expr(),
|
||||||
Keyword::EXISTS => self.parse_exists_expr(),
|
Keyword::EXISTS => self.parse_exists_expr(false),
|
||||||
Keyword::EXTRACT => self.parse_extract_expr(),
|
Keyword::EXTRACT => self.parse_extract_expr(),
|
||||||
Keyword::POSITION => self.parse_position_expr(),
|
Keyword::POSITION => self.parse_position_expr(),
|
||||||
Keyword::SUBSTRING => self.parse_substring_expr(),
|
Keyword::SUBSTRING => self.parse_substring_expr(),
|
||||||
|
@ -438,10 +438,7 @@ impl<'a> Parser<'a> {
|
||||||
self.expect_token(&Token::LBracket)?;
|
self.expect_token(&Token::LBracket)?;
|
||||||
self.parse_array_expr(true)
|
self.parse_array_expr(true)
|
||||||
}
|
}
|
||||||
Keyword::NOT => Ok(Expr::UnaryOp {
|
Keyword::NOT => self.parse_not(),
|
||||||
op: UnaryOperator::Not,
|
|
||||||
expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?),
|
|
||||||
}),
|
|
||||||
// Here `w` is a word, check if it's a part of a multi-part
|
// Here `w` is a word, check if it's a part of a multi-part
|
||||||
// identifier, a function call, or a simple identifier:
|
// identifier, a function call, or a simple identifier:
|
||||||
_ => match self.peek_token() {
|
_ => match self.peek_token() {
|
||||||
|
@ -783,9 +780,12 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a SQL EXISTS expression e.g. `WHERE EXISTS(SELECT ...)`.
|
/// Parse a SQL EXISTS expression e.g. `WHERE EXISTS(SELECT ...)`.
|
||||||
pub fn parse_exists_expr(&mut self) -> Result<Expr, ParserError> {
|
pub fn parse_exists_expr(&mut self, negated: bool) -> Result<Expr, ParserError> {
|
||||||
self.expect_token(&Token::LParen)?;
|
self.expect_token(&Token::LParen)?;
|
||||||
let exists_node = Expr::Exists(Box::new(self.parse_query()?));
|
let exists_node = Expr::Exists {
|
||||||
|
negated,
|
||||||
|
subquery: Box::new(self.parse_query()?),
|
||||||
|
};
|
||||||
self.expect_token(&Token::RParen)?;
|
self.expect_token(&Token::RParen)?;
|
||||||
Ok(exists_node)
|
Ok(exists_node)
|
||||||
}
|
}
|
||||||
|
@ -984,6 +984,26 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_not(&mut self) -> Result<Expr, ParserError> {
|
||||||
|
match self.peek_token() {
|
||||||
|
Token::Word(w) => match w.keyword {
|
||||||
|
Keyword::EXISTS => {
|
||||||
|
let negated = true;
|
||||||
|
let _ = self.parse_keyword(Keyword::EXISTS);
|
||||||
|
self.parse_exists_expr(negated)
|
||||||
|
}
|
||||||
|
_ => Ok(Expr::UnaryOp {
|
||||||
|
op: UnaryOperator::Not,
|
||||||
|
expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Ok(Expr::UnaryOp {
|
||||||
|
op: UnaryOperator::Not,
|
||||||
|
expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse an INTERVAL literal.
|
/// Parse an INTERVAL literal.
|
||||||
///
|
///
|
||||||
/// Some syntactically valid intervals:
|
/// Some syntactically valid intervals:
|
||||||
|
|
|
@ -3625,16 +3625,19 @@ fn parse_exists_subquery() {
|
||||||
let sql = "SELECT * FROM t WHERE EXISTS (SELECT 1)";
|
let sql = "SELECT * FROM t WHERE EXISTS (SELECT 1)";
|
||||||
let select = verified_only_select(sql);
|
let select = verified_only_select(sql);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Expr::Exists(Box::new(expected_inner.clone())),
|
Expr::Exists {
|
||||||
|
negated: false,
|
||||||
|
subquery: Box::new(expected_inner.clone())
|
||||||
|
},
|
||||||
select.selection.unwrap(),
|
select.selection.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let sql = "SELECT * FROM t WHERE NOT EXISTS (SELECT 1)";
|
let sql = "SELECT * FROM t WHERE NOT EXISTS (SELECT 1)";
|
||||||
let select = verified_only_select(sql);
|
let select = verified_only_select(sql);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Expr::UnaryOp {
|
Expr::Exists {
|
||||||
op: UnaryOperator::Not,
|
negated: true,
|
||||||
expr: Box::new(Expr::Exists(Box::new(expected_inner))),
|
subquery: Box::new(expected_inner)
|
||||||
},
|
},
|
||||||
select.selection.unwrap(),
|
select.selection.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue