File tree Expand file tree Collapse file tree 7 files changed +63
-6
lines changed
Expand file tree Collapse file tree 7 files changed +63
-6
lines changed Original file line number Diff line number Diff line change @@ -2333,7 +2333,11 @@ impl fmt::Display for Join {
23332333 self . relation,
23342334 suffix( constraint)
23352335 ) ) ,
2336- JoinOperator :: CrossJoin => f. write_fmt ( format_args ! ( "CROSS JOIN {}" , self . relation) ) ,
2336+ JoinOperator :: CrossJoin ( constraint) => f. write_fmt ( format_args ! (
2337+ "CROSS JOIN {}{}" ,
2338+ self . relation,
2339+ suffix( constraint)
2340+ ) ) ,
23372341 JoinOperator :: Semi ( constraint) => f. write_fmt ( format_args ! (
23382342 "{}SEMI JOIN {}{}" ,
23392343 prefix( constraint) ,
@@ -2400,7 +2404,8 @@ pub enum JoinOperator {
24002404 Right ( JoinConstraint ) ,
24012405 RightOuter ( JoinConstraint ) ,
24022406 FullOuter ( JoinConstraint ) ,
2403- CrossJoin ,
2407+ /// CROSS (constraint is non-standard)
2408+ CrossJoin ( JoinConstraint ) ,
24042409 /// SEMI (non-standard)
24052410 Semi ( JoinConstraint ) ,
24062411 /// LEFT SEMI (non-standard)
Original file line number Diff line number Diff line change @@ -2226,7 +2226,7 @@ impl Spanned for JoinOperator {
22262226 JoinOperator :: Right ( join_constraint) => join_constraint. span ( ) ,
22272227 JoinOperator :: RightOuter ( join_constraint) => join_constraint. span ( ) ,
22282228 JoinOperator :: FullOuter ( join_constraint) => join_constraint. span ( ) ,
2229- JoinOperator :: CrossJoin => Span :: empty ( ) ,
2229+ JoinOperator :: CrossJoin ( join_constraint ) => join_constraint . span ( ) ,
22302230 JoinOperator :: LeftSemi ( join_constraint) => join_constraint. span ( ) ,
22312231 JoinOperator :: RightSemi ( join_constraint) => join_constraint. span ( ) ,
22322232 JoinOperator :: LeftAnti ( join_constraint) => join_constraint. span ( ) ,
Original file line number Diff line number Diff line change @@ -311,6 +311,11 @@ pub trait Dialect: Debug + Any {
311311 false
312312 }
313313
314+ /// Returns true if the dialect supports a join specification on CROSS JOIN.
315+ fn supports_cross_join_constraint ( & self ) -> bool {
316+ false
317+ }
318+
314319 /// Returns true if the dialect supports CONNECT BY.
315320 fn supports_connect_by ( & self ) -> bool {
316321 false
Original file line number Diff line number Diff line change @@ -163,6 +163,10 @@ impl Dialect for MySqlDialect {
163163 fn supports_data_type_signed_suffix ( & self ) -> bool {
164164 true
165165 }
166+
167+ fn supports_cross_join_constraint ( & self ) -> bool {
168+ true
169+ }
166170}
167171
168172/// `LOCK TABLES`
Original file line number Diff line number Diff line change @@ -13317,15 +13317,24 @@ impl<'a> Parser<'a> {
1331713317 let global = self.parse_keyword(Keyword::GLOBAL);
1331813318 let join = if self.parse_keyword(Keyword::CROSS) {
1331913319 let join_operator = if self.parse_keyword(Keyword::JOIN) {
13320- JoinOperator::CrossJoin
13320+ JoinOperator::CrossJoin(JoinConstraint::None)
1332113321 } else if self.parse_keyword(Keyword::APPLY) {
1332213322 // MSSQL extension, similar to CROSS JOIN LATERAL
1332313323 JoinOperator::CrossApply
1332413324 } else {
1332513325 return self.expected("JOIN or APPLY after CROSS", self.peek_token());
1332613326 };
13327+ let relation = self.parse_table_factor()?;
13328+ let join_operator = if matches!(join_operator, JoinOperator::CrossJoin(_))
13329+ && self.dialect.supports_cross_join_constraint()
13330+ {
13331+ let constraint = self.parse_join_constraint(false)?;
13332+ JoinOperator::CrossJoin(constraint)
13333+ } else {
13334+ join_operator
13335+ };
1332713336 Join {
13328- relation: self.parse_table_factor()? ,
13337+ relation,
1332913338 global,
1333013339 join_operator,
1333113340 }
Original file line number Diff line number Diff line change @@ -7131,7 +7131,7 @@ fn parse_cross_join() {
71317131 Join {
71327132 relation: table_from_name(ObjectName::from(vec![Ident::new("t2")])),
71337133 global: false,
7134- join_operator: JoinOperator::CrossJoin,
7134+ join_operator: JoinOperator::CrossJoin(JoinConstraint::None) ,
71357135 },
71367136 only(only(select.from).joins),
71377137 );
Original file line number Diff line number Diff line change @@ -4132,6 +4132,40 @@ fn parse_straight_join() {
41324132 . verified_stmt ( "SELECT a.*, b.* FROM table_a STRAIGHT_JOIN table_b AS b ON a.b_id = b.id" ) ;
41334133}
41344134
4135+ #[ test]
4136+ fn parse_cross_join_on ( ) {
4137+ let sql = "SELECT * FROM t1 CROSS JOIN t2 ON a = b" ;
4138+ let select = mysql ( ) . verified_only_select ( sql) ;
4139+ assert_eq ! (
4140+ Join {
4141+ relation: table_from_name( ObjectName :: from( vec![ Ident :: new( "t2" ) ] ) ) ,
4142+ global: false ,
4143+ join_operator: JoinOperator :: CrossJoin ( JoinConstraint :: On ( Expr :: BinaryOp {
4144+ left: Box :: new( Expr :: Identifier ( Ident :: new( "a" ) ) ) ,
4145+ op: BinaryOperator :: Eq ,
4146+ right: Box :: new( Expr :: Identifier ( Ident :: new( "b" ) ) ) ,
4147+ } ) ) ,
4148+ } ,
4149+ only( only( select. from) . joins) ,
4150+ ) ;
4151+ }
4152+
4153+ #[ test]
4154+ fn parse_cross_join_using ( ) {
4155+ let sql = "SELECT * FROM t1 CROSS JOIN t2 USING(a)" ;
4156+ let select = mysql ( ) . verified_only_select ( sql) ;
4157+ assert_eq ! (
4158+ Join {
4159+ relation: table_from_name( ObjectName :: from( vec![ Ident :: new( "t2" ) ] ) ) ,
4160+ global: false ,
4161+ join_operator: JoinOperator :: CrossJoin ( JoinConstraint :: Using ( vec![ ObjectName :: from(
4162+ vec![ Ident :: new( "a" ) ]
4163+ ) ] , ) ) ,
4164+ } ,
4165+ only( only( select. from) . joins) ,
4166+ ) ;
4167+ }
4168+
41354169#[ test]
41364170fn mysql_foreign_key_with_index_name ( ) {
41374171 mysql ( ) . verified_stmt (
You can’t perform that action at this time.
0 commit comments