Support ANTI and SEMI joins without LEFT/RIGHT (#1528)

This commit is contained in:
delamarch3 2024-11-18 12:30:20 +00:00 committed by GitHub
parent 4a5f20e911
commit a67a4f3cbe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 46 additions and 0 deletions

View file

@ -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)

View file

@ -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,

View file

@ -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 ]

View file

@ -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)]