Skip to content

Commit c3ed0d5

Browse files
git-hulkayman-sigma
authored andcommitted
Allow to use the GLOBAL keyword before the join operator (apache#1353)
1 parent 66549fc commit c3ed0d5

File tree

9 files changed

+81
-8
lines changed

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
@@ -1549,6 +1549,9 @@ impl Display for TableVersion {
15491549
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
15501550
pub struct Join {
15511551
pub relation: TableFactor,
1552+
/// ClickHouse supports the optional `GLOBAL` keyword before the join operator.
1553+
/// See [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/select/join)
1554+
pub global: bool,
15521555
pub join_operator: JoinOperator,
15531556
}
15541557

@@ -1575,6 +1578,10 @@ impl fmt::Display for Join {
15751578
}
15761579
Suffix(constraint)
15771580
}
1581+
if self.global {
1582+
write!(f, " GLOBAL")?;
1583+
}
1584+
15781585
match &self.join_operator {
15791586
JoinOperator::Inner(constraint) => write!(
15801587
f,

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@ pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
851851
Keyword::USING,
852852
Keyword::CLUSTER,
853853
Keyword::DISTRIBUTE,
854+
Keyword::GLOBAL,
854855
// for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
855856
Keyword::OUTER,
856857
Keyword::SET,

src/parser/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9029,6 +9029,7 @@ impl<'a> Parser<'a> {
90299029
// a table alias.
90309030
let mut joins = vec![];
90319031
loop {
9032+
let global = self.parse_keyword(Keyword::GLOBAL);
90329033
let join = if self.parse_keyword(Keyword::CROSS) {
90339034
let join_operator = if self.parse_keyword(Keyword::JOIN) {
90349035
JoinOperator::CrossJoin
@@ -9040,13 +9041,15 @@ impl<'a> Parser<'a> {
90409041
};
90419042
Join {
90429043
relation: self.parse_table_factor()?,
9044+
global,
90439045
join_operator,
90449046
}
90459047
} else if self.parse_keyword(Keyword::OUTER) {
90469048
// MSSQL extension, similar to LEFT JOIN LATERAL .. ON 1=1
90479049
self.expect_keyword(Keyword::APPLY)?;
90489050
Join {
90499051
relation: self.parse_table_factor()?,
9052+
global,
90509053
join_operator: JoinOperator::OuterApply,
90519054
}
90529055
} else if self.parse_keyword(Keyword::ASOF) {
@@ -9056,6 +9059,7 @@ impl<'a> Parser<'a> {
90569059
let match_condition = self.parse_parenthesized(Self::parse_expr)?;
90579060
Join {
90589061
relation,
9062+
global,
90599063
join_operator: JoinOperator::AsOf {
90609064
match_condition,
90619065
constraint: self.parse_join_constraint(false)?,
@@ -9141,6 +9145,7 @@ impl<'a> Parser<'a> {
91419145
let join_constraint = self.parse_join_constraint(natural)?;
91429146
Join {
91439147
relation,
9148+
global,
91449149
join_operator: join_operator_type(join_constraint),
91459150
}
91469151
};

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
@@ -5601,6 +5601,7 @@ fn parse_implicit_join() {
56015601
partitions: vec![],
56025602
with_ordinality: false,
56035603
},
5604+
global: false,
56045605
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
56055606
}],
56065607
},
@@ -5624,6 +5625,7 @@ fn parse_implicit_join() {
56245625
partitions: vec![],
56255626
with_ordinality: false,
56265627
},
5628+
global: false,
56275629
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
56285630
}],
56295631
},
@@ -5647,6 +5649,7 @@ fn parse_cross_join() {
56475649
partitions: vec![],
56485650
with_ordinality: false,
56495651
},
5652+
global: false,
56505653
join_operator: JoinOperator::CrossJoin,
56515654
},
56525655
only(only(select.from).joins),
@@ -5658,6 +5661,7 @@ fn parse_joins_on() {
56585661
fn join_with_constraint(
56595662
relation: impl Into<String>,
56605663
alias: Option<TableAlias>,
5664+
global: bool,
56615665
f: impl Fn(JoinConstraint) -> JoinOperator,
56625666
) -> Join {
56635667
Join {
@@ -5670,6 +5674,7 @@ fn parse_joins_on() {
56705674
partitions: vec![],
56715675
with_ordinality: false,
56725676
},
5677+
global,
56735678
join_operator: f(JoinConstraint::On(Expr::BinaryOp {
56745679
left: Box::new(Expr::Identifier("c1".into())),
56755680
op: BinaryOperator::Eq,
@@ -5683,6 +5688,7 @@ fn parse_joins_on() {
56835688
vec![join_with_constraint(
56845689
"t2",
56855690
table_alias("foo"),
5691+
false,
56865692
JoinOperator::Inner,
56875693
)]
56885694
);
@@ -5693,35 +5699,80 @@ fn parse_joins_on() {
56935699
// Test parsing of different join operators
56945700
assert_eq!(
56955701
only(&verified_only_select("SELECT * FROM t1 JOIN t2 ON c1 = c2").from).joins,
5696-
vec![join_with_constraint("t2", None, JoinOperator::Inner)]
5702+
vec![join_with_constraint("t2", None, false, JoinOperator::Inner)]
56975703
);
56985704
assert_eq!(
56995705
only(&verified_only_select("SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2").from).joins,
5700-
vec![join_with_constraint("t2", None, JoinOperator::LeftOuter)]
5706+
vec![join_with_constraint(
5707+
"t2",
5708+
None,
5709+
false,
5710+
JoinOperator::LeftOuter
5711+
)]
57015712
);
57025713
assert_eq!(
57035714
only(&verified_only_select("SELECT * FROM t1 RIGHT JOIN t2 ON c1 = c2").from).joins,
5704-
vec![join_with_constraint("t2", None, JoinOperator::RightOuter)]
5715+
vec![join_with_constraint(
5716+
"t2",
5717+
None,
5718+
false,
5719+
JoinOperator::RightOuter
5720+
)]
57055721
);
57065722
assert_eq!(
57075723
only(&verified_only_select("SELECT * FROM t1 LEFT SEMI JOIN t2 ON c1 = c2").from).joins,
5708-
vec![join_with_constraint("t2", None, JoinOperator::LeftSemi)]
5724+
vec![join_with_constraint(
5725+
"t2",
5726+
None,
5727+
false,
5728+
JoinOperator::LeftSemi
5729+
)]
57095730
);
57105731
assert_eq!(
57115732
only(&verified_only_select("SELECT * FROM t1 RIGHT SEMI JOIN t2 ON c1 = c2").from).joins,
5712-
vec![join_with_constraint("t2", None, JoinOperator::RightSemi)]
5733+
vec![join_with_constraint(
5734+
"t2",
5735+
None,
5736+
false,
5737+
JoinOperator::RightSemi
5738+
)]
57135739
);
57145740
assert_eq!(
57155741
only(&verified_only_select("SELECT * FROM t1 LEFT ANTI JOIN t2 ON c1 = c2").from).joins,
5716-
vec![join_with_constraint("t2", None, JoinOperator::LeftAnti)]
5742+
vec![join_with_constraint(
5743+
"t2",
5744+
None,
5745+
false,
5746+
JoinOperator::LeftAnti
5747+
)]
57175748
);
57185749
assert_eq!(
57195750
only(&verified_only_select("SELECT * FROM t1 RIGHT ANTI JOIN t2 ON c1 = c2").from).joins,
5720-
vec![join_with_constraint("t2", None, JoinOperator::RightAnti)]
5751+
vec![join_with_constraint(
5752+
"t2",
5753+
None,
5754+
false,
5755+
JoinOperator::RightAnti
5756+
)]
57215757
);
57225758
assert_eq!(
57235759
only(&verified_only_select("SELECT * FROM t1 FULL JOIN t2 ON c1 = c2").from).joins,
5724-
vec![join_with_constraint("t2", None, JoinOperator::FullOuter)]
5760+
vec![join_with_constraint(
5761+
"t2",
5762+
None,
5763+
false,
5764+
JoinOperator::FullOuter
5765+
)]
5766+
);
5767+
5768+
assert_eq!(
5769+
only(&verified_only_select("SELECT * FROM t1 GLOBAL FULL JOIN t2 ON c1 = c2").from).joins,
5770+
vec![join_with_constraint(
5771+
"t2",
5772+
None,
5773+
true,
5774+
JoinOperator::FullOuter
5775+
)]
57255776
);
57265777
}
57275778

@@ -5742,6 +5793,7 @@ fn parse_joins_using() {
57425793
partitions: vec![],
57435794
with_ordinality: false,
57445795
},
5796+
global: false,
57455797
join_operator: f(JoinConstraint::Using(vec!["c1".into()])),
57465798
}
57475799
}
@@ -5806,6 +5858,7 @@ fn parse_natural_join() {
58065858
partitions: vec![],
58075859
with_ordinality: false,
58085860
},
5861+
global: false,
58095862
join_operator: f(JoinConstraint::Natural),
58105863
}
58115864
}
@@ -6074,6 +6127,7 @@ fn parse_derived_tables() {
60746127
partitions: vec![],
60756128
with_ordinality: false,
60766129
},
6130+
global: false,
60776131
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
60786132
}],
60796133
}),
@@ -6984,6 +7038,7 @@ fn lateral_function() {
69847038
],
69857039
alias: None,
69867040
},
7041+
global: false,
69877042
join_operator: JoinOperator::LeftOuter(JoinConstraint::None),
69887043
}],
69897044
}],

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
@@ -2213,6 +2213,7 @@ fn asof_joins() {
22132213
relation: table_with_alias("trades_unixtime", "tu"),
22142214
joins: vec![Join {
22152215
relation: table_with_alias("quotes_unixtime", "qu"),
2216+
global: false,
22162217
join_operator: JoinOperator::AsOf {
22172218
match_condition: Expr::BinaryOp {
22182219
left: Box::new(Expr::CompoundIdentifier(vec![

0 commit comments

Comments
 (0)