Skip to content

Commit 4a63f7f

Browse files
committed
Do not set guessed type as expected parameter type
1 parent d2599c6 commit 4a63f7f

File tree

6 files changed

+230
-3
lines changed

6 files changed

+230
-3
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System.Linq;
12+
using NHibernate.Cfg.MappingSchema;
13+
using NHibernate.Mapping.ByCode;
14+
using NUnit.Framework;
15+
using NHibernate.Linq;
16+
17+
namespace NHibernate.Test.NHSpecificTest.NH3565
18+
{
19+
using System.Threading.Tasks;
20+
[TestFixture]
21+
public class ByCodeFixtureAsync : TestCaseMappingByCode
22+
{
23+
protected override HbmMapping GetMappings()
24+
{
25+
var mapper = new ModelMapper();
26+
mapper.Class<Entity>(rc =>
27+
{
28+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
29+
rc.Property(x => x.Name, m =>
30+
{
31+
m.Type(NHibernateUtil.AnsiString);
32+
m.Length(10);
33+
});
34+
});
35+
36+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
37+
}
38+
39+
protected override void OnSetUp()
40+
{
41+
using (var session = OpenSession())
42+
using (var transaction = session.BeginTransaction())
43+
{
44+
var e1 = new Entity { Name = "Bob" };
45+
session.Save(e1);
46+
47+
var e2 = new Entity { Name = "Sally" };
48+
session.Save(e2);
49+
50+
transaction.Commit();
51+
}
52+
}
53+
54+
protected override void OnTearDown()
55+
{
56+
using (var session = OpenSession())
57+
using (var transaction = session.BeginTransaction())
58+
{
59+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
60+
61+
transaction.Commit();
62+
}
63+
}
64+
65+
[Test]
66+
public async Task ParameterTypeForLikeIsProperlyDetectedAsync()
67+
{
68+
using(var logSpy = new SqlLogSpy())
69+
using (var session = OpenSession())
70+
{
71+
var result = from e in session.Query<Entity>()
72+
where NHibernate.Linq.SqlMethods.Like(e.Name, "Bob")
73+
select e;
74+
75+
Assert.That(await (result.ToListAsync()), Has.Count.EqualTo(1));
76+
Assert.That(logSpy.GetWholeLog().Contains("Type: AnsiString (10"));
77+
}
78+
}
79+
80+
[KnownBug("Not fixed yet")]
81+
[Test]
82+
public async Task ParameterTypeForContainsIsProperlyDetectedAsync()
83+
{
84+
using(var logSpy = new SqlLogSpy())
85+
using (var session = OpenSession())
86+
{
87+
var result = from e in session.Query<Entity>()
88+
where e.Name.Contains("Bob")
89+
select e;
90+
91+
Assert.That(await (result.ToListAsync()), Has.Count.EqualTo(1));
92+
Assert.That(logSpy.GetWholeLog().Contains("Type: AnsiString (10"));
93+
}
94+
}
95+
96+
[KnownBug("Not fixed yet")]
97+
[Test]
98+
public async Task ParameterTypeForStartsWithIsProperlyDetectedAsync()
99+
{
100+
using(var logSpy = new SqlLogSpy())
101+
using (var session = OpenSession())
102+
{
103+
var result = from e in session.Query<Entity>()
104+
where e.Name.StartsWith("Bob")
105+
select e;
106+
107+
Assert.That(await (result.ToListAsync()), Has.Count.EqualTo(1));
108+
Assert.That(logSpy.GetWholeLog().Contains("Type: AnsiString (10"));
109+
}
110+
}
111+
}
112+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH3565
4+
{
5+
class Entity
6+
{
7+
public virtual Guid Id { get; set; }
8+
public virtual string Name { get; set; }
9+
}
10+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System.Linq;
2+
using NHibernate.Cfg.MappingSchema;
3+
using NHibernate.Mapping.ByCode;
4+
using NUnit.Framework;
5+
6+
namespace NHibernate.Test.NHSpecificTest.NH3565
7+
{
8+
[TestFixture]
9+
public class ByCodeFixture : TestCaseMappingByCode
10+
{
11+
protected override HbmMapping GetMappings()
12+
{
13+
var mapper = new ModelMapper();
14+
mapper.Class<Entity>(rc =>
15+
{
16+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
17+
rc.Property(x => x.Name, m =>
18+
{
19+
m.Type(NHibernateUtil.AnsiString);
20+
m.Length(10);
21+
});
22+
});
23+
24+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
25+
}
26+
27+
protected override void OnSetUp()
28+
{
29+
using (var session = OpenSession())
30+
using (var transaction = session.BeginTransaction())
31+
{
32+
var e1 = new Entity { Name = "Bob" };
33+
session.Save(e1);
34+
35+
var e2 = new Entity { Name = "Sally" };
36+
session.Save(e2);
37+
38+
transaction.Commit();
39+
}
40+
}
41+
42+
protected override void OnTearDown()
43+
{
44+
using (var session = OpenSession())
45+
using (var transaction = session.BeginTransaction())
46+
{
47+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
48+
49+
transaction.Commit();
50+
}
51+
}
52+
53+
[Test]
54+
public void ParameterTypeForLikeIsProperlyDetected()
55+
{
56+
using(var logSpy = new SqlLogSpy())
57+
using (var session = OpenSession())
58+
{
59+
var result = from e in session.Query<Entity>()
60+
where NHibernate.Linq.SqlMethods.Like(e.Name, "Bob")
61+
select e;
62+
63+
Assert.That(result.ToList(), Has.Count.EqualTo(1));
64+
Assert.That(logSpy.GetWholeLog().Contains("Type: AnsiString (10"));
65+
}
66+
}
67+
68+
[KnownBug("Not fixed yet")]
69+
[Test]
70+
public void ParameterTypeForContainsIsProperlyDetected()
71+
{
72+
using(var logSpy = new SqlLogSpy())
73+
using (var session = OpenSession())
74+
{
75+
var result = from e in session.Query<Entity>()
76+
where e.Name.Contains("Bob")
77+
select e;
78+
79+
Assert.That(result.ToList(), Has.Count.EqualTo(1));
80+
Assert.That(logSpy.GetWholeLog().Contains("Type: AnsiString (10"));
81+
}
82+
}
83+
84+
[KnownBug("Not fixed yet")]
85+
[Test]
86+
public void ParameterTypeForStartsWithIsProperlyDetected()
87+
{
88+
using(var logSpy = new SqlLogSpy())
89+
using (var session = OpenSession())
90+
{
91+
var result = from e in session.Query<Entity>()
92+
where e.Name.StartsWith("Bob")
93+
select e;
94+
95+
Assert.That(result.ToList(), Has.Count.EqualTo(1));
96+
Assert.That(logSpy.GetWholeLog().Contains("Type: AnsiString (10"));
97+
}
98+
}
99+
}
100+
}

src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ IASTNode GenerateNamedParameter(IASTNode delimiterNode, IASTNode nameNode)
10521052
);
10531053

10541054
parameter.HqlParameterSpecification = paramSpec;
1055-
if (_namedParameters != null && _namedParameters.TryGetValue(name, out var namedParameter))
1055+
if (_namedParameters != null && _namedParameters.TryGetValue(name, out var namedParameter) && namedParameter.IsGuessedType == false)
10561056
{
10571057
// Add the parameter type information so that we are able to calculate functions return types
10581058
// when the parameter is used as an argument.

src/NHibernate/Linq/Visitors/ParameterTypeLocator.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ internal static void SetParameterTypes(
9393
continue;
9494
}
9595

96-
namedParameter.Type = GetParameterType(sessionFactory, constantExpressions, visitor, namedParameter);
96+
namedParameter.Type = GetParameterType(sessionFactory, constantExpressions, visitor, namedParameter, out var isGuessedType);
97+
namedParameter.IsGuessedType = isGuessedType;
9798
}
9899
}
99100

@@ -145,8 +146,10 @@ private static IType GetParameterType(
145146
ISessionFactoryImplementor sessionFactory,
146147
HashSet<ConstantExpression> constantExpressions,
147148
ConstantTypeLocatorVisitor visitor,
148-
NamedParameter namedParameter)
149+
NamedParameter namedParameter,
150+
out bool isGuessedType)
149151
{
152+
isGuessedType = false;
150153
// All constant expressions have the same type/value
151154
var constantExpression = constantExpressions.First();
152155
var constantType = constantExpression.Type.UnwrapIfNullable();
@@ -156,6 +159,7 @@ private static IType GetParameterType(
156159
return candidateType;
157160
}
158161

162+
isGuessedType = true;
159163
// No related MemberExpressions was found, guess the type by value or its type when null.
160164
// When a numeric parameter is compared to different columns with different types (e.g. Where(o => o.Single >= singleParam || o.Double <= singleParam))
161165
// do not change the parameter type, but instead cast the parameter when comparing with different column types.

src/NHibernate/Param/NamedParameter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ internal NamedParameter(string name, object value, IType type, bool isCollection
2020
public string Name { get; private set; }
2121
public object Value { get; internal set; }
2222
public IType Type { get; internal set; }
23+
internal bool IsGuessedType { get; set; }
2324

2425
public virtual bool IsCollection { get; }
2526

0 commit comments

Comments
 (0)