Subqueries in the FROM clause #3768
Replies: 6 comments 25 replies
-
So at the base, an So another option would be to:
Not sure it makes sense to allow such a subquery as a root however |
Beta Was this translation helpful? Give feedback.
-
Thanks @beikov. So the way I naïvely view it is as follows: what is the type of a subquery expression? Or, phrased slightly differently, what is the type of a "table" expression? An intuitive answer could indeed by that well, in Hibernate we represent tables as entity classes, so table expression are entities. And that's not a terrible idea, however, I fear it makes subqueries (and by extension CTEs) somewhat less useful, and actually isn't anyway a perfect fit.
Indeed, in light of 2 and 3, one sees that if subquery expression corresponds to a class it actually corresponds much more closely to a HQL Unfortunately But returning to 1, I really question whether we want these table expressions to map to Java classes at all. I think the most natural thing is to treat them as tuples, or more precisely record types. (A record type is a tuple where the tuple elements have names.) So I would think that the following is rather natural
where the Now, it's true that you wouldn't be able to write:
since we don't have a way to map records into Java. But what is the actual use case for that anyway? I don't actually see it. On the other hand, you could write:
and all the other sorts of things you can already write in HQL Hell, perhaps we could even let you write:
Though I'm still not at all clear on how that would be useful. Now, on the other hand, what if the subselect
But what's happening here is that we're picking the entity-typed member out of the record type. |
Beta Was this translation helpful? Give feedback.
-
I mean, arguing purely on the basis of regularity, a |
Beta Was this translation helpful? Give feedback.
-
Again, I personally think that the proper model here is at the SQM level. Sure that approach won't match nicely with the JPA contracts, but honestly who cares? This is explicitly something JPA does not support and so its not necessarily going to map to the JPA contracts cleanly. BTW we have a similar problem with "entity joins" as well in terms of not mapping cleanly. In JPA a join is always based on an attribute. So we have to fudge some of the JP contract impls to account for that. |
Beta Was this translation helpful? Give feedback.
-
So let's put this to a vote... Which approach do we think is the best? Also, who is going to implement this (because their opinion should have a certain weight to it)? |
Beta Was this translation helpful? Give feedback.
-
I'll close this discussion for now, since the "dynamic" approach that everyone preferred was implemented as part of this PR: #5086 Further discussion can happen on that PR, or if we think this is not ready yet, reopen this here. |
Beta Was this translation helpful? Give feedback.
-
Up until now, HQL only supported scalar subqueries
select * from ... where (select ... from ...) = ...
.The proposal is to also support subqueries in FROM clause like e.g.
select * from (select ... from ..) x
.This allows to logically separate concerns into smaller queries which helps dealing with complexity and increases reusability.
One of the fundamental questions that has to be answered is, how to represent the type of a subquery in the query model.
Currently, we represent FROM clause nodes as
SqmFrom
andSqmRoot
which require a model type that is a subtype ofjavax.persistence.metamodel.Bindable
andjavax.persistence.metamodel.EntityType
respectively.The possible options for modelling this are:
EntityType
/ManagedType
that is created on-demand per query. Something like a "tuple type"Ad-Hoc type
The idea is, that during query parsing, we figure out the select item aliases and types of such subqueries in FROM clauses and construct an ad-hoc
EntityType
/ManagedType
.For every select item, we create an attribute in the ad-hoc
EntityType
/ManagedType
with the respective select item result type.The
SqmFrom
/SqmRoot
object for this subquery then uses the ad-hoc type as model type.Pros
Cons
select e from (...) e
Explicit entity type
The idea is that a user has to explicitly declare a special kind of entity type, much like
@Subselect
entities.In the query, the user then somehow binds the select items to the attributes of the special entity.
A possible syntax could be
FROM entityName LP queryExpression RP alias (LP attributeNames+ RP)?
which binds select items positionally to attribute names, or matches the select item aliases to attribute names.In an example like
select e from SpecialEntity(select n.id as id, n.name as label, 123 as number from Node n) e
orselect e from SpecialEntity(select n.id, n.name, 123 from Node n) e(id, label, number)
we bind the first select item to the attribute
id
, the second tolabel
and the third tonumber
.The
SpecialEntity
could look like the following:Pros
select e from (...) e
Cons
Note that subqueries in a FROM clause are very similar to (IMO a subset of) CTEs. A CTE is like a database view, a query with a name, with the exception that it is bound to a main query within which it is declared.
Beta Was this translation helpful? Give feedback.
All reactions