-
Notifications
You must be signed in to change notification settings - Fork 934
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
Exception executing HQL query with uncorrelated left joins in subselect #3334
Comments
Generate correct outer joins in case it is explicit in a subselect
from ChildEntity children1_
--...
LEFT JOIN ROOT.OtherEntity AS otherEntity I would say it's invalid hql. What does this join do in subquery? It makes no sense to me. SELECT ROOT
FROM Entity AS ROOT
LEFT JOIN ROOT.OtherEntity AS otherEntity -- MOVED HERE
WHERE
EXISTS
(FROM ELEMENTS(ROOT.Children) AS child
LEFT JOIN child.Child AS grandChild
WHERE
grandChild.Name like 'G%'
OR otherEntity.Name like 'G%'
) |
HQL documentation does not mention any restrictions on such joins and the same way you can place outer joins in SQL wherever you want, it could be handled in HQL. That query worked fine in NHibernate 1.2.1. and it is not hand-written HQL but generated from our application. |
It's another case of #1228 It's actually mentioned in original issue discussion that provided hql looks wrong. I also already mentioned it: #2146 (comment) |
There is nothing mentioned in HQL doc that it is illegal and it worked (quite far) in the past. I guess you would allow a query where an implied join is made like so: SELECT ROOT
FROM Entity AS ROOT
WHERE
EXISTS
(FROM ELEMENTS(ROOT.Children) AS child
WHERE
child.Child.Name like 'G%'
OR ROOT.OtherEntity.Name like 'A%'
) Then why an explicit left join should be forbidden? In some cases (depending on the mapping), this would even lead to an outer join in the generated SQL inside the subselect. But not in mine... I get a theta join with that hql so I would like to have the explicit outer join. |
Ok. Ideally, we should support such nonsensical joins too. Only your initial fix is wrong. In #2146 implicit join is generated instead of requested explicit join. I had to add some hacks too properly handle it in #2990 (see 32fdfec) Your current PR is just another hack supporting your specific case. If you need such joins fix it properly and remove my hack. The following query would still fail with your suggested fix: q = session.CreateQuery(
@"
SELECT ROOT
FROM Entity AS ROOT
WHERE
EXISTS
(FROM ChildEntity AS child
LEFT JOIN child.Child AS grandChild
LEFT JOIN ROOT.OtherEntity AS otherEntity
WHERE
grandChild.Name like 'A%'
OR otherEntity.Name like 'A%'
)");
Assert.AreEqual(1, q.List().Count); |
Yep, I also have a feeling that my fix won't handle all the posssible cases... It would be ideal if the code in #2146 would not be required, it was a workaround already then but it was driven by the comment that the from clause processor will take care of adding it to the right place. I would be willing to do some further steps but it's really not an easy task because of those complex interdependencies. |
Convert EntityJoin to FROM_FRAGMENT only for first element Adjust comment in HqlSqlWalker before adding an element without Parent to the tree and use AppendFromElement instead of direct AddChild
Generate correct outer joins in case it is explicit in a subselect
The base situation
We have a data model like this one
The associations to OtherEntity and GrandChildEntity are mapped as
many-to-one
.When executing the HQL query ...
The problem
... we get the following sql generated:
This leads to an exception because the comma
,
before the lastleft outer join
is illegal.Side note on why we don't use direct dot-navigations instead of explicit joins
Using implied joins on the :1-navigations like in the following query does not work because then, the joins are created as
inner join
or theta join so the condition is not evaluated correctly if there is not OtherEntity associated with Entity:I might start a separate discussion on Nullability and
many-to-one
because of that.The text was updated successfully, but these errors were encountered: