Skip to content

Commit e4e0dc0

Browse files
committed
Allow to use the GLOBAL keyword before the join operator (apache#1353)
1 parent 9ee8988 commit e4e0dc0

9 files changed

+81
-8
lines changed

src/ast/query.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,9 @@ impl Display for TableVersion {
15371537
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
15381538
pub struct Join {
15391539
pub relation: TableFactor,
1540+
/// ClickHouse supports the optional `GLOBAL` keyword before the join operator.
1541+
/// See [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/select/join)
1542+
pub global: bool,
15401543
pub join_operator: JoinOperator,
15411544
}
15421545

@@ -1563,6 +1566,10 @@ impl fmt::Display for Join {
15631566
}
15641567
Suffix(constraint)
15651568
}
1569+
if self.global {
1570+
write!(f, " GLOBAL")?;
1571+
}
1572+
15661573
match &self.join_operator {
15671574
JoinOperator::Inner(constraint) => write!(
15681575
f,

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
853853
Keyword::USING,
854854
Keyword::CLUSTER,
855855
Keyword::DISTRIBUTE,
856+
Keyword::GLOBAL,
856857
// for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
857858
Keyword::OUTER,
858859
Keyword::SET,

src/parser/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9019,6 +9019,7 @@ impl<'a> Parser<'a> {
90199019
// a table alias.
90209020
let mut joins = vec![];
90219021
loop {
9022+
let global = self.parse_keyword(Keyword::GLOBAL);
90229023
let join = if self.parse_keyword(Keyword::CROSS) {
90239024
let join_operator = if self.parse_keyword(Keyword::JOIN) {
90249025
JoinOperator::CrossJoin
@@ -9030,13 +9031,15 @@ impl<'a> Parser<'a> {
90309031
};
90319032
Join {
90329033
relation: self.parse_table_factor()?,
9034+
global,
90339035
join_operator,
90349036
}
90359037
} else if self.parse_keyword(Keyword::OUTER) {
90369038
// MSSQL extension, similar to LEFT JOIN LATERAL .. ON 1=1
90379039
self.expect_keyword(Keyword::APPLY)?;
90389040
Join {
90399041
relation: self.parse_table_factor()?,
9042+
global,
90409043
join_operator: JoinOperator::OuterApply,
90419044
}
90429045
} else if self.parse_keyword(Keyword::ASOF) {
@@ -9046,6 +9049,7 @@ impl<'a> Parser<'a> {
90469049
let match_condition = self.parse_parenthesized(Self::parse_expr)?;
90479050
Join {
90489051
relation,
9052+
global,
90499053
join_operator: JoinOperator::AsOf {
90509054
match_condition,
90519055
constraint: self.parse_join_constraint(false)?,
@@ -9131,6 +9135,7 @@ impl<'a> Parser<'a> {
91319135
let join_constraint = self.parse_join_constraint(natural)?;
91329136
Join {
91339137
relation,
9138+
global,
91349139
join_operator: join_operator_type(join_constraint),
91359140
}
91369141
};

src/test_utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ pub fn table_with_alias(name: impl Into<String>, alias: impl Into<String>) -> Ta
331331
pub fn join(relation: TableFactor) -> Join {
332332
Join {
333333
relation,
334+
global: false,
334335
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
335336
}
336337
}

tests/sqlparser_bigquery.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,7 @@ fn parse_join_constraint_unnest_alias() {
15571557
with_offset_alias: None,
15581558
with_ordinality: false,
15591559
},
1560+
global: false,
15601561
join_operator: JoinOperator::Inner(JoinConstraint::On(Expr::BinaryOp {
15611562
left: Box::new(Expr::Identifier("c1".into())),
15621563
op: BinaryOperator::Eq,

tests/sqlparser_common.rs

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5600,6 +5600,7 @@ fn parse_implicit_join() {
56005600
partitions: vec![],
56015601
with_ordinality: false,
56025602
},
5603+
global: false,
56035604
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
56045605
}],
56055606
},
@@ -5623,6 +5624,7 @@ fn parse_implicit_join() {
56235624
partitions: vec![],
56245625
with_ordinality: false,
56255626
},
5627+
global: false,
56265628
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
56275629
}],
56285630
},
@@ -5646,6 +5648,7 @@ fn parse_cross_join() {
56465648
partitions: vec![],
56475649
with_ordinality: false,
56485650
},
5651+
global: false,
56495652
join_operator: JoinOperator::CrossJoin,
56505653
},
56515654
only(only(select.from).joins),
@@ -5657,6 +5660,7 @@ fn parse_joins_on() {
56575660
fn join_with_constraint(
56585661
relation: impl Into<String>,
56595662
alias: Option<TableAlias>,
5663+
global: bool,
56605664
f: impl Fn(JoinConstraint) -> JoinOperator,
56615665
) -> Join {
56625666
Join {
@@ -5669,6 +5673,7 @@ fn parse_joins_on() {
56695673
partitions: vec![],
56705674
with_ordinality: false,
56715675
},
5676+
global,
56725677
join_operator: f(JoinConstraint::On(Expr::BinaryOp {
56735678
left: Box::new(Expr::Identifier("c1".into())),
56745679
op: BinaryOperator::Eq,
@@ -5682,6 +5687,7 @@ fn parse_joins_on() {
56825687
vec![join_with_constraint(
56835688
"t2",
56845689
table_alias("foo"),
5690+
false,
56855691
JoinOperator::Inner,
56865692
)]
56875693
);
@@ -5692,35 +5698,80 @@ fn parse_joins_on() {
56925698
// Test parsing of different join operators
56935699
assert_eq!(
56945700
only(&verified_only_select("SELECT * FROM t1 JOIN t2 ON c1 = c2").from).joins,
5695-
vec![join_with_constraint("t2", None, JoinOperator::Inner)]
5701+
vec![join_with_constraint("t2", None, false, JoinOperator::Inner)]
56965702
);
56975703
assert_eq!(
56985704
only(&verified_only_select("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2").from).joins,
5699-
vec![join_with_constraint("t2", None, JoinOperator::LeftOuter)]
5705+
vec![join_with_constraint(
5706+
"t2",
5707+
None,
5708+
false,
5709+
JoinOperator::LeftOuter
5710+
)]
57005711
);
57015712
assert_eq!(
57025713
only(&verified_only_select("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2").from).joins,
5703-
vec![join_with_constraint("t2", None, JoinOperator::RightOuter)]
5714+
vec![join_with_constraint(
5715+
"t2",
5716+
None,
5717+
false,
5718+
JoinOperator::RightOuter
5719+
)]
57045720
);
57055721
assert_eq!(
57065722
only(&verified_only_select("SELECT * FROM t1 LEFT SEMI JOIN t2 ON c1 = c2").from).joins,
5707-
vec![join_with_constraint("t2", None, JoinOperator::LeftSemi)]
5723+
vec![join_with_constraint(
5724+
"t2",
5725+
None,
5726+
false,
5727+
JoinOperator::LeftSemi
5728+
)]
57085729
);
57095730
assert_eq!(
57105731
only(&verified_only_select("SELECT * FROM t1 RIGHT SEMI JOIN t2 ON c1 = c2").from).joins,
5711-
vec![join_with_constraint("t2", None, JoinOperator::RightSemi)]
5732+
vec![join_with_constraint(
5733+
"t2",
5734+
None,
5735+
false,
5736+
JoinOperator::RightSemi
5737+
)]
57125738
);
57135739
assert_eq!(
57145740
only(&verified_only_select("SELECT * FROM t1 LEFT ANTI JOIN t2 ON c1 = c2").from).joins,
5715-
vec![join_with_constraint("t2", None, JoinOperator::LeftAnti)]
5741+
vec![join_with_constraint(
5742+
"t2",
5743+
None,
5744+
false,
5745+
JoinOperator::LeftAnti
5746+
)]
57165747
);
57175748
assert_eq!(
57185749
only(&verified_only_select("SELECT * FROM t1 RIGHT ANTI JOIN t2 ON c1 = c2").from).joins,
5719-
vec![join_with_constraint("t2", None, JoinOperator::RightAnti)]
5750+
vec![join_with_constraint(
5751+
"t2",
5752+
None,
5753+
false,
5754+
JoinOperator::RightAnti
5755+
)]
57205756
);
57215757
assert_eq!(
57225758
only(&verified_only_select("SELECT * FROM t1 FULL JOIN t2 ON c1 = c2").from).joins,
5723-
vec![join_with_constraint("t2", None, JoinOperator::FullOuter)]
5759+
vec![join_with_constraint(
5760+
"t2",
5761+
None,
5762+
false,
5763+
JoinOperator::FullOuter
5764+
)]
5765+
);
5766+
5767+
assert_eq!(
5768+
only(&verified_only_select("SELECT * FROM t1 GLOBAL FULL JOIN t2 ON c1 = c2").from).joins,
5769+
vec![join_with_constraint(
5770+
"t2",
5771+
None,
5772+
true,
5773+
JoinOperator::FullOuter
5774+
)]
57245775
);
57255776
}
57265777

@@ -5741,6 +5792,7 @@ fn parse_joins_using() {
57415792
partitions: vec![],
57425793
with_ordinality: false,
57435794
},
5795+
global: false,
57445796
join_operator: f(JoinConstraint::Using(vec!["c1".into()])),
57455797
}
57465798
}
@@ -5805,6 +5857,7 @@ fn parse_natural_join() {
58055857
partitions: vec![],
58065858
with_ordinality: false,
58075859
},
5860+
global: false,
58085861
join_operator: f(JoinConstraint::Natural),
58095862
}
58105863
}
@@ -6073,6 +6126,7 @@ fn parse_derived_tables() {
60736126
partitions: vec![],
60746127
with_ordinality: false,
60756128
},
6129+
global: false,
60766130
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
60776131
}],
60786132
}),
@@ -6983,6 +7037,7 @@ fn lateral_function() {
69837037
],
69847038
alias: None,
69857039
},
7040+
global: false,
69867041
join_operator: JoinOperator::LeftOuter(JoinConstraint::None),
69877042
}],
69887043
}],

tests/sqlparser_mysql.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,6 +1891,7 @@ fn parse_update_with_joins() {
18911891
partitions: vec![],
18921892
with_ordinality: false,
18931893
},
1894+
global: false,
18941895
join_operator: JoinOperator::Inner(JoinConstraint::On(Expr::BinaryOp {
18951896
left: Box::new(Expr::CompoundIdentifier(vec![
18961897
Ident::new("o"),

tests/sqlparser_postgres.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4102,6 +4102,7 @@ fn parse_join_constraint_unnest_alias() {
41024102
with_offset_alias: None,
41034103
with_ordinality: false,
41044104
},
4105+
global: false,
41054106
join_operator: JoinOperator::Inner(JoinConstraint::On(Expr::BinaryOp {
41064107
left: Box::new(Expr::Identifier("c1".into())),
41074108
op: BinaryOperator::Eq,

tests/sqlparser_snowflake.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,6 +2206,7 @@ fn asof_joins() {
22062206
relation: table_with_alias("trades_unixtime", "tu"),
22072207
joins: vec![Join {
22082208
relation: table_with_alias("quotes_unixtime", "qu"),
2209+
global: false,
22092210
join_operator: JoinOperator::AsOf {
22102211
match_condition: Expr::BinaryOp {
22112212
left: Box::new(Expr::CompoundIdentifier(vec![

0 commit comments

Comments
 (0)