Reuse parse_joins function

This commit is contained in:
Simon Vandel Sillesen 2025-06-29 16:02:29 +02:00
parent 330a9252af
commit 324ad14701
2 changed files with 11 additions and 116 deletions

View file

@ -11297,117 +11297,17 @@ impl<'a> Parser<'a> {
alias,
});
}
Keyword::JOIN => {
let relation = self.parse_table_factor()?;
let constraint = self.parse_join_constraint(false)?;
if matches!(constraint, JoinConstraint::None) {
return Err(ParserError::ParserError(
"JOIN in pipe syntax requires ON or USING clause".to_string(),
));
}
let join_operator = JoinOperator::Join(constraint);
pipe_operators.push(PipeOperator::Join(Join {
relation,
global: false,
join_operator,
}))
}
Keyword::INNER => {
self.expect_keyword(Keyword::JOIN)?;
let relation = self.parse_table_factor()?;
let constraint = self.parse_join_constraint(false)?;
if matches!(constraint, JoinConstraint::None) {
return Err(ParserError::ParserError(
"INNER JOIN in pipe syntax requires ON or USING clause".to_string(),
));
}
let join_operator = JoinOperator::Inner(constraint);
pipe_operators.push(PipeOperator::Join(Join {
relation,
global: false,
join_operator,
}))
}
Keyword::LEFT => {
let outer = self.parse_keyword(Keyword::OUTER);
self.expect_keyword(Keyword::JOIN)?;
let relation = self.parse_table_factor()?;
let constraint = self.parse_join_constraint(false)?;
if matches!(constraint, JoinConstraint::None) {
let join_type = if outer {
"LEFT OUTER JOIN"
} else {
"LEFT JOIN"
};
return Err(ParserError::ParserError(format!(
"{} in pipe syntax requires ON or USING clause",
join_type
)));
}
let join_operator = if outer {
JoinOperator::LeftOuter(constraint)
} else {
JoinOperator::Left(constraint)
};
pipe_operators.push(PipeOperator::Join(Join {
relation,
global: false,
join_operator,
}))
}
Keyword::RIGHT => {
let outer = self.parse_keyword(Keyword::OUTER);
self.expect_keyword(Keyword::JOIN)?;
let relation = self.parse_table_factor()?;
let constraint = self.parse_join_constraint(false)?;
if matches!(constraint, JoinConstraint::None) {
let join_type = if outer {
"RIGHT OUTER JOIN"
} else {
"RIGHT JOIN"
};
return Err(ParserError::ParserError(format!(
"{} in pipe syntax requires ON or USING clause",
join_type
)));
}
let join_operator = if outer {
JoinOperator::RightOuter(constraint)
} else {
JoinOperator::Right(constraint)
};
pipe_operators.push(PipeOperator::Join(Join {
relation,
global: false,
join_operator,
}))
}
Keyword::FULL => {
let _outer = self.parse_keyword(Keyword::OUTER);
self.expect_keyword(Keyword::JOIN)?;
let relation = self.parse_table_factor()?;
let constraint = self.parse_join_constraint(false)?;
if matches!(constraint, JoinConstraint::None) {
return Err(ParserError::ParserError(
"FULL JOIN in pipe syntax requires ON or USING clause".to_string(),
));
}
let join_operator = JoinOperator::FullOuter(constraint);
pipe_operators.push(PipeOperator::Join(Join {
relation,
global: false,
join_operator,
}))
}
Keyword::CROSS => {
self.expect_keyword(Keyword::JOIN)?;
let relation = self.parse_table_factor()?;
let join_operator = JoinOperator::CrossJoin;
pipe_operators.push(PipeOperator::Join(Join {
relation,
global: false,
join_operator,
}))
Keyword::JOIN
| Keyword::INNER
| Keyword::LEFT
| Keyword::RIGHT
| Keyword::FULL
| Keyword::CROSS => {
self.prev_token();
let mut joins = self.parse_joins()?;
// Take first
let join = joins.swap_remove(0);
pipe_operators.push(PipeOperator::Join(join))
}
unhandled => {
return Err(ParserError::ParserError(format!(

View file

@ -15587,11 +15587,6 @@ fn parse_pipeline_operator_negative_tests() {
.parse_sql_statements("SELECT * FROM users |> JOIN ON users.id = orders.user_id")
.is_err());
// Test that JOIN without ON or USING condition fails (except CROSS JOIN)
assert!(dialects
.parse_sql_statements("SELECT * FROM users |> JOIN orders")
.is_err());
// Test that CROSS JOIN with ON condition fails
assert!(dialects
.parse_sql_statements(