-
Notifications
You must be signed in to change notification settings - Fork 612
Properly handle mixed implicit and explicit joins #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Pull Request Test Coverage Report for Build 330
💛 - Coveralls |
@nickolay I realize this is likely to be a bit prickly, as it is a substantial refactoring of a core AST. I wanted to flesh out what it looked like, though, and it didn't turn out to be too bad. Note that because we now support nested joins, we could alternatively parse
But perhaps downstream consumers will want to distinguish between implicit and explicit cross joins. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent, thank you! I had some ideas about naming / organization, but feel free to merge in any case.
src/sqlast/query.rs
Outdated
@@ -197,6 +192,23 @@ impl ToString for SQLSelectItem { | |||
} | |||
} | |||
|
|||
/// A table reference is one table factor followed by any number of joins. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get that this follows the names of the productions in ANSI SQL syntax, but maybe TableWithJoins
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I find them hard to remember too. I've taken your suggestion for TableWithJoins
.
src/sqlast/query.rs
Outdated
base: Box<TableFactor>, | ||
joins: Vec<Join>, | ||
}, | ||
NestedJoin(Box<TableReference>), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given https://github.com/andygrove/sqlparser-rs/pull/108#pullrequestreview-247376543 maybe call it TableFactor::Nested
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something about this whole design wasn't sitting right with me, so I decided to address the underlying issue you brought up in #108, rather than renaming this variant. I've pushed two commits that make it so that NestedJoin always contains a table reference with at least one join. A nice side effect of this work was supporting derived tables with set operations, like SELECT * FROM (((SELECT 1) UNION (SELECT 2)) t1 NATURAL JOIN t2)
.
src/sqlparser.rs
Outdated
group_by, | ||
having, | ||
}) | ||
} | ||
|
||
pub fn parse_table_reference(&mut self) -> Result<TableReference, ParserError> { | ||
let relation = self.parse_table_factor()?; | ||
let joins = self.parse_joins()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would parse_joins
be useful elsewhere? Perhaps inline it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, not that I can see. Inlined!
Could you please extract the new Making two parse attempts bothers me, plus the names from the spec ( |
7210715
to
94c23f3
Compare
Yep, working on that now. I'll open a new PR for the remaining changes as soon as this lands. |
Parse a query like SELECT * FROM a NATURAL JOIN b, c NATURAL JOIN d as the SQL specification requires, i.e.: from: [ TableReference { relation: TableFactor::Table("a"), joins: [Join { relation: TableFactor::Table("b"), join_operator: JoinOperator::Natural, }] }, TableReference { relation: TableFactor::Table("c"), joins: [Join { relation: TableFactor::Table("d"), join_operator: JoinOperator::Natural, }] } ] Previously we were parsing such queries as relation: TableFactor::Table("a"), joins: [ Join { relation: TableFactor::Table("b"), join_operator: JoinOperator::Natural, }, Join { relation: TableFactor::Table("c"), join_operator: JoinOperator::Implicit, }, Join { relation: TableFactor::Table("d"), join_operator: JoinOperator::Natural, }, ] which did not make the join hierarchy clear.
94c23f3
to
ce171c2
Compare
This is a follow-up to apache#109 which moved the handling of Token::Comma from parse_table_and_joins to the `FROM` parser.
Parse a query like
as the SQL specification requires, i.e.:
Previously we were parsing such queries as
which did not make the join hierarchy clear.