mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-24 16:04:04 +00:00
Differentiate LEFT JOIN from LEFT OUTER JOIN (#1726)
This commit is contained in:
parent
1c0e5d3554
commit
68c41a9d5a
4 changed files with 65 additions and 23 deletions
|
@ -2077,20 +2077,34 @@ impl fmt::Display for Join {
|
||||||
self.relation,
|
self.relation,
|
||||||
suffix(constraint)
|
suffix(constraint)
|
||||||
),
|
),
|
||||||
JoinOperator::LeftOuter(constraint) => write!(
|
JoinOperator::Left(constraint) => write!(
|
||||||
f,
|
f,
|
||||||
" {}LEFT JOIN {}{}",
|
" {}LEFT JOIN {}{}",
|
||||||
prefix(constraint),
|
prefix(constraint),
|
||||||
self.relation,
|
self.relation,
|
||||||
suffix(constraint)
|
suffix(constraint)
|
||||||
),
|
),
|
||||||
JoinOperator::RightOuter(constraint) => write!(
|
JoinOperator::LeftOuter(constraint) => write!(
|
||||||
|
f,
|
||||||
|
" {}LEFT OUTER JOIN {}{}",
|
||||||
|
prefix(constraint),
|
||||||
|
self.relation,
|
||||||
|
suffix(constraint)
|
||||||
|
),
|
||||||
|
JoinOperator::Right(constraint) => write!(
|
||||||
f,
|
f,
|
||||||
" {}RIGHT JOIN {}{}",
|
" {}RIGHT JOIN {}{}",
|
||||||
prefix(constraint),
|
prefix(constraint),
|
||||||
self.relation,
|
self.relation,
|
||||||
suffix(constraint)
|
suffix(constraint)
|
||||||
),
|
),
|
||||||
|
JoinOperator::RightOuter(constraint) => write!(
|
||||||
|
f,
|
||||||
|
" {}RIGHT OUTER JOIN {}{}",
|
||||||
|
prefix(constraint),
|
||||||
|
self.relation,
|
||||||
|
suffix(constraint)
|
||||||
|
),
|
||||||
JoinOperator::FullOuter(constraint) => write!(
|
JoinOperator::FullOuter(constraint) => write!(
|
||||||
f,
|
f,
|
||||||
" {}FULL JOIN {}{}",
|
" {}FULL JOIN {}{}",
|
||||||
|
@ -2162,7 +2176,9 @@ impl fmt::Display for Join {
|
||||||
pub enum JoinOperator {
|
pub enum JoinOperator {
|
||||||
Join(JoinConstraint),
|
Join(JoinConstraint),
|
||||||
Inner(JoinConstraint),
|
Inner(JoinConstraint),
|
||||||
|
Left(JoinConstraint),
|
||||||
LeftOuter(JoinConstraint),
|
LeftOuter(JoinConstraint),
|
||||||
|
Right(JoinConstraint),
|
||||||
RightOuter(JoinConstraint),
|
RightOuter(JoinConstraint),
|
||||||
FullOuter(JoinConstraint),
|
FullOuter(JoinConstraint),
|
||||||
CrossJoin,
|
CrossJoin,
|
||||||
|
|
|
@ -2010,7 +2010,9 @@ impl Spanned for JoinOperator {
|
||||||
match self {
|
match self {
|
||||||
JoinOperator::Join(join_constraint) => join_constraint.span(),
|
JoinOperator::Join(join_constraint) => join_constraint.span(),
|
||||||
JoinOperator::Inner(join_constraint) => join_constraint.span(),
|
JoinOperator::Inner(join_constraint) => join_constraint.span(),
|
||||||
|
JoinOperator::Left(join_constraint) => join_constraint.span(),
|
||||||
JoinOperator::LeftOuter(join_constraint) => join_constraint.span(),
|
JoinOperator::LeftOuter(join_constraint) => join_constraint.span(),
|
||||||
|
JoinOperator::Right(join_constraint) => join_constraint.span(),
|
||||||
JoinOperator::RightOuter(join_constraint) => join_constraint.span(),
|
JoinOperator::RightOuter(join_constraint) => join_constraint.span(),
|
||||||
JoinOperator::FullOuter(join_constraint) => join_constraint.span(),
|
JoinOperator::FullOuter(join_constraint) => join_constraint.span(),
|
||||||
JoinOperator::CrossJoin => Span::empty(),
|
JoinOperator::CrossJoin => Span::empty(),
|
||||||
|
|
|
@ -5740,7 +5740,7 @@ impl<'a> Parser<'a> {
|
||||||
drop_behavior,
|
drop_behavior,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/// ```sql
|
/// ```sql
|
||||||
/// DROP CONNECTOR [IF EXISTS] name
|
/// DROP CONNECTOR [IF EXISTS] name
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
@ -11190,9 +11190,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
Some(Keyword::JOIN) => {
|
Some(Keyword::JOIN) => {
|
||||||
if is_left {
|
if is_left {
|
||||||
JoinOperator::LeftOuter
|
JoinOperator::Left
|
||||||
} else {
|
} else {
|
||||||
JoinOperator::RightOuter
|
JoinOperator::Right
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -6661,8 +6661,16 @@ fn parse_joins_on() {
|
||||||
only(&verified_only_select("SELECT * FROM t1 JOIN t2 ON c1 = c2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 JOIN t2 ON c1 = c2").from).joins,
|
||||||
vec![join_with_constraint("t2", None, false, JoinOperator::Join)]
|
vec![join_with_constraint("t2", None, false, JoinOperator::Join)]
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
only(&verified_only_select("SELECT * FROM t1 INNER JOIN t2 ON c1 = c2").from).joins,
|
||||||
|
vec![join_with_constraint("t2", None, false, JoinOperator::Inner)]
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2").from).joins,
|
||||||
|
vec![join_with_constraint("t2", None, false, JoinOperator::Left)]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
only(&verified_only_select("SELECT * FROM t1 LEFT OUTER JOIN t2 ON c1 = c2").from).joins,
|
||||||
vec![join_with_constraint(
|
vec![join_with_constraint(
|
||||||
"t2",
|
"t2",
|
||||||
None,
|
None,
|
||||||
|
@ -6672,6 +6680,10 @@ fn parse_joins_on() {
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2").from).joins,
|
||||||
|
vec![join_with_constraint("t2", None, false, JoinOperator::Right)]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
only(&verified_only_select("SELECT * FROM t1 RIGHT OUTER JOIN t2 ON c1 = c2").from).joins,
|
||||||
vec![join_with_constraint(
|
vec![join_with_constraint(
|
||||||
"t2",
|
"t2",
|
||||||
None,
|
None,
|
||||||
|
@ -6794,10 +6806,18 @@ fn parse_joins_using() {
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 LEFT JOIN t2 USING(c1)").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 LEFT JOIN t2 USING(c1)").from).joins,
|
||||||
|
vec![join_with_constraint("t2", None, JoinOperator::Left)]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
only(&verified_only_select("SELECT * FROM t1 LEFT OUTER JOIN t2 USING(c1)").from).joins,
|
||||||
vec![join_with_constraint("t2", None, JoinOperator::LeftOuter)]
|
vec![join_with_constraint("t2", None, JoinOperator::LeftOuter)]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
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::Right)]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
only(&verified_only_select("SELECT * FROM t1 RIGHT OUTER JOIN t2 USING(c1)").from).joins,
|
||||||
vec![join_with_constraint("t2", None, JoinOperator::RightOuter)]
|
vec![join_with_constraint("t2", None, JoinOperator::RightOuter)]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -6857,20 +6877,34 @@ fn parse_natural_join() {
|
||||||
only(&verified_only_select("SELECT * FROM t1 NATURAL JOIN t2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 NATURAL JOIN t2").from).joins,
|
||||||
vec![natural_join(JoinOperator::Join, None)]
|
vec![natural_join(JoinOperator::Join, None)]
|
||||||
);
|
);
|
||||||
|
|
||||||
// inner join explicitly
|
// inner join explicitly
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 NATURAL INNER JOIN t2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 NATURAL INNER JOIN t2").from).joins,
|
||||||
vec![natural_join(JoinOperator::Inner, None)]
|
vec![natural_join(JoinOperator::Inner, None)]
|
||||||
);
|
);
|
||||||
|
|
||||||
// left join explicitly
|
// left join explicitly
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 NATURAL LEFT JOIN t2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 NATURAL LEFT JOIN t2").from).joins,
|
||||||
|
vec![natural_join(JoinOperator::Left, None)]
|
||||||
|
);
|
||||||
|
|
||||||
|
// left outer join explicitly
|
||||||
|
assert_eq!(
|
||||||
|
only(&verified_only_select("SELECT * FROM t1 NATURAL LEFT OUTER JOIN t2").from).joins,
|
||||||
vec![natural_join(JoinOperator::LeftOuter, None)]
|
vec![natural_join(JoinOperator::LeftOuter, None)]
|
||||||
);
|
);
|
||||||
|
|
||||||
// right join explicitly
|
// right join explicitly
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
only(&verified_only_select("SELECT * FROM t1 NATURAL RIGHT JOIN t2").from).joins,
|
only(&verified_only_select("SELECT * FROM t1 NATURAL RIGHT JOIN t2").from).joins,
|
||||||
|
vec![natural_join(JoinOperator::Right, None)]
|
||||||
|
);
|
||||||
|
|
||||||
|
// right outer join explicitly
|
||||||
|
assert_eq!(
|
||||||
|
only(&verified_only_select("SELECT * FROM t1 NATURAL RIGHT OUTER JOIN t2").from).joins,
|
||||||
vec![natural_join(JoinOperator::RightOuter, None)]
|
vec![natural_join(JoinOperator::RightOuter, None)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -6950,22 +6984,12 @@ fn parse_join_nesting() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_join_syntax_variants() {
|
fn parse_join_syntax_variants() {
|
||||||
one_statement_parses_to(
|
verified_stmt("SELECT c1 FROM t1 JOIN t2 USING(c1)");
|
||||||
"SELECT c1 FROM t1 JOIN t2 USING(c1)",
|
verified_stmt("SELECT c1 FROM t1 INNER JOIN t2 USING(c1)");
|
||||||
"SELECT c1 FROM t1 JOIN t2 USING(c1)",
|
verified_stmt("SELECT c1 FROM t1 LEFT JOIN t2 USING(c1)");
|
||||||
);
|
verified_stmt("SELECT c1 FROM t1 LEFT OUTER JOIN t2 USING(c1)");
|
||||||
one_statement_parses_to(
|
verified_stmt("SELECT c1 FROM t1 RIGHT JOIN t2 USING(c1)");
|
||||||
"SELECT c1 FROM t1 INNER JOIN t2 USING(c1)",
|
verified_stmt("SELECT c1 FROM t1 RIGHT OUTER JOIN t2 USING(c1)");
|
||||||
"SELECT c1 FROM t1 INNER JOIN t2 USING(c1)",
|
|
||||||
);
|
|
||||||
one_statement_parses_to(
|
|
||||||
"SELECT c1 FROM t1 LEFT OUTER JOIN t2 USING(c1)",
|
|
||||||
"SELECT c1 FROM t1 LEFT JOIN t2 USING(c1)",
|
|
||||||
);
|
|
||||||
one_statement_parses_to(
|
|
||||||
"SELECT c1 FROM t1 RIGHT OUTER JOIN t2 USING(c1)",
|
|
||||||
"SELECT c1 FROM t1 RIGHT JOIN t2 USING(c1)",
|
|
||||||
);
|
|
||||||
one_statement_parses_to(
|
one_statement_parses_to(
|
||||||
"SELECT c1 FROM t1 FULL OUTER JOIN t2 USING(c1)",
|
"SELECT c1 FROM t1 FULL OUTER JOIN t2 USING(c1)",
|
||||||
"SELECT c1 FROM t1 FULL JOIN t2 USING(c1)",
|
"SELECT c1 FROM t1 FULL JOIN t2 USING(c1)",
|
||||||
|
@ -8027,7 +8051,7 @@ fn lateral_derived() {
|
||||||
let join = &from.joins[0];
|
let join = &from.joins[0];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
join.join_operator,
|
join.join_operator,
|
||||||
JoinOperator::LeftOuter(JoinConstraint::On(Expr::Value(test_utils::number("1"))))
|
JoinOperator::Left(JoinConstraint::On(Expr::Value(test_utils::number("1"))))
|
||||||
);
|
);
|
||||||
if let TableFactor::Derived {
|
if let TableFactor::Derived {
|
||||||
lateral,
|
lateral,
|
||||||
|
@ -8095,7 +8119,7 @@ fn lateral_function() {
|
||||||
alias: None,
|
alias: None,
|
||||||
},
|
},
|
||||||
global: false,
|
global: false,
|
||||||
join_operator: JoinOperator::LeftOuter(JoinConstraint::None),
|
join_operator: JoinOperator::Left(JoinConstraint::None),
|
||||||
}],
|
}],
|
||||||
}],
|
}],
|
||||||
lateral_views: vec![],
|
lateral_views: vec![],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue