Permalink
Browse files

Fix SQL Server dialect paging bug (NH-3138)

The MsSql2005DialectQueryPager was found to be incorrectly identifying
columns in the ORDER BY expression of a query that contains a function
with parameters separated by commas (e.g. "ORDER BY COALESCE(param1,
param2)").

Employed a regular expression for a more sophisticated method of
identifying the columns.
  • Loading branch information...
1 parent 7a7e91f commit 8d7b870012b6f9298d54b2caa732cb6ce1268c52 @julian-maughan julian-maughan committed May 16, 2012
@@ -0,0 +1,65 @@
+using System;
+using NHibernate.Mapping.ByCode;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH3138
+{
+ [TestFixture]
+ public class FixtureByCode : TestCaseMappingByCode
+ {
+ protected override bool AppliesTo(Dialect.Dialect dialect)
+ {
+ return dialect is Dialect.MsSql2005Dialect;
+ }
+
+ protected override Cfg.MappingSchema.HbmMapping GetMappings()
+ {
+ var mapper = new ModelMapper();
+ mapper.Class<Entity>(ca =>
+ {
+ ca.Lazy(false);
+ ca.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
+ ca.Property(x => x.EnglishName);
+ ca.Property(x => x.GermanName);
+ });
+
+ return mapper.CompileMappingForAllExplicitlyAddedEntities();
+ }
+
+ [Test]
+ public void PageQueryWithDistinctAndOrderByContainingFunctionWithCommaSeparatedParameters()
+ {
+ using (var session = OpenSession())
+ {
+ Assert.DoesNotThrow(() =>
+ session
+ .CreateQuery("select distinct e.Id, coalesce(e.EnglishName, e.GermanName) from Entity e order by coalesce(e.EnglishName, e.GermanName) asc")
+ .SetFirstResult(10)
+ .SetMaxResults(20)
+ .List<Entity>());
+ }
+ }
+
+ [Test]
+ [Ignore("Failing")]
+ public void PageQueryWithDistinctAndOrderByContainingAliasedFunction()
+ {
+ using (var session = OpenSession())
+ {
+ Assert.DoesNotThrow(() =>
+ session
+ .CreateQuery("select distinct e.Id, coalesce(e.EnglishName, e.GermanName) as LocalizedName from Entity e order by LocalizedName asc")
+ .SetFirstResult(10)
+ .SetMaxResults(20)
+ .List<Entity>());
+ }
+ }
+ }
+
+ class Entity
+ {
+ public Guid Id { get; set; }
+ public string EnglishName { get; set; }
+ public string GermanName { get; set; }
+ }
+}
@@ -963,6 +963,7 @@
<Compile Include="NHSpecificTest\NH3074\Fixture.cs" />
<Compile Include="NHSpecificTest\NH3074\Model.cs" />
<Compile Include="NHSpecificTest\NH3124\FixtureByCode.cs" />
+ <Compile Include="NHSpecificTest\NH3138\FixtureByCode.cs" />
<Compile Include="NHSpecificTest\NH941\Domain.cs" />
<Compile Include="NHSpecificTest\NH941\Fixture.cs" />
<Compile Include="NHSpecificTest\NH941\FixtureUsingList.cs" />
@@ -67,8 +67,8 @@ private SqlString PageByLimitAndOffset(SqlString offset, SqlString limit)
if (orderIndex > 0 && HasMatchingParens(_sourceQuery.Substring(orderIndex).ToString()))
{
fromAndWhere = _sourceQuery.Substring(fromIndex, orderIndex - fromIndex).Trim();
- SqlString orderBy = _sourceQuery.Substring(orderIndex).Trim();
- sortExpressions = orderBy.Substring(9).Split(",");
+ SqlString orderBy = _sourceQuery.Substring(orderIndex).Trim().Substring(9);
+ sortExpressions = orderBy.SplitWithRegex(@"(?<!\([^\)]*),{1}");
}
else
{
@@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using System.Collections;
+using System.Text.RegularExpressions;
namespace NHibernate.SqlCommand
{
@@ -557,6 +558,11 @@ public SqlString[] Split(string splitter)
return SplitParts(splitter).ToArray();
}
+ internal SqlString[] SplitWithRegex(string pattern)
+ {
+ return Regex.Split(ToString(), pattern).Select(Parse).ToArray();
+ }
+
private IEnumerable<SqlString> SplitParts(string splitter)
{
var startIndex = 0;

0 comments on commit 8d7b870

Please sign in to comment.