Skip to content

Commit a3244ea

Browse files
on condition requirement for join
1 parent 0fb2ef3 commit a3244ea

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

src/parser/mod.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10102,10 +10102,30 @@ impl<'a> Parser<'a> {
1010210102
};
1010310103
let relation = self.parse_table_factor()?;
1010410104
let join_constraint = self.parse_join_constraint(natural)?;
10105+
let join_operator = join_operator_type(join_constraint);
10106+
10107+
let requires_constraint = match join_operator {
10108+
JoinOperator::Inner(JoinConstraint::None)
10109+
| JoinOperator::LeftOuter(JoinConstraint::None)
10110+
| JoinOperator::RightOuter(JoinConstraint::None)
10111+
| JoinOperator::FullOuter(JoinConstraint::None)
10112+
| JoinOperator::LeftSemi(JoinConstraint::None)
10113+
| JoinOperator::RightSemi(JoinConstraint::None)
10114+
| JoinOperator::LeftAnti(JoinConstraint::None)
10115+
| JoinOperator::RightAnti(JoinConstraint::None)
10116+
| JoinOperator::Semi(JoinConstraint::None)
10117+
| JoinOperator::Anti(JoinConstraint::None) => !natural,
10118+
_ => false,
10119+
};
10120+
10121+
if requires_constraint {
10122+
self.expected("ON, or USING after JOIN", self.peek_token())?
10123+
}
10124+
1010510125
Join {
1010610126
relation,
1010710127
global,
10108-
join_operator: join_operator_type(join_constraint),
10128+
join_operator,
1010910129
}
1011010130
};
1011110131
joins.push(join);
@@ -10914,7 +10934,6 @@ impl<'a> Parser<'a> {
1091410934
Ok(JoinConstraint::Using(columns))
1091510935
} else {
1091610936
Ok(JoinConstraint::None)
10917-
//self.expected("ON, or USING after JOIN", self.peek_token())
1091810937
}
1091910938
}
1092010939

tests/sqlparser_common.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7444,7 +7444,7 @@ fn lateral_derived() {
74447444

74457445
#[test]
74467446
fn lateral_function() {
7447-
let sql = "SELECT * FROM customer LEFT JOIN LATERAL generate_series(1, customer.id)";
7447+
let sql = "SELECT * FROM customer CROSS JOIN LATERAL generate_series(1, customer.id)";
74487448
let actual_select_only = verified_only_select(sql);
74497449
let expected = Select {
74507450
distinct: None,
@@ -7485,7 +7485,7 @@ fn lateral_function() {
74857485
alias: None,
74867486
},
74877487
global: false,
7488-
join_operator: JoinOperator::LeftOuter(JoinConstraint::None),
7488+
join_operator: JoinOperator::CrossJoin,
74897489
}],
74907490
}],
74917491
lateral_views: vec![],
@@ -12198,3 +12198,47 @@ fn parse_create_table_select() {
1219812198
);
1219912199
}
1220012200
}
12201+
12202+
#[test]
12203+
fn parse_no_condition_join_strategy() {
12204+
let dialects = all_dialects_where(|d| d.supports_create_table_select());
12205+
12206+
let join_types = vec![
12207+
"JOIN",
12208+
"INNER JOIN",
12209+
"LEFT JOIN",
12210+
"LEFT OUTER JOIN",
12211+
"RIGHT JOIN",
12212+
"RIGHT OUTER JOIN",
12213+
"FULL JOIN",
12214+
"FULL OUTER JOIN",
12215+
"CROSS JOIN",
12216+
"NATURAL JOIN",
12217+
"LEFT SEMI JOIN",
12218+
"RIGHT SEMI JOIN",
12219+
"LEFT ANTI JOIN",
12220+
"RIGHT ANTI JOIN",
12221+
"SEMI JOIN",
12222+
"ANTI JOIN",
12223+
];
12224+
12225+
for join in join_types {
12226+
let sql = format!(
12227+
"SELECT * FROM (SELECT 1 AS id, 'Foo' AS name) AS l {} (SELECT 1 AS id, 'Bar' AS name) AS r",
12228+
join
12229+
);
12230+
let result = dialects.parse_sql_statements(&sql);
12231+
if join.starts_with("CROSS") || join.starts_with("NATURAL") {
12232+
// CROSS JOIN and NATURAL JOIN don't require ON or USING clauses
12233+
assert!(result.is_ok());
12234+
} else {
12235+
// Other joins require ON or USING clauses
12236+
assert_eq!(
12237+
result.unwrap_err(),
12238+
ParserError::ParserError(
12239+
"Expected: ON, or USING after JOIN, found: EOF".to_string()
12240+
)
12241+
);
12242+
}
12243+
}
12244+
}

tests/sqlparser_hive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ fn test_distribute_by() {
285285

286286
#[test]
287287
fn no_join_condition() {
288-
let join = "SELECT a, b FROM db.table_name JOIN a";
288+
let join = "SELECT a, b FROM db.table_name CROSS JOIN a";
289289
hive().verified_stmt(join);
290290
}
291291

0 commit comments

Comments
 (0)