mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-10 05:52:13 +00:00
Support ANTI and SEMI joins without LEFT/RIGHT (#1528)
This commit is contained in:
parent
4a5f20e911
commit
a67a4f3cbe
4 changed files with 46 additions and 0 deletions
|
@ -1694,6 +1694,13 @@ impl fmt::Display for Join {
|
||||||
suffix(constraint)
|
suffix(constraint)
|
||||||
),
|
),
|
||||||
JoinOperator::CrossJoin => write!(f, " CROSS JOIN {}", self.relation),
|
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!(
|
JoinOperator::LeftSemi(constraint) => write!(
|
||||||
f,
|
f,
|
||||||
" {}LEFT SEMI JOIN {}{}",
|
" {}LEFT SEMI JOIN {}{}",
|
||||||
|
@ -1708,6 +1715,13 @@ impl fmt::Display for Join {
|
||||||
self.relation,
|
self.relation,
|
||||||
suffix(constraint)
|
suffix(constraint)
|
||||||
),
|
),
|
||||||
|
JoinOperator::Anti(constraint) => write!(
|
||||||
|
f,
|
||||||
|
" {}ANTI JOIN {}{}",
|
||||||
|
prefix(constraint),
|
||||||
|
self.relation,
|
||||||
|
suffix(constraint)
|
||||||
|
),
|
||||||
JoinOperator::LeftAnti(constraint) => write!(
|
JoinOperator::LeftAnti(constraint) => write!(
|
||||||
f,
|
f,
|
||||||
" {}LEFT ANTI JOIN {}{}",
|
" {}LEFT ANTI JOIN {}{}",
|
||||||
|
@ -1746,10 +1760,14 @@ pub enum JoinOperator {
|
||||||
RightOuter(JoinConstraint),
|
RightOuter(JoinConstraint),
|
||||||
FullOuter(JoinConstraint),
|
FullOuter(JoinConstraint),
|
||||||
CrossJoin,
|
CrossJoin,
|
||||||
|
/// SEMI (non-standard)
|
||||||
|
Semi(JoinConstraint),
|
||||||
/// LEFT SEMI (non-standard)
|
/// LEFT SEMI (non-standard)
|
||||||
LeftSemi(JoinConstraint),
|
LeftSemi(JoinConstraint),
|
||||||
/// RIGHT SEMI (non-standard)
|
/// RIGHT SEMI (non-standard)
|
||||||
RightSemi(JoinConstraint),
|
RightSemi(JoinConstraint),
|
||||||
|
/// ANTI (non-standard)
|
||||||
|
Anti(JoinConstraint),
|
||||||
/// LEFT ANTI (non-standard)
|
/// LEFT ANTI (non-standard)
|
||||||
LeftAnti(JoinConstraint),
|
LeftAnti(JoinConstraint),
|
||||||
/// RIGHT ANTI (non-standard)
|
/// RIGHT ANTI (non-standard)
|
||||||
|
|
|
@ -892,6 +892,8 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
|
||||||
Keyword::CLUSTER,
|
Keyword::CLUSTER,
|
||||||
Keyword::DISTRIBUTE,
|
Keyword::DISTRIBUTE,
|
||||||
Keyword::GLOBAL,
|
Keyword::GLOBAL,
|
||||||
|
Keyword::ANTI,
|
||||||
|
Keyword::SEMI,
|
||||||
// for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
|
// for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
|
||||||
Keyword::OUTER,
|
Keyword::OUTER,
|
||||||
Keyword::SET,
|
Keyword::SET,
|
||||||
|
|
|
@ -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 => {
|
Keyword::FULL => {
|
||||||
let _ = self.next_token(); // consume FULL
|
let _ = self.next_token(); // consume FULL
|
||||||
let _ = self.parse_keyword(Keyword::OUTER); // [ OUTER ]
|
let _ = self.parse_keyword(Keyword::OUTER); // [ OUTER ]
|
||||||
|
|
|
@ -6013,6 +6013,10 @@ fn parse_joins_on() {
|
||||||
JoinOperator::RightOuter
|
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!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 LEFT SEMI JOIN t2 ON c1 = c2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 LEFT SEMI JOIN t2 ON c1 = c2").from).joins,
|
||||||
vec![join_with_constraint(
|
vec![join_with_constraint(
|
||||||
|
@ -6031,6 +6035,10 @@ fn parse_joins_on() {
|
||||||
JoinOperator::RightSemi
|
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!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 LEFT ANTI JOIN t2 ON c1 = c2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 LEFT ANTI JOIN t2 ON c1 = c2").from).joins,
|
||||||
vec![join_with_constraint(
|
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,
|
only(&verified_only_select("SELECT * FROM t1 RIGHT JOIN t2 USING(c1)").from).joins,
|
||||||
vec![join_with_constraint("t2", None, JoinOperator::RightOuter)]
|
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!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 LEFT SEMI JOIN t2 USING(c1)").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 LEFT SEMI JOIN t2 USING(c1)").from).joins,
|
||||||
vec![join_with_constraint("t2", None, JoinOperator::LeftSemi)]
|
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,
|
only(&verified_only_select("SELECT * FROM t1 RIGHT SEMI JOIN t2 USING(c1)").from).joins,
|
||||||
vec![join_with_constraint("t2", None, JoinOperator::RightSemi)]
|
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!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 LEFT ANTI JOIN t2 USING(c1)").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 LEFT ANTI JOIN t2 USING(c1)").from).joins,
|
||||||
vec![join_with_constraint("t2", None, JoinOperator::LeftAnti)]
|
vec![join_with_constraint("t2", None, JoinOperator::LeftAnti)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue