Skip to content

join syntax #459

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

Closed
ghost opened this issue Apr 14, 2022 · 3 comments
Closed

join syntax #459

ghost opened this issue Apr 14, 2022 · 3 comments

Comments

@ghost
Copy link

ghost commented Apr 14, 2022

If we do a join based on the syntax:
select a.id, b.id from mytable a join mytable1 b on a.id=b.id;

We get a single TablewithJoins strcut that shows how the join occurs (see below), but if we do:

select * from mytable a, mytable b where a.id=b.id;
We get two TableWithJoins but there is nothing that says how these two are joined together.. Should these two select statements produce the same TableWithJoin structure?

Here's the output from my tests:

 select a.id, b.id from mytable a join mytable1 b on a.id=b.id;
[TableWithJoins { relation: Table { name: ObjectName([Ident { value: "mytable", quote_style: None }]), alias: Some(TableAlias { name: Ident { value: "a", quote_style: None }, columns: [] }), args: [], with_hints: [] }, joins: [Join { relation: Table { name: ObjectName([Ident { value: "mytable1", quote_style: None }]), alias: Some(TableAlias { name: Ident { value: "b", quote_style: None }, columns: [] }), args: [], with_hints: [] }, join_operator: Inner(On(BinaryOp { left: CompoundIdentifier([Ident { value: "a", quote_style: None }, Ident { value: "id", quote_style: None }]), op: Eq, right: CompoundIdentifier([Ident { value: "b", quote_style: None }, Ident { value: "id", quote_style: None }]) })) }] }]


select * from mytable a, mytable b where a.id=b.id;
[TableWithJoins { relation: Table { name: ObjectName([Ident { value: "mytable", quote_style: None }]), alias: Some(TableAlias { name: Ident { value: "a", quote_style: None }, columns: [] }), args: [], with_hints: [] }, joins: [] }, TableWithJoins { relation: Table { name: ObjectName([Ident { value: "mytable", quote_style: None }]), alias: Some(TableAlias { name: Ident { value: "b", quote_style: None }, columns: [] }), args: [], with_hints: [] }, joins: [] }]
@ghost
Copy link
Author

ghost commented Apr 17, 2022

Here is the output for the 0.16.0 version:

sql: "SELECT a.* FROM mytable a join mytable b on a.id=b.id"
AST: [Query(Query { with: None, body: Select(Select { distinct: false, top: None, projection: [QualifiedWildcard(ObjectName([Ident { value: "a", quote_style: None }]))], into: None, from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "mytable", quote_style: None }]), alias: Some(TableAlias { name: Ident { value: "a", quote_style: None }, columns: [] }), args: [], with_hints: [] }, joins: [Join { relation: Table { name: ObjectName([Ident { value: "mytable", quote_style: None }]), alias: Some(TableAlias { name: Ident { value: "b", quote_style: None }, columns: [] }), args: [], with_hints: [] }, join_operator: Inner(On(BinaryOp { left: CompoundIdentifier([Ident { value: "a", quote_style: None }, Ident { value: "id", quote_style: None }]), op: Eq, right: CompoundIdentifier([Ident { value: "b", quote_style: None }, Ident { value: "id", quote_style: None }]) })) }] }], lateral_views: [], selection: None, group_by: [], cluster_by: [], distribute_by: [], sort_by: [], having: None }), order_by: [], limit: None, offset: None, fetch: None, lock: None })]

sql: "select a.* from mytable a, mytable b where a.id=b.id"
AST: [Query(Query { with: None, body: Select(Select { distinct: false, top: None, projection: [QualifiedWildcard(ObjectName([Ident { value: "a", quote_style: None }]))], into: None, from: [TableWithJoins { relation: Table { name: ObjectName([Ident { value: "mytable", quote_style: None }]), alias: Some(TableAlias { name: Ident { value: "a", quote_style: None }, columns: [] }), args: [], with_hints: [] }, joins: [] }, TableWithJoins { relation: Table { name: ObjectName([Ident { value: "mytable", quote_style: None }]), alias: Some(TableAlias { name: Ident { value: "b", quote_style: None }, columns: [] }), args: [], with_hints: [] }, joins: [] }], lateral_views: [], selection: Some(BinaryOp { left: CompoundIdentifier([Ident { value: "a", quote_style: None }, Ident { value: "id", quote_style: None }]), op: Eq, right: CompoundIdentifier([Ident { value: "b", quote_style: None }, Ident { value: "id", quote_style: None }]) }), group_by: [], cluster_by: [], distribute_by: [], sort_by: [], having: None }), order_by: [], limit: None, offset: None, fetch: None, lock: None })]

@nickolay
Copy link
Contributor

Since no-one had the chance to reply yet, and I was around when the current implementation landed in #109, I can share my perspective.

The parser's job is to produce the parse tree, i.e. determine the syntactic structure of the input text according to the grammar of the language. That's what it currently does -- you can see that in the SQL grammar, which we roughly follow, FROM and WHERE are two separate clauses.

You seem to want to do some semantic analysis, which is normally done in a separate step.

Note that there isn't a single universally correct answer to "how these are [supposed to be] joined together", if you're not content with the syntax-based answer. For instance the following slightly more complicated example:

foo
join bar on foo.x = bar.x
join baz on bar.x = baz.x
where foo.y = baz.y

..can be described

  • as 1) foo and bar are joined on x, 2) the result is joined with baz on {x,y}" or
  • as 1) foo is joined with baz on {x,y}, the result joined with bar on x
  • as well as foo, bar, and baz are joined on x, but only results where foo.y = baz.y are included in the results.

@ghost
Copy link
Author

ghost commented May 12, 2022

Thanks.. That makes sense.

@ghost ghost closed this as completed May 12, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant