You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by al...@apache.org on 2024/11/18 12:30:25 UTC

(datafusion-sqlparser-rs) branch main updated: Support ANTI and SEMI joins without LEFT/RIGHT (#1528)

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

alamb 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 a67a4f3c Support ANTI and SEMI joins without LEFT/RIGHT (#1528)
a67a4f3c is described below

commit a67a4f3cbe2cb6e266f3914db8520890bfa7e198
Author: delamarch3 <68...@users.noreply.github.com>
AuthorDate: Mon Nov 18 12:30:20 2024 +0000

    Support ANTI and SEMI joins without LEFT/RIGHT (#1528)
---
 src/ast/query.rs          | 18 ++++++++++++++++++
 src/keywords.rs           |  2 ++
 src/parser/mod.rs         | 10 ++++++++++
 tests/sqlparser_common.rs | 16 ++++++++++++++++
 4 files changed, 46 insertions(+)

diff --git a/src/ast/query.rs b/src/ast/query.rs
index 60ebe376..2160da0d 100644
--- a/src/ast/query.rs
+++ b/src/ast/query.rs
@@ -1694,6 +1694,13 @@ impl fmt::Display for Join {
                 suffix(constraint)
             ),
             JoinOperator::CrossJoin => write!(f, " CROSS JOIN {}", self.relation),
+            JoinOperator::Semi(constraint) => write!(
+                f,
+                " {}SEMI JOIN {}{}",
+                prefix(constraint),
+                self.relation,
+                suffix(constraint)
+            ),
             JoinOperator::LeftSemi(constraint) => write!(
                 f,
                 " {}LEFT SEMI JOIN {}{}",
@@ -1708,6 +1715,13 @@ impl fmt::Display for Join {
                 self.relation,
                 suffix(constraint)
             ),
+            JoinOperator::Anti(constraint) => write!(
+                f,
+                " {}ANTI JOIN {}{}",
+                prefix(constraint),
+                self.relation,
+                suffix(constraint)
+            ),
             JoinOperator::LeftAnti(constraint) => write!(
                 f,
                 " {}LEFT ANTI JOIN {}{}",
@@ -1746,10 +1760,14 @@ pub enum JoinOperator {
     RightOuter(JoinConstraint),
     FullOuter(JoinConstraint),
     CrossJoin,
+    /// SEMI (non-standard)
+    Semi(JoinConstraint),
     /// LEFT SEMI (non-standard)
     LeftSemi(JoinConstraint),
     /// RIGHT SEMI (non-standard)
     RightSemi(JoinConstraint),
+    /// ANTI (non-standard)
+    Anti(JoinConstraint),
     /// LEFT ANTI (non-standard)
     LeftAnti(JoinConstraint),
     /// RIGHT ANTI (non-standard)
diff --git a/src/keywords.rs b/src/keywords.rs
index 79026821..fdf2bf35 100644
--- a/src/keywords.rs
+++ b/src/keywords.rs
@@ -892,6 +892,8 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
     Keyword::CLUSTER,
     Keyword::DISTRIBUTE,
     Keyword::GLOBAL,
+    Keyword::ANTI,
+    Keyword::SEMI,
     // for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
     Keyword::OUTER,
     Keyword::SET,
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index a583112a..1a094c14 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -10025,6 +10025,16 @@ impl<'a> Parser<'a> {
                             }
                         }
                     }
+                    Keyword::ANTI => {
+                        let _ = self.next_token(); // consume ANTI
+                        self.expect_keyword(Keyword::JOIN)?;
+                        JoinOperator::Anti
+                    }
+                    Keyword::SEMI => {
+                        let _ = self.next_token(); // consume SEMI
+                        self.expect_keyword(Keyword::JOIN)?;
+                        JoinOperator::Semi
+                    }
                     Keyword::FULL => {
                         let _ = self.next_token(); // consume FULL
                         let _ = self.parse_keyword(Keyword::OUTER); // [ OUTER ]
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 2ffb5f44..77496781 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -6013,6 +6013,10 @@ fn parse_joins_on() {
             JoinOperator::RightOuter
         )]
     );
+    assert_eq!(
+        only(&verified_only_select("SELECT * FROM t1 SEMI JOIN t2 ON c1 = c2").from).joins,
+        vec![join_with_constraint("t2", None, false, JoinOperator::Semi)]
+    );
     assert_eq!(
         only(&verified_only_select("SELECT * FROM t1 LEFT SEMI JOIN t2 ON c1 = c2").from).joins,
         vec![join_with_constraint(
@@ -6031,6 +6035,10 @@ fn parse_joins_on() {
             JoinOperator::RightSemi
         )]
     );
+    assert_eq!(
+        only(&verified_only_select("SELECT * FROM t1 ANTI JOIN t2 ON c1 = c2").from).joins,
+        vec![join_with_constraint("t2", None, false, JoinOperator::Anti)]
+    );
     assert_eq!(
         only(&verified_only_select("SELECT * FROM t1 LEFT ANTI JOIN t2 ON c1 = c2").from).joins,
         vec![join_with_constraint(
@@ -6117,6 +6125,10 @@ fn parse_joins_using() {
         only(&verified_only_select("SELECT * FROM t1 RIGHT JOIN t2 USING(c1)").from).joins,
         vec![join_with_constraint("t2", None, JoinOperator::RightOuter)]
     );
+    assert_eq!(
+        only(&verified_only_select("SELECT * FROM t1 SEMI JOIN t2 USING(c1)").from).joins,
+        vec![join_with_constraint("t2", None, JoinOperator::Semi)]
+    );
     assert_eq!(
         only(&verified_only_select("SELECT * FROM t1 LEFT SEMI JOIN t2 USING(c1)").from).joins,
         vec![join_with_constraint("t2", None, JoinOperator::LeftSemi)]
@@ -6125,6 +6137,10 @@ fn parse_joins_using() {
         only(&verified_only_select("SELECT * FROM t1 RIGHT SEMI JOIN t2 USING(c1)").from).joins,
         vec![join_with_constraint("t2", None, JoinOperator::RightSemi)]
     );
+    assert_eq!(
+        only(&verified_only_select("SELECT * FROM t1 ANTI JOIN t2 USING(c1)").from).joins,
+        vec![join_with_constraint("t2", None, JoinOperator::Anti)]
+    );
     assert_eq!(
         only(&verified_only_select("SELECT * FROM t1 LEFT ANTI JOIN t2 USING(c1)").from).joins,
         vec![join_with_constraint("t2", None, JoinOperator::LeftAnti)]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org