|
From: <ric...@us...> - 2010-02-16 22:50:26
|
Revision: 4944
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4944&view=rev
Author: ricbrown
Date: 2010-02-16 22:50:19 +0000 (Tue, 16 Feb 2010)
Log Message:
-----------
Fix NH-1981 (Multiple SQL parameters generated for same HQL parameter)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs
trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs
trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs
trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs
trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs
trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs
trunk/nhibernate/src/NHibernate/Loader/Loader.cs
trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs
trunk/nhibernate/src/NHibernate.Test/Linq/RegresstionTests.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Model.cs
Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -50,19 +50,6 @@
{
return base.GetLimitString(querySqlString, offset, last);
}
- // we have to do this in order to support parameters in order clause, the foramt
- // that sql 2005 uses for paging means that we move the parameters around, which means,
- // that positions are lost, so we record them before making any changes.
- // NH-1528
- int parameterPositon = 0;
- foreach (var part in querySqlString.Parts)
- {
- Parameter param = part as Parameter;
- if (param == null)
- continue;
- param.OriginalPositionInQuery = parameterPositon;
- parameterPositon += 1;
- }
int fromIndex = GetFromIndex(querySqlString);
SqlString select = querySqlString.Substring(0, fromIndex);
Modified: trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -56,27 +56,8 @@
return;
}
- string name;
+ string name = formatter.GetParameterName(parameter.ParameterPosition ?? parameterIndex);
- if (queryIndexToNumberOfPreceedingParameters.Count == 0)
- {
- // there's only one query... no need to worry about indexes of parameters of previous queries
- name = formatter.GetParameterName(parameter.OriginalPositionInQuery ?? parameterIndex);
- }
- else
- {
- // multiple queries... in case the parameters were switched around (for SQL paging for instance) we need
- // to keep the number of preceeding parameters (in previous queries of the batch) into account
- if (parameter.OriginalPositionInQuery != null)
- {
- name = formatter.GetParameterName(GetNumberOfPreceedingParameters() + parameter.OriginalPositionInQuery.Value);
- }
- else
- {
- name = formatter.GetParameterName(parameterIndex);
- }
- }
-
parameterIndex++;
result.Append(name);
}
Modified: trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -86,7 +86,7 @@
{
queryParameters.ProcessFilters(customQuery.SQL, session);
SqlString sql = queryParameters.FilteredSQL;
- SqlType[] sqlTypes = GetParameterTypes(queryParameters, session);
+ SqlType[] sqlTypes = queryParameters.PrepareParameterTypes(sql, session.Factory, GetNamedParameterLocs, 0, false, false);
IDbCommand ps = session.Batcher.PrepareCommand(CommandType.Text, sql, sqlTypes);
@@ -102,7 +102,7 @@
// The responsibility of parameter binding was entirely moved to QueryParameters
// to deal with positionslParameter+NamedParameter+ParameterOfFilters
- queryParameters.BindParameters(ps, GetNamedParameterLocs, 0, session);
+ queryParameters.BindParameters(ps, 0, session);
result = session.Batcher.ExecuteNonQuery(ps);
}
finally
@@ -125,52 +125,5 @@
return result;
}
-
- private SqlType[] GetParameterTypes(QueryParameters parameters, ISessionImplementor session)
- {
- List<IType> paramTypeList = new List<IType>();
- int span = 0;
-
- foreach (IType type in parameters.PositionalParameterTypes)
- {
- paramTypeList.Add(type);
- span += type.GetColumnSpan(session.Factory);
- }
-
- if (parameters.NamedParameters != null && parameters.NamedParameters.Count > 0)
- {
- int offset = paramTypeList.Count;
-
- // convert the named parameters to an array of types
- foreach (KeyValuePair<string, TypedValue> e in parameters.NamedParameters)
- {
- string name = e.Key;
- TypedValue typedval = e.Value;
- int[] locs = GetNamedParameterLocs(name);
- span += typedval.Type.GetColumnSpan(session.Factory) * locs.Length;
-
- for (int i = 0; i < locs.Length; i++)
- {
- ArrayHelper.SafeSetValue(paramTypeList, locs[i] + offset, typedval.Type);
- }
- }
- }
- return ConvertITypesToSqlTypes(paramTypeList, span, session);
- }
-
- private static SqlType[] ConvertITypesToSqlTypes(IList<IType> nhTypes, int totalSpan, ISessionImplementor session)
- {
- SqlType[] result = new SqlType[totalSpan];
-
- int index = 0;
- foreach (IType type in nhTypes)
- {
- int span = type.SqlTypes(session.Factory).Length;
- Array.Copy(type.SqlTypes(session.Factory), 0, result, index, span);
- index += span;
- }
-
- return result;
- }
}
}
Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -6,6 +6,7 @@
using NHibernate.Hql.Classic;
using NHibernate.Impl;
using NHibernate.SqlCommand;
+using NHibernate.SqlTypes;
using NHibernate.Transform;
using NHibernate.Type;
using NHibernate.Util;
@@ -392,31 +393,162 @@
processedSQL = result.ToSqlString();
}
- public int BindParameters(IDbCommand command, GetNamedParameterLocations getNamedParameterLocations, int start,
- ISessionImplementor session)
+ private IList<Parameter> ResetParameterLocations(SqlString sqlString)
{
+ IList<Parameter> sqlParameters = new List<Parameter>();
+
+ foreach (object sqlParameter in sqlString.Parts)
+ {
+ if (sqlParameter is Parameter)
+ {
+ Parameter parameter = (Parameter)sqlParameter;
+ parameter.ParameterPosition = null;
+ sqlParameters.Add(parameter);
+ }
+ }
+
+ return sqlParameters;
+ }
+
+ private void SetParameterLocation(IList<Parameter> sqlParameters, int parameterIndex, int sqlLocation, int span)
+ {
+ int i = 0;
+ while (i < span)
+ {
+ sqlParameters[sqlLocation + i].ParameterPosition = parameterIndex + i;
+ i++;
+ }
+ }
+
+ private SqlType[] ConvertITypesToSqlTypes(List<IType> nhTypes, ISessionFactoryImplementor factory, int totalSpan)
+ {
+ SqlType[] result = new SqlType[totalSpan];
+
+ int index = 0;
+ foreach (IType type in nhTypes)
+ {
+ int span = type.SqlTypes(factory).Length;
+ Array.Copy(type.SqlTypes(factory), 0, result, index, span);
+ index += span;
+ }
+
+ return result;
+ }
+
+ public SqlType[] PrepareParameterTypes(SqlString sqlString, ISessionFactoryImplementor factory, GetNamedParameterLocations getNamedParameterLocations, int startParameterIndex, bool addLimit, bool addOffset)
+ {
+ List<IType> paramTypeList = new List<IType>();
+ int parameterIndex = 0;
+ int totalSpan = 0;
+
+ IList<Parameter> sqlParameters = ResetParameterLocations(sqlString);
+
+ for (int index = 0; index < PositionalParameterTypes.Length; index++)
+ {
+ IType type = PositionalParameterTypes[index];
+ ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, type);
+
+ int location = PositionalParameterLocations[index];
+ location = FindAdjustedParameterLocation(location);
+ int span = type.GetColumnSpan(factory);
+ SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span);
+
+ totalSpan += span;
+ parameterIndex++;
+ }
+
+ for (int index = 0; index < FilteredParameterTypes.Count; index++)
+ {
+ IType type = FilteredParameterTypes[index];
+ ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, type);
+
+ int location = FilteredParameterLocations[index];
+ int span = type.GetColumnSpan(factory);
+ SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span);
+
+ totalSpan += span;
+ parameterIndex++;
+ }
+
+ if (NamedParameters != null && NamedParameters.Count > 0)
+ {
+ // convert the named parameters to an array of types
+ foreach (KeyValuePair<string, TypedValue> namedParameter in NamedParameters)
+ {
+ TypedValue typedval = namedParameter.Value;
+ ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, typedval.Type);
+
+ int span = typedval.Type.GetColumnSpan(factory);
+ string name = namedParameter.Key;
+ int[] locs = getNamedParameterLocations(name);
+ for (int i = 0; i < locs.Length; i++)
+ {
+ int location = locs[i];
+ location = FindAdjustedParameterLocation(location);
+
+ // can still clash with positional parameters
+ // could consider throwing an exception to locate problem (NH-1098)
+ while ((location < sqlParameters.Count) && (sqlParameters[location].ParameterPosition != null))
+ location++;
+
+ SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span);
+ }
+
+ totalSpan += span;
+ parameterIndex++;
+ }
+ }
+
+ if (addLimit && factory.Dialect.SupportsVariableLimit)
+ {
+ if (factory.Dialect.BindLimitParametersFirst)
+ {
+ paramTypeList.Insert(0, NHibernateUtil.Int32);
+ if (addOffset)
+ {
+ paramTypeList.Insert(0, NHibernateUtil.Int32);
+ }
+ }
+ else
+ {
+ paramTypeList.Add(NHibernateUtil.Int32);
+ if (addOffset)
+ {
+ paramTypeList.Add(NHibernateUtil.Int32);
+ }
+ }
+
+ totalSpan += addOffset ? 2 : 1;
+ }
+
+ return ConvertITypesToSqlTypes(paramTypeList, factory, totalSpan);
+ }
+
+ public int BindParameters(IDbCommand command, int start, ISessionImplementor session)
+ {
+ int location = 0;
var values = new List<object>();
var types = new List<IType>();
var sources = new List<string>();
for (int i = 0; i < _positionalParameterLocations.Length; i++)
{
- int location = FindAdjustedParameterLocation(_positionalParameterLocations[i]);
object value = _positionalParameterValues[i];
IType type = _positionalParameterTypes[i];
ArrayHelper.SafeSetValue(values, location, value);
ArrayHelper.SafeSetValue(types, location, type);
ArrayHelper.SafeSetValue(sources, location, "Positional" + i);
+ location++;
}
for (int i = 0; i < filteredParameterLocations.Count; i++)
{
- int location = filteredParameterLocations[i];
object value = filteredParameterValues[i];
IType type = filteredParameterTypes[i];
ArrayHelper.SafeSetValue(values, location, value);
ArrayHelper.SafeSetValue(types, location, type);
ArrayHelper.SafeSetValue(sources, location, "Filter" + i);
+ location++;
}
if ((_namedParameters != null) && (_namedParameters.Count > 0))
@@ -425,22 +557,10 @@
{
string name = namedParameter.Key;
TypedValue typedval = namedParameter.Value;
- int[] locations = getNamedParameterLocations(name);
- for (int i = 0; i < locations.Length; i++)
- {
- int location = FindAdjustedParameterLocation(locations[i]);
-
- // can still clash with positional parameters
- // could consider throwing an exception to locate problem (NH-1098)
- while ((location < types.Count) && (types[location] != null))
- {
- location++;
- }
-
- ArrayHelper.SafeSetValue(values, location, typedval.Value);
- ArrayHelper.SafeSetValue(types, location, typedval.Type);
- ArrayHelper.SafeSetValue(sources, location, "name" + i);
- }
+ ArrayHelper.SafeSetValue(values, location, typedval.Value);
+ ArrayHelper.SafeSetValue(types, location, typedval.Type);
+ ArrayHelper.SafeSetValue(sources, location, "name_" + name);
+ location++;
}
}
Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -180,7 +180,7 @@
translators.Add(translator);
QueryParameters queryParameters = translator.GetQueryParameters();
parameters.Add(queryParameters);
- SqlCommandInfo commandInfo = loader.GetQueryStringAndTypes(session, queryParameters);
+ SqlCommandInfo commandInfo = loader.GetQueryStringAndTypes(session, queryParameters, types.Count);
sqlString = sqlString.Append(commandInfo.Text)
.Append(session.Factory.ConnectionProvider.Driver.MultipleQueriesSeparator)
.Append(Environment.NewLine);
@@ -339,7 +339,7 @@
for (int i = 0; i < loaders.Count; i++)
{
QueryParameters parameter = parameters[i];
- colIndex += parameter.BindParameters(command, loaders[i].GetNamedParameterLocs, colIndex, session);
+ colIndex += parameter.BindParameters(command, colIndex, session);
}
return colIndex;
}
Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -616,7 +616,7 @@
translators.Add(translator);
parameters.Add(queryParameters);
queryParameters = GetFilteredQueryParameters(queryParameters, translator);
- SqlCommandInfo commandInfo = translator.Loader.GetQueryStringAndTypes(session, queryParameters);
+ SqlCommandInfo commandInfo = translator.Loader.GetQueryStringAndTypes(session, queryParameters, types.Count);
sqlString = sqlString.Append(commandInfo.Text).Append(session.Factory.ConnectionProvider.Driver.MultipleQueriesSeparator).Append(Environment.NewLine);
types.AddRange(commandInfo.ParameterTypes);
}
@@ -668,7 +668,7 @@
{
IQueryTranslator translator = Translators[i];
QueryParameters parameter = Parameters[i];
- colIndex += parameter.BindParameters(command, translator.Loader.GetNamedParameterLocs, colIndex, session);
+ colIndex += parameter.BindParameters(command, colIndex, session);
}
return colIndex;
}
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Remotion.Data.Linq.Parsing;
@@ -23,12 +24,17 @@
protected override Expression VisitConstantExpression(ConstantExpression expression)
{
- if (!typeof(IQueryable).IsAssignableFrom(expression.Type))
+ if (!typeof(IQueryable).IsAssignableFrom(expression.Type) && !IsNullObject(expression))
{
_parameters.Add(expression, new NamedParameter("p" + (_parameters.Count + 1), expression.Value, NHibernateUtil.GuessType(expression.Type)));
}
return base.VisitConstantExpression(expression);
}
+
+ private bool IsNullObject(ConstantExpression expression)
+ {
+ return expression.Type == typeof(Object) && expression.Value == null;
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -1106,6 +1106,8 @@
bool useOffset = hasFirstRow && useLimit && dialect.SupportsLimitOffset;
// TODO NH bool callable = queryParameters.Callable;
+ SqlType[] parameterTypes = queryParameters.PrepareParameterTypes(sqlString, Factory, GetNamedParameterLocs, 0, useLimit, useOffset);
+
if (useLimit)
{
sqlString =
@@ -1116,8 +1118,7 @@
// TODO NH: Callable for SP -> PrepareCallableQueryCommand
IDbCommand command =
- session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString,
- GetParameterTypes(queryParameters, useLimit, useOffset));
+ session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, parameterTypes);
try
{
@@ -1263,7 +1264,7 @@
// NH Different behavior:
// The responsibility of parameter binding was entirely moved to QueryParameters
// to deal with positionslParameter+NamedParameter+ParameterOfFilters
- return queryParameters.BindParameters(statement, GetNamedParameterLocs, 0, session);
+ return queryParameters.BindParameters(statement, 0, session);
}
public virtual int[] GetNamedParameterLocs(string name)
@@ -1683,7 +1684,7 @@
#region NHibernate specific
- public virtual SqlCommandInfo GetQueryStringAndTypes(ISessionImplementor session, QueryParameters parameters)
+ public virtual SqlCommandInfo GetQueryStringAndTypes(ISessionImplementor session, QueryParameters parameters, int startParameterIndex)
{
SqlString sqlString = ProcessFilters(parameters, session);
Dialect.Dialect dialect = session.Factory.Dialect;
@@ -1693,6 +1694,8 @@
bool hasFirstRow = GetFirstRow(selection) > 0;
bool useOffset = hasFirstRow && useLimit && dialect.SupportsLimitOffset;
+ SqlType[] sqlTypes = parameters.PrepareParameterTypes(sqlString, Factory, GetNamedParameterLocs, startParameterIndex, useLimit, useOffset);
+
if (useLimit)
{
sqlString =
@@ -1700,97 +1703,9 @@
}
sqlString = PreprocessSQL(sqlString, parameters, dialect);
- return new SqlCommandInfo(sqlString, GetParameterTypes(parameters, useLimit, useOffset));
+ return new SqlCommandInfo(sqlString, sqlTypes);
}
- protected SqlType[] ConvertITypesToSqlTypes(List<IType> nhTypes, int totalSpan)
- {
- SqlType[] result = new SqlType[totalSpan];
-
- int index = 0;
- foreach (IType type in nhTypes)
- {
- int span = type.SqlTypes(Factory).Length;
- Array.Copy(type.SqlTypes(Factory), 0, result, index, span);
- index += span;
- }
-
- return result;
- }
-
- /// <returns><see cref="IList" /> of <see cref="IType" /></returns>
- protected SqlType[] GetParameterTypes(QueryParameters parameters, bool addLimit, bool addOffset)
- {
- List<IType> paramTypeList = new List<IType>();
- int span = 0;
-
- for (int index = 0; index < parameters.PositionalParameterTypes.Length; index++)
- {
- int location = parameters.PositionalParameterLocations[index];
- location = parameters.FindAdjustedParameterLocation(location);
- IType type = parameters.PositionalParameterTypes[index];
- ArrayHelper.SafeSetValue(paramTypeList, location, type);
- span += type.GetColumnSpan(Factory);
- }
-
- for (int index = 0; index < parameters.FilteredParameterTypes.Count; index++)
- {
- int location = parameters.FilteredParameterLocations[index];
- IType type = parameters.FilteredParameterTypes[index];
- ArrayHelper.SafeSetValue(paramTypeList, location, type);
- span += type.GetColumnSpan(Factory);
- }
-
- if (parameters.NamedParameters != null && parameters.NamedParameters.Count > 0)
- {
- // convert the named parameters to an array of types
- foreach (KeyValuePair<string, TypedValue> namedParameter in parameters.NamedParameters)
- {
- string name = namedParameter.Key;
- TypedValue typedval = namedParameter.Value;
- int[] locs = GetNamedParameterLocs(name);
- span += typedval.Type.GetColumnSpan(Factory) * locs.Length;
-
- for (int i = 0; i < locs.Length; i++)
- {
- int location = locs[i];
- location = parameters.FindAdjustedParameterLocation(location);
-
- // can still clash with positional parameters
- // could consider throwing an exception to locate problem (NH-1098)
- while ((location < paramTypeList.Count) && (paramTypeList[location] != null))
- location++;
-
- ArrayHelper.SafeSetValue(paramTypeList, location, typedval.Type);
- }
- }
- }
-
- if (addLimit && Factory.Dialect.SupportsVariableLimit)
- {
- if (Factory.Dialect.BindLimitParametersFirst)
- {
- paramTypeList.Insert(0, NHibernateUtil.Int32);
- if (addOffset)
- {
- paramTypeList.Insert(0, NHibernateUtil.Int32);
- }
- }
- else
- {
- paramTypeList.Add(NHibernateUtil.Int32);
- if (addOffset)
- {
- paramTypeList.Add(NHibernateUtil.Int32);
- }
- }
-
- span += addOffset ? 2 : 1;
- }
-
- return ConvertITypesToSqlTypes(paramTypeList, span);
- }
-
#endregion
}
}
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -10,16 +10,13 @@
[Serializable]
public class Parameter
{
- /// <summary>
+ /// <summary>
/// We need to know what the position of the parameter was in a query
/// before we rearranged the query.
- /// This is used only by dialects that rearrange the query, unfortunately,
- /// the MS SQL 2005 dialect have to re shuffle the query (and ruin positional parameter
- /// support) because the SQL 2005 and 2008 SQL dialects have a completely broken
- /// support for paging, which is just a tad less important than SELECT.
- /// See NH-1528
- /// </summary>
- public int? OriginalPositionInQuery;
+ /// This is the ADO parameter position that this SqlString parameter is
+ /// bound to. The SqlString can be safely rearranged once this is set.
+ /// </summary>
+ public int? ParameterPosition;
/// <summary>
/// Used as a placeholder when parsing HQL or SQL queries.
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/RegresstionTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/RegresstionTests.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/RegresstionTests.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -1,5 +1,6 @@
using System.Linq;
using NUnit.Framework;
+using NHibernate.Test.Linq.Entities;
namespace NHibernate.Test.Linq
{
@@ -10,7 +11,7 @@
/// http://aspzone.com/tech/nhibernate-linq-troubles/
/// </summary>
[Test]
- public void HierarchicalQueries()
+ public void HierarchicalQueries_InlineConstant()
{
var children = from s in db.Role
where s.ParentRole != null
@@ -24,5 +25,32 @@
Assert.AreEqual(2, roots.Count());
}
+
+ [Test]
+ public void HierarchicalQueries_Variable()
+ {
+ Role testRole = null;
+ var children = from s in db.Role
+ where s.ParentRole != testRole
+ select s;
+
+ Assert.AreEqual(0, children.Count());
+
+ var roots = from s in db.Role
+ where s.ParentRole == testRole
+ select s;
+
+ Assert.AreEqual(2, roots.Count());
+ }
+ [Test]
+ public void CanUseNullConstantAndRestriction()
+ {
+ var roots = from s in db.Role
+ where s.ParentRole == null
+ && s.Name == "Admin"
+ select s;
+
+ Assert.AreEqual(1, roots.Count());
+ }
}
}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using NHibernate.Cfg;
+using NHibernate.Tool.hbm2ddl;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1981
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ [Test]
+ public void CanGroupWithParameter()
+ {
+ using (ISession s = OpenSession())
+ using (ITransaction tx = s.BeginTransaction())
+ {
+ s.Save(new Article() { Longitude = 90 });
+ s.Save(new Article() { Longitude = 90 });
+ s.Save(new Article() { Longitude = 120 });
+
+ IList<double> quotients =
+ s.CreateQuery(
+ @"select (Longitude / :divisor)
+ from Article
+ group by (Longitude / :divisor)")
+ .SetDouble("divisor", 30)
+ .List<double>();
+
+ Assert.That(quotients.Count, Is.EqualTo(2));
+ Assert.That(quotients[0], Is.EqualTo(3));
+ Assert.That(quotients[1], Is.EqualTo(4));
+ }
+ }
+ }
+}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Mappings.hbm.xml 2010-02-16 22:50:19 UTC (rev 4944)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.NHSpecificTest.NH1981"
+ assembly="NHibernate.Test">
+
+ <class name="Article">
+ <id name="Id">
+ <generator class="hilo" />
+ </id>
+ <property name="Longitude" />
+ </class>
+</hibernate-mapping>
+
+
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Model.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Model.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Model.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+
+namespace NHibernate.Test.NHSpecificTest.NH1981
+{
+ public class Article
+ {
+ public virtual int Id { get; set; }
+ public virtual double Longitude { get; set; }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-02-16 22:50:19 UTC (rev 4944)
@@ -663,6 +663,8 @@
<Compile Include="NHSpecificTest\NH1978\AliasTest.cs" />
<Compile Include="NHSpecificTest\NH1978\Employee.cs" />
<Compile Include="NHSpecificTest\NH1978\_401k.cs" />
+ <Compile Include="NHSpecificTest\NH1981\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH1981\Model.cs" />
<Compile Include="NHSpecificTest\NH1989\Fixture.cs" />
<Compile Include="NHSpecificTest\NH1989\Model.cs" />
<Compile Include="NHSpecificTest\NH2009\Fixture.cs" />
@@ -2121,6 +2123,7 @@
<EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" />
<EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="NHSpecificTest\NH1981\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2074\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2077\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2020\Mappings.hbm.xml" />
Modified: trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs 2010-02-07 12:15:51 UTC (rev 4943)
+++ trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs 2010-02-16 22:50:19 UTC (rev 4944)
@@ -375,8 +375,8 @@
Assert.AreEqual(parameterString1, parameterString2);
Assert.AreNotSame(parameterString1, parameterString2);
- parameters1[0].OriginalPositionInQuery = 231;
- Assert.IsNull(parameters2[0].OriginalPositionInQuery);
+ parameters1[0].ParameterPosition = 231;
+ Assert.IsNull(parameters2[0].ParameterPosition);
}
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|