mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
Add support for the Snowflake MINUS set operator (#1652)
This commit is contained in:
parent
4fdf5e1b30
commit
5a761dd6db
4 changed files with 19 additions and 3 deletions
|
@ -208,6 +208,7 @@ pub enum SetOperator {
|
|||
Union,
|
||||
Except,
|
||||
Intersect,
|
||||
Minus,
|
||||
}
|
||||
|
||||
impl fmt::Display for SetOperator {
|
||||
|
@ -216,6 +217,7 @@ impl fmt::Display for SetOperator {
|
|||
SetOperator::Union => "UNION",
|
||||
SetOperator::Except => "EXCEPT",
|
||||
SetOperator::Intersect => "INTERSECT",
|
||||
SetOperator::Minus => "MINUS",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,6 +503,7 @@ define_keywords!(
|
|||
MILLISECOND,
|
||||
MILLISECONDS,
|
||||
MIN,
|
||||
MINUS,
|
||||
MINUTE,
|
||||
MINUTES,
|
||||
MINVALUE,
|
||||
|
@ -921,6 +922,7 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
|
|||
Keyword::UNION,
|
||||
Keyword::EXCEPT,
|
||||
Keyword::INTERSECT,
|
||||
Keyword::MINUS,
|
||||
// Reserved only as a table alias in the `FROM`/`JOIN` clauses:
|
||||
Keyword::ON,
|
||||
Keyword::JOIN,
|
||||
|
@ -984,6 +986,7 @@ pub const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
|
|||
Keyword::UNION,
|
||||
Keyword::EXCEPT,
|
||||
Keyword::INTERSECT,
|
||||
Keyword::MINUS,
|
||||
Keyword::CLUSTER,
|
||||
Keyword::DISTRIBUTE,
|
||||
Keyword::RETURNING,
|
||||
|
|
|
@ -9942,7 +9942,9 @@ impl<'a> Parser<'a> {
|
|||
let op = self.parse_set_operator(&self.peek_token().token);
|
||||
let next_precedence = match op {
|
||||
// UNION and EXCEPT have the same binding power and evaluate left-to-right
|
||||
Some(SetOperator::Union) | Some(SetOperator::Except) => 10,
|
||||
Some(SetOperator::Union) | Some(SetOperator::Except) | Some(SetOperator::Minus) => {
|
||||
10
|
||||
}
|
||||
// INTERSECT has higher precedence than UNION/EXCEPT
|
||||
Some(SetOperator::Intersect) => 20,
|
||||
// Unexpected token or EOF => stop parsing the query body
|
||||
|
@ -9969,13 +9971,19 @@ impl<'a> Parser<'a> {
|
|||
Token::Word(w) if w.keyword == Keyword::UNION => Some(SetOperator::Union),
|
||||
Token::Word(w) if w.keyword == Keyword::EXCEPT => Some(SetOperator::Except),
|
||||
Token::Word(w) if w.keyword == Keyword::INTERSECT => Some(SetOperator::Intersect),
|
||||
Token::Word(w) if w.keyword == Keyword::MINUS => Some(SetOperator::Minus),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_set_quantifier(&mut self, op: &Option<SetOperator>) -> SetQuantifier {
|
||||
match op {
|
||||
Some(SetOperator::Except | SetOperator::Intersect | SetOperator::Union) => {
|
||||
Some(
|
||||
SetOperator::Except
|
||||
| SetOperator::Intersect
|
||||
| SetOperator::Union
|
||||
| SetOperator::Minus,
|
||||
) => {
|
||||
if self.parse_keywords(&[Keyword::DISTINCT, Keyword::BY, Keyword::NAME]) {
|
||||
SetQuantifier::DistinctByName
|
||||
} else if self.parse_keywords(&[Keyword::BY, Keyword::NAME]) {
|
||||
|
|
|
@ -6860,7 +6860,7 @@ fn parse_derived_tables() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn parse_union_except_intersect() {
|
||||
fn parse_union_except_intersect_minus() {
|
||||
// TODO: add assertions
|
||||
verified_stmt("SELECT 1 UNION SELECT 2");
|
||||
verified_stmt("SELECT 1 UNION ALL SELECT 2");
|
||||
|
@ -6868,6 +6868,9 @@ fn parse_union_except_intersect() {
|
|||
verified_stmt("SELECT 1 EXCEPT SELECT 2");
|
||||
verified_stmt("SELECT 1 EXCEPT ALL SELECT 2");
|
||||
verified_stmt("SELECT 1 EXCEPT DISTINCT SELECT 1");
|
||||
verified_stmt("SELECT 1 MINUS SELECT 2");
|
||||
verified_stmt("SELECT 1 MINUS ALL SELECT 2");
|
||||
verified_stmt("SELECT 1 MINUS DISTINCT SELECT 1");
|
||||
verified_stmt("SELECT 1 INTERSECT SELECT 2");
|
||||
verified_stmt("SELECT 1 INTERSECT ALL SELECT 2");
|
||||
verified_stmt("SELECT 1 INTERSECT DISTINCT SELECT 1");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue