mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-23 08:15:00 +00:00
Require that nested joins always have one join
The SQL specification prohibits constructions like SELECT * FROM a NATURAL JOIN (b) where b sits alone inside parentheses. Parentheses in a FROM entry always introduce either a derived table or a join.
This commit is contained in:
parent
8bee74277a
commit
4ee461bae4
3 changed files with 27 additions and 1 deletions
|
@ -238,6 +238,10 @@ pub enum TableFactor {
|
||||||
subquery: Box<SQLQuery>,
|
subquery: Box<SQLQuery>,
|
||||||
alias: Option<TableAlias>,
|
alias: Option<TableAlias>,
|
||||||
},
|
},
|
||||||
|
/// Represents a parenthesized join expression, such as
|
||||||
|
/// `(foo <JOIN> bar [ <JOIN> baz ... ])`.
|
||||||
|
/// The inner `TableWithJoins` can have no joins only if its
|
||||||
|
/// `relation` is itself a `TableFactor::NestedJoin`.
|
||||||
NestedJoin(Box<TableWithJoins>),
|
NestedJoin(Box<TableWithJoins>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1719,6 +1719,16 @@ impl Parser {
|
||||||
// we won't, and we'll return that error instead.
|
// we won't, and we'll return that error instead.
|
||||||
self.index = index;
|
self.index = index;
|
||||||
let table_and_joins = self.parse_table_and_joins()?;
|
let table_and_joins = self.parse_table_and_joins()?;
|
||||||
|
match table_and_joins.relation {
|
||||||
|
TableFactor::NestedJoin { .. } => (),
|
||||||
|
_ => {
|
||||||
|
if table_and_joins.joins.is_empty() {
|
||||||
|
// The SQL spec prohibits derived tables and bare
|
||||||
|
// tables from appearing alone in parentheses.
|
||||||
|
self.expected("joined table", self.peek_token())?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
self.expect_token(&Token::RParen)?;
|
self.expect_token(&Token::RParen)?;
|
||||||
Ok(TableFactor::NestedJoin(Box::new(table_and_joins)))
|
Ok(TableFactor::NestedJoin(Box::new(table_and_joins)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1742,6 +1742,12 @@ fn parse_join_nesting() {
|
||||||
from.joins,
|
from.joins,
|
||||||
vec![join(nest!(nest!(nest!(table("b"), table("c")))))]
|
vec![join(nest!(nest!(nest!(table("b"), table("c")))))]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let res = parse_sql_statements("SELECT * FROM (a NATURAL JOIN (b))");
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected joined table, found: )".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1873,7 +1879,13 @@ fn parse_derived_tables() {
|
||||||
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
|
join_operator: JoinOperator::Inner(JoinConstraint::Natural),
|
||||||
}],
|
}],
|
||||||
}))
|
}))
|
||||||
)
|
);
|
||||||
|
|
||||||
|
let res = parse_sql_statements("SELECT * FROM ((SELECT 1) AS t)");
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected joined table, found: )".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue