Skip to content

Commit 5f01b69

Browse files
Test case and fix for NH-3079 on branch master
1 parent c6c904b commit 5f01b69

5 files changed

Lines changed: 164 additions & 17 deletions

File tree

src/NHibernate/Impl/AbstractQueryImpl.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,22 @@ public bool HasNamedParameters
7272

7373
protected internal virtual void VerifyParameters()
7474
{
75-
VerifyParameters(false);
75+
VerifyParameters(reserveFirstParameter: false, componentsParametersWillBeFlattened: false);
76+
}
77+
78+
/// <summary>
79+
///
80+
/// </summary>
81+
/// <param name="componentsParametersWillBeFlattened">
82+
/// FIX TO NH3079: Must be <c>true</c> when using positional parameters and
83+
/// value one or more parameter values can be component with no change of
84+
/// parameter placemarkers count. This is because on native sql queries
85+
/// 'components parameter' must always be positioned with as much
86+
/// parameter placemarks as ordinal values on components.
87+
/// </param>
88+
protected internal virtual void VerifyParameters(bool componentsParametersWillBeFlattened)
89+
{
90+
VerifyParameters(reserveFirstParameter: false, componentsParametersWillBeFlattened: componentsParametersWillBeFlattened);
7691
}
7792

7893
/// <summary>
@@ -82,7 +97,14 @@ protected internal virtual void VerifyParameters()
8297
/// if true, the first ? will not be verified since
8398
/// its needed for e.g. callable statements returning a out parameter
8499
/// </param>
85-
protected internal virtual void VerifyParameters(bool reserveFirstParameter)
100+
/// <param name="componentsParametersWillBeFlattened">
101+
/// FIX TO NH3079: Must be <c>true</c> when using positional parameters and
102+
/// value one or more parameter values can be component with no change of
103+
/// parameter placemarkers count. This is because on native sql queries
104+
/// 'components parameter' must always be positioned with as much
105+
/// parameter placemarks as ordinal values on components.
106+
/// </param>
107+
protected internal virtual void VerifyParameters(bool reserveFirstParameter, bool componentsParametersWillBeFlattened)
86108
{
87109
if (parameterMetadata.NamedParameterNames.Count != namedParameters.Count + namedParameterLists.Count)
88110
{
@@ -107,7 +129,15 @@ protected internal virtual void VerifyParameters(bool reserveFirstParameter)
107129
throw new QueryException("Unset positional parameter at position: " + i, QueryString);
108130
}
109131
}
110-
positionalValueSpan++;
132+
//FIX TO NH3079
133+
if (componentsParametersWillBeFlattened)
134+
{
135+
positionalValueSpan += ((IType)obj).GetColumnSpan(session.Factory);
136+
}
137+
else
138+
{
139+
positionalValueSpan++;
140+
}
111141
}
112142

113143
if (parameterMetadata.OrdinalParameterCount != positionalValueSpan)

src/NHibernate/Impl/AbstractQueryImpl2.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public override IQuery SetLockMode(string alias, LockMode lockMode)
2828

2929
public override int ExecuteUpdate()
3030
{
31-
VerifyParameters();
31+
//FIX TO NH3079
32+
VerifyParameters(componentsParametersWillBeFlattened: false);
3233
var namedParams = NamedParams;
3334
Before();
3435
try
@@ -43,7 +44,8 @@ public override int ExecuteUpdate()
4344

4445
public override IEnumerable Enumerable()
4546
{
46-
VerifyParameters();
47+
//FIX TO NH3079
48+
VerifyParameters(componentsParametersWillBeFlattened: false);
4749
var namedParams = NamedParams;
4850
Before();
4951
try
@@ -58,7 +60,8 @@ public override IEnumerable Enumerable()
5860

5961
public override IEnumerable<T> Enumerable<T>()
6062
{
61-
VerifyParameters();
63+
//FIX TO NH3079
64+
VerifyParameters(componentsParametersWillBeFlattened: false);
6265
var namedParams = NamedParams;
6366
Before();
6467
try
@@ -73,7 +76,8 @@ public override IEnumerable<T> Enumerable<T>()
7376

7477
public override IList List()
7578
{
76-
VerifyParameters();
79+
//FIX TO NH3079
80+
VerifyParameters(componentsParametersWillBeFlattened: false);
7781
var namedParams = NamedParams;
7882
Before();
7983
try
@@ -88,7 +92,8 @@ public override IList List()
8892

8993
public override void List(IList results)
9094
{
91-
VerifyParameters();
95+
//FIX TO NH3079
96+
VerifyParameters(componentsParametersWillBeFlattened: false);
9297
var namedParams = NamedParams;
9398
Before();
9499
try
@@ -103,7 +108,8 @@ public override void List(IList results)
103108

104109
public override IList<T> List<T>()
105110
{
106-
VerifyParameters();
111+
//FIX TO NH3079
112+
VerifyParameters(componentsParametersWillBeFlattened: false);
107113
var namedParams = NamedParams;
108114
Before();
109115
try

src/NHibernate/Impl/CollectionFilterImpl.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,32 @@ public CollectionFilterImpl(string queryString, object collection, ISessionImple
2121

2222
public override IEnumerable Enumerable()
2323
{
24-
VerifyParameters();
24+
//FIX TO NH3079
25+
VerifyParameters(componentsParametersWillBeFlattened: false);
2526
IDictionary<string, TypedValue> namedParams = NamedParams;
2627
return Session.EnumerableFilter(collection, ExpandParameterLists(namedParams), GetQueryParameters(namedParams));
2728
}
2829

2930
public override IEnumerable<T> Enumerable<T>()
3031
{
31-
VerifyParameters();
32+
//FIX TO NH3079
33+
VerifyParameters(componentsParametersWillBeFlattened: false);
3234
IDictionary<string, TypedValue> namedParams = NamedParams;
3335
return Session.EnumerableFilter<T>(collection, ExpandParameterLists(namedParams), GetQueryParameters(namedParams));
3436
}
3537

3638
public override IList List()
3739
{
38-
VerifyParameters();
40+
//FIX TO NH3079
41+
VerifyParameters(componentsParametersWillBeFlattened: false);
3942
IDictionary<string, TypedValue> namedParams = NamedParams;
4043
return Session.ListFilter(collection, ExpandParameterLists(namedParams), GetQueryParameters(namedParams));
4144
}
4245

4346
public override IList<T> List<T>()
4447
{
45-
VerifyParameters();
48+
//FIX TO NH3079
49+
VerifyParameters(componentsParametersWillBeFlattened: false);
4650
IDictionary<string, TypedValue> namedParams = NamedParams;
4751
return Session.ListFilter<T>(collection, ExpandParameterLists(namedParams), GetQueryParameters(namedParams));
4852
}

src/NHibernate/Impl/SqlQueryImpl.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ public override IType[] ReturnTypes
116116

117117
public override IList List()
118118
{
119-
VerifyParameters();
119+
//FIX TO NH3079
120+
VerifyParameters(componentsParametersWillBeFlattened: true);
120121
IDictionary<string, TypedValue> namedParams = NamedParams;
121122
NativeSQLQuerySpecification spec = GenerateQuerySpecification(namedParams);
122123
QueryParameters qp = GetQueryParameters(namedParams);
@@ -134,7 +135,8 @@ public override IList List()
134135

135136
public override void List(IList results)
136137
{
137-
VerifyParameters();
138+
//FIX TO NH3079
139+
VerifyParameters(componentsParametersWillBeFlattened: true);
138140
IDictionary<string, TypedValue> namedParams = NamedParams;
139141
NativeSQLQuerySpecification spec = GenerateQuerySpecification(namedParams);
140142
QueryParameters qp = GetQueryParameters(namedParams);
@@ -152,7 +154,8 @@ public override void List(IList results)
152154

153155
public override IList<T> List<T>()
154156
{
155-
VerifyParameters();
157+
//FIX TO NH3079
158+
VerifyParameters(componentsParametersWillBeFlattened: true);
156159
IDictionary<string, TypedValue> namedParams = NamedParams;
157160
NativeSQLQuerySpecification spec = GenerateQuerySpecification(namedParams);
158161
QueryParameters qp = GetQueryParameters(namedParams);
@@ -269,7 +272,14 @@ public ISQLQuery SetResultSetMapping(string name)
269272

270273
protected internal override void VerifyParameters()
271274
{
272-
base.VerifyParameters();
275+
//FIX TO NH3079
276+
VerifyParameters(componentsParametersWillBeFlattened: true);
277+
}
278+
279+
protected internal override void VerifyParameters(bool componentsParametersWillBeFlattened)
280+
{
281+
//FIX TO NH3079
282+
base.VerifyParameters(reserveFirstParameter: false, componentsParametersWillBeFlattened: true);
273283
bool noReturns = queryReturns == null || queryReturns.Count == 0;
274284
if (noReturns)
275285
{

src/NHibernate/Loader/Custom/CustomLoader.cs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,103 @@ protected internal override void AutoDiscoverTypes(IDataReader rs)
343343
transformerAliases = aliases.ToArray();
344344
}
345345

346+
public override ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session)
347+
{
348+
// FIX TO NH3079:
349+
if (queryParameters.NamedParameters.Count == 0 && queryParameters.PositionalParameterTypes.Length > 0)
350+
{
351+
IType[] flattenedPositionalParameterTypes =
352+
this.FlattenComponentParameterTypes(
353+
queryParameters.PositionalParameterTypes,
354+
session);
355+
object[] flattenedPositionalParameterValues =
356+
this.FlattenComponentParameterValues(
357+
queryParameters.PositionalParameterTypes,
358+
queryParameters.PositionalParameterValues,
359+
session);
360+
queryParameters.PositionalParameterTypes = flattenedPositionalParameterTypes;
361+
queryParameters.PositionalParameterValues = flattenedPositionalParameterValues;
362+
}
363+
return base.CreateSqlCommand(queryParameters, session);
364+
}
365+
366+
// FIX TO NH3079:
367+
protected internal virtual IType[] FlattenComponentParameterTypes(IType[] positionalParameterTypes, ISessionImplementor session)
368+
{
369+
List<IType> typesResult = new List<IType>();
370+
for (int i = 0; i < positionalParameterTypes.Length; i++)
371+
{
372+
IType typeItem = positionalParameterTypes[i];
373+
374+
int loopCount = 0;
375+
while (typeItem.IsEntityType)
376+
{
377+
EntityType entityTypeItem = (EntityType)typeItem;
378+
typeItem = entityTypeItem.GetIdentifierType(session);
379+
380+
if (loopCount++ > 200)
381+
{
382+
throw new HibernateException("unexpected situation here 'loopCount': " + loopCount);
383+
}
384+
}
385+
386+
if (typeItem.IsComponentType)
387+
{
388+
IAbstractComponentType componentTypeItem = (IAbstractComponentType)typeItem;
389+
IType[] subcalues =
390+
this.FlattenComponentParameterTypes(
391+
componentTypeItem.Subtypes,
392+
session);
393+
typesResult.AddRange(subcalues);
394+
}
395+
else
396+
{
397+
typesResult.Add(typeItem);
398+
}
399+
}
400+
401+
return typesResult.ToArray();
402+
}
403+
404+
// FIX TO NH3079:
405+
protected internal virtual object[] FlattenComponentParameterValues(IType[] positionalParameterTypes, object[] positionalParameterValues, ISessionImplementor session)
406+
{
407+
List<Object> valuesResult = new List<Object>();
408+
for (int i = 0; i < positionalParameterTypes.Length; i++)
409+
{
410+
IType typeItem = positionalParameterTypes[i];
411+
object valueItem = positionalParameterValues[i];
412+
413+
int loopCount = 0;
414+
while (typeItem.IsEntityType)
415+
{
416+
EntityType entityTypeItem = (EntityType)typeItem;
417+
typeItem = entityTypeItem.GetIdentifierType(session);
418+
valueItem = entityTypeItem.GetIdentifier(valueItem, session);
419+
if (loopCount++ > 200)
420+
{
421+
throw new HibernateException("unexpected situation here 'loopCount': " + loopCount);
422+
}
423+
}
424+
425+
if (typeItem.IsComponentType)
426+
{
427+
IAbstractComponentType componentTypeItem = (IAbstractComponentType)typeItem;
428+
object[] subValues =
429+
this.FlattenComponentParameterValues(
430+
componentTypeItem.Subtypes,
431+
componentTypeItem.GetPropertyValues(valueItem, session),
432+
session);
433+
valuesResult.AddRange(subValues);
434+
}
435+
else
436+
{
437+
valuesResult.Add(valueItem);
438+
}
439+
}
440+
441+
return valuesResult.ToArray();
442+
}
346443
protected override void ResetEffectiveExpectedType(IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters)
347444
{
348445
parameterSpecs.ResetEffectiveExpectedType(queryParameters);

0 commit comments

Comments
 (0)