This is an automated email from the ASF dual-hosted git repository.

iffyio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 5a761dd6 Add support for the Snowflake MINUS set operator (#1652)
5a761dd6 is described below

commit 5a761dd6dbb6945607b4eaf82891aa5a8d241171
Author: Yoav Cohen <[email protected]>
AuthorDate: Fri Jan 10 00:52:09 2025 +0100

    Add support for the Snowflake MINUS set operator (#1652)
---
 src/ast/query.rs          |  2 ++
 src/keywords.rs           |  3 +++
 src/parser/mod.rs         | 12 ++++++++++--
 tests/sqlparser_common.rs |  5 ++++-
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/ast/query.rs b/src/ast/query.rs
index 9e4e9e2e..2f0663a5 100644
--- a/src/ast/query.rs
+++ b/src/ast/query.rs
@@ -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",
         })
     }
 }
diff --git a/src/keywords.rs b/src/keywords.rs
index 897e5b5c..bd538ec6 100644
--- a/src/keywords.rs
+++ b/src/keywords.rs
@@ -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,
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 70868335..397ff37b 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -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]) {
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index df39c221..ba2f5309 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -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");


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to