From: <ric...@us...> - 2010-09-04 23:33:08
|
Revision: 5180 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5180&view=rev Author: ricbrown Date: 2010-09-04 23:33:02 +0000 (Sat, 04 Sep 2010) Log Message: ----------- Fix NH-2258 (Paging params in subquery breaks query execution) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs trunk/nhibernate/src/NHibernate/Loader/Loader.cs trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2010-09-03 05:07:46 UTC (rev 5179) +++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2010-09-04 23:33:02 UTC (rev 5180) @@ -68,8 +68,9 @@ if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue) { + int maxResults = (criteriaImpl.MaxResults != RowSelection.NoValue) ? criteriaImpl.MaxResults : int.MaxValue; int? offsetParameterIndex = criteriaQuery.CreatePagingParameter(criteriaImpl.FirstResult); - int? limitParameterIndex = criteriaQuery.CreatePagingParameter(criteriaImpl.MaxResults); + int? limitParameterIndex = criteriaQuery.CreatePagingParameter(maxResults); sql = factory.Dialect.GetLimitString(sql, criteriaImpl.FirstResult, criteriaImpl.MaxResults, offsetParameterIndex, limitParameterIndex); } Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2010-09-03 05:07:46 UTC (rev 5179) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2010-09-04 23:33:02 UTC (rev 5180) @@ -1058,6 +1058,11 @@ return selection != null && selection.MaxRows != RowSelection.NoValue; } + private static bool HasOffset(RowSelection selection) + { + return selection != null && selection.MaxRows != RowSelection.NoValue; + } + internal static int GetFirstRow(RowSelection selection) { if (selection == null || !selection.DefinesLimits) @@ -1079,7 +1084,7 @@ /// <returns></returns> internal static bool UseLimit(RowSelection selection, Dialect.Dialect dialect) { - return dialect.SupportsLimit && HasMaxRows(selection); + return dialect.SupportsLimit && (HasMaxRows(selection) || HasOffset(selection)); } /// <summary> @@ -1202,6 +1207,9 @@ int firstRow = GetFirstRow(selection); int lastRow = selection.MaxRows; + if (lastRow == RowSelection.NoValue) + return int.MaxValue; + if (dialect.UseMaxForLimit) { return lastRow + firstRow; @@ -1230,10 +1238,7 @@ { return 0; } - if (!HasMaxRows(selection)) - { - throw new AssertionFailure("max results not set"); - } + int firstRow = GetFirstRow(selection); int lastRow = GetMaxOrLimit(dialect, selection); Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs 2010-09-03 05:07:46 UTC (rev 5179) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs 2010-09-04 23:33:02 UTC (rev 5180) @@ -312,6 +312,90 @@ } [Test] + public void SubqueryPaginationOnlyWithFirst() + { + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + session.Save(new Student { Name = "Mengano", StudentNumber = 232 }); + session.Save(new Student { Name = "Ayende", StudentNumber = 999 }); + session.Save(new Student { Name = "Fabio", StudentNumber = 123 }); + session.Save(new Student { Name = "Merlo", StudentNumber = 456 }); + session.Save(new Student { Name = "Fulano", StudentNumber = 0 }); + + t.Commit(); + } + + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + DetachedCriteria dc = DetachedCriteria.For(typeof(Student)) + .Add(Property.ForName("StudentNumber").Gt(0L)) + .SetFirstResult(1) + .AddOrder(Order.Asc("StudentNumber")) + .SetProjection(Property.ForName("Name")); + + var result = session.CreateCriteria(typeof(Student)) + .Add(Subqueries.PropertyIn("Name", dc)) + .List<Student>(); + + Assert.That(result.Count, Is.EqualTo(3)); + t.Commit(); + } + + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + session.CreateQuery("delete from Student").ExecuteUpdate(); + t.Commit(); + } + } + + [Test] + public void SubqueryPagination() + { + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + session.Save(new Student { Name = "Mengano", StudentNumber = 232 }); + session.Save(new Student { Name = "Ayende", StudentNumber = 999 }); + session.Save(new Student { Name = "Fabio", StudentNumber = 123 }); + session.Save(new Student { Name = "Merlo", StudentNumber = 456 }); + session.Save(new Student { Name = "Fulano", StudentNumber = 0 }); + + t.Commit(); + } + + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + DetachedCriteria dc = DetachedCriteria.For(typeof (Student)) + .Add(Property.ForName("StudentNumber").Gt(200L)) + .SetMaxResults(2) + .SetFirstResult(1) + .AddOrder(Order.Asc("StudentNumber")) + .SetProjection(Property.ForName("Name")); + + var result = session.CreateCriteria(typeof(Student)) + .Add(Subqueries.PropertyIn("Name", dc)) + .List<Student>(); + + Assert.That(result.Count, Is.EqualTo(2)); + Assert.That(result[0].StudentNumber, Is.EqualTo(456)); + Assert.That(result[1].StudentNumber, Is.EqualTo(999)); + + t.Commit(); + } + + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + session.CreateQuery("delete from Student").ExecuteUpdate(); + t.Commit(); + } + } + + [Test] public void SimplePagination() { using (ISession session = OpenSession()) @@ -350,6 +434,46 @@ } [Test] + public void SimplePaginationOnlyWithFirst() + { + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + session.Save(new Student {Name = "Mengano", StudentNumber = 232}); + session.Save(new Student {Name = "Ayende", StudentNumber = 999}); + session.Save(new Student {Name = "Fabio", StudentNumber = 123}); + session.Save(new Student {Name = "Merlo", StudentNumber = 456}); + session.Save(new Student {Name = "Fulano", StudentNumber = 0}); + + t.Commit(); + } + + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + var result = session.CreateCriteria<Student>() + .Add(Restrictions.Gt("StudentNumber", 0L)) + .AddOrder(Order.Asc("StudentNumber")) + .SetFirstResult(1) + .List<Student>(); + + Assert.That(result.Count, Is.EqualTo(3)); + Assert.That(result[0].StudentNumber, Is.EqualTo(232)); + Assert.That(result[1].StudentNumber, Is.EqualTo(456)); + Assert.That(result[2].StudentNumber, Is.EqualTo(999)); + + t.Commit(); + } + + using (ISession session = OpenSession()) + using (ITransaction t = session.BeginTransaction()) + { + session.CreateQuery("delete from Student").ExecuteUpdate(); + t.Commit(); + } + } + + [Test] public void CloningDetachedCriteriaTest() { DetachedCriteria dc = DetachedCriteria.For(typeof(Student)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |