Skip to content
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

HHH-3356 Support for normal and lateral subquery in from clause #5086

Merged
merged 1 commit into from
Jun 4, 2022

Conversation

beikov
Copy link
Contributor

@beikov beikov commented Jun 2, 2022

https://hibernate.atlassian.net/browse/HHH-3356

This adds support for sub queries in the from clause as roots and joins. Sub queries can have an optional lateral marker, which allows sub queries to refer to previous from clause nodes. Also see the SQL standard definition of LATERAL or the nice documentation text from PostgreSQL for more details: https://www.postgresql.org/docs/current/queries-table-expressions.html#QUERIES-LATERAL

The design follows what was discussed here which is, that tuple types and their model parts are determined based on the select items of a sub query. It is not necessary to define an explicit (managed) type in order to use this feature.

There are a few things missing which are mostly of "mechanical" nature, i.e. someone needs to do it, but there shouldn't be any technical challenge. These will be added to the next bug fix version of 6.1, given that this PR makes it into 6.1. This was done deliberately to be able for this feature to make it into 6.1.

The currently missing parts are:

  • DomainResult support for anonymous tuples i.e. select d from (select ...) d is not supported
  • Correlation support i.e. select ... from (select ...) d where (select ... where d.field = 1) is not supported
  • Support for selecting entity valued paths, where the entity type has an id class or embedded id. See SubQueryInFromEmbeddedIdTests and SubQueryInFromIdClassTests

@beikov beikov added the 6.1 label Jun 2, 2022
@gavinking
Copy link
Member

This looks rather good, assuming I'm understanding everything. A couple of comments:

  • Is there truly an advantage to requiring this explicit lateral? Could it be implicit? Is the reason for making it explicit that it's something that's only supported on one platform?
  • There's lots of tests for lateral, but not so many for plain vanilla from-clause subselects. I would like to see more of the "basic" case, so I can get a better feel for it.

@beikov
Copy link
Contributor Author

beikov commented Jun 2, 2022

Is there truly an advantage to requiring this explicit lateral? Could it be implicit? Is the reason for making it explicit that it's something that's only supported on one platform?

lateral, or cross apply how SQL server and some other DB vendors are calling this, essentially forces the database to process table scans/joins in a certain order and forces a nested loop join. So this is not something that we can or should do by default. If by implicit, you mean that if we can infer whether lateral is "required", then yes, that would be possible, though I'd say there are valid reasons for wanting to use lateral even if it isn't required.
Either lateral or cross apply are supported on the major DBMS (MySQL 8, PostgreSQL, Oracle, SQL Server, DB2, HSQL, HANA). We have an emulation for it for others DBs, but as you can imagine, it's not pretty and also limited to certain sub query shapes.

Either way, I'd rather not make this the default if that's what you mean by "implicit".

There's lots of tests for lateral, but not so many for plain vanilla from-clause subselects. I would like to see more of the "basic" case, so I can get a better feel for it.

I'll add a few more tests if that makes you feel better ;)

@gavinking
Copy link
Member

forces the database to process table scans/joins in a certain order and forces a nested loop join. So this is not something that we can or should do by default.

Well yeah but I'm not suggesting to generate the lateral keyword by default. I'm suggesting to automatically detect when it's required. Which seems straightforward?

@beikov
Copy link
Contributor Author

beikov commented Jun 2, 2022

Well yeah but I'm not suggesting to generate the lateral keyword by default. I'm suggesting to automatically detect when it's required. Which seems straightforward?

Right, we can determine this, but I wouldn't say it is "straightforward". The problem here is that JPA Criteria seems to allow accessing paths from the outer query regardless if the path base is correlated, so the check is not as simple as determining whether the set of correlated nodes is non-empty. We'd have to traverse the whole query tree to be sure. Maybe we could do that somehow during SQM->SQL AST translation, but it's not like I can just grab a flag from somewhere and do something like isLateral() || isCorrelated(). I can add this improvement to the list of things to do for 6.1.1 though.

@beikov beikov merged commit 341267b into hibernate:main Jun 4, 2022
@beikov beikov deleted the HHH-3356 branch June 4, 2022 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants