diff --git a/src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs b/src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs index 60c0547722f..596ab76b218 100644 --- a/src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs +++ b/src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs @@ -8,6 +8,7 @@ //------------------------------------------------------------------------------ +using System.Text.RegularExpressions; using NHibernate.Cfg.MappingSchema; using NHibernate.Mapping.ByCode; using NHibernate.Test.Hql.EntityJoinHqlTestEntities; @@ -152,6 +153,67 @@ public async Task EntityJoinFoSubqueryAsync() } } + [Test] + public async Task EntityJoinWithEntityComparisonInWithClausShouldNotAddJoinAsync() + { + using (var sqlLog = new SqlLogSpy()) + using (var session = OpenSession()) + { + EntityComplex entityComplex = + await (session + .CreateQuery( + "select ex " + + "from EntityComplex ex " + + "inner join EntityComplex st with st = ex.SameTypeChild " + ).SetMaxResults(1) + .UniqueResultAsync()); + + Assert.That(Regex.Matches(sqlLog.GetWholeLog(), "EntityComplex").Count, Is.EqualTo(2)); + Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected"); + } + } + + [Test] + public async Task EntityJoinWithEntityAssociationComparisonShouldAddJoinAsync() + { + using (var sqlLog = new SqlLogSpy()) + using (var session = OpenSession()) + { + EntityComplex entityComplex = + await (session + .CreateQuery( + "select ex " + + "from EntityComplex ex " + + "inner join EntityComplex st with st = ex.SameTypeChild.SameTypeChild " + ).SetMaxResults(1) + .UniqueResultAsync()); + + Assert.That(Regex.Matches(sqlLog.GetWholeLog(), "EntityComplex").Count, Is.EqualTo(3)); + Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected"); + } + } + + [Test] + public async Task EntityJoinWithEntityAssociationComparison2ShouldAddJoinAsync() + { + using (var sqlLog = new SqlLogSpy()) + using (var session = OpenSession()) + { + EntityComplex entityComplex = + await (session + .CreateQuery( + "select ex " + + "from EntityComplex ex " + + "inner join EntityComplex st with st.Version = ex.SameTypeChild.Version " + ).SetMaxResults(1) + .UniqueResultAsync()); + + Assert.That(Regex.Matches(sqlLog.GetWholeLog(), "EntityComplex").Count, Is.EqualTo(3)); + Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected"); + } + } + + [Test, Ignore("Failing for unrelated reasons")] public async Task CrossJoinAndWithClauseAsync() { diff --git a/src/NHibernate.Test/Hql/EntityJoinHqlTest.cs b/src/NHibernate.Test/Hql/EntityJoinHqlTest.cs index 1ed6d125db1..e9725bf62fe 100644 --- a/src/NHibernate.Test/Hql/EntityJoinHqlTest.cs +++ b/src/NHibernate.Test/Hql/EntityJoinHqlTest.cs @@ -1,4 +1,5 @@ -using NHibernate.Cfg.MappingSchema; +using System.Text.RegularExpressions; +using NHibernate.Cfg.MappingSchema; using NHibernate.Mapping.ByCode; using NHibernate.Test.Hql.EntityJoinHqlTestEntities; using NUnit.Framework; @@ -141,6 +142,67 @@ public void EntityJoinFoSubquery() } } + [Test] + public void EntityJoinWithEntityComparisonInWithClausShouldNotAddJoin() + { + using (var sqlLog = new SqlLogSpy()) + using (var session = OpenSession()) + { + EntityComplex entityComplex = + session + .CreateQuery( + "select ex " + + "from EntityComplex ex " + + "inner join EntityComplex st with st = ex.SameTypeChild " + ).SetMaxResults(1) + .UniqueResult(); + + Assert.That(Regex.Matches(sqlLog.GetWholeLog(), "EntityComplex").Count, Is.EqualTo(2)); + Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected"); + } + } + + [Test] + public void EntityJoinWithEntityAssociationComparisonShouldAddJoin() + { + using (var sqlLog = new SqlLogSpy()) + using (var session = OpenSession()) + { + EntityComplex entityComplex = + session + .CreateQuery( + "select ex " + + "from EntityComplex ex " + + "inner join EntityComplex st with st = ex.SameTypeChild.SameTypeChild " + ).SetMaxResults(1) + .UniqueResult(); + + Assert.That(Regex.Matches(sqlLog.GetWholeLog(), "EntityComplex").Count, Is.EqualTo(3)); + Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected"); + } + } + + [Test] + public void EntityJoinWithEntityAssociationComparison2ShouldAddJoin() + { + using (var sqlLog = new SqlLogSpy()) + using (var session = OpenSession()) + { + EntityComplex entityComplex = + session + .CreateQuery( + "select ex " + + "from EntityComplex ex " + + "inner join EntityComplex st with st.Version = ex.SameTypeChild.Version " + ).SetMaxResults(1) + .UniqueResult(); + + Assert.That(Regex.Matches(sqlLog.GetWholeLog(), "EntityComplex").Count, Is.EqualTo(3)); + Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected"); + } + } + + [Test, Ignore("Failing for unrelated reasons")] public void CrossJoinAndWithClause() { diff --git a/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs b/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs index 8e25ba37fd9..fddf68e9259 100644 --- a/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs +++ b/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs @@ -407,9 +407,9 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string // this is the regression style determination which matches the logic of the classic translator joinIsNeeded = generateJoin && ( !Walker.IsInSelect || !Walker.IsShallowQuery); } - else + else { - joinIsNeeded = generateJoin || ( (Walker.IsInSelect && !Walker.IsInCase ) || Walker.IsInFrom ); + joinIsNeeded = generateJoin || ((Walker.IsInSelect && !Walker.IsInCase) || (Walker.IsInFrom && !Walker.IsComparativeExpressionClause)); } if ( joinIsNeeded )