Skip to content

Commit a67407c

Browse files
committed
Merge branch '6.0' into 6.0-wrong-join-type-for-refs
# Conflicts: # ChangeLog/6.0.13_dev.txt
2 parents 2664edb + cca040d commit a67407c

File tree

10 files changed

+308
-32
lines changed

10 files changed

+308
-32
lines changed

ChangeLog/6.0.13_dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[main] Fixed certain cases of bad translation of casts via 'as' operator in LINQ queries
22
[main] Addressed certain issues of translation connected with comparison with local entity instace within LINQ queries
33
[main] Fixed rare issues of incorrect translation of filtered index expressions including conditional expressions
4+
[main] Join/LeftJoin is denied to have the same expression instance for both inner/outer selector.
45
[main] Addressed issue when wrong type of join was chosen when .First/FirstOrDefalult() method was used as subquery
56
[postgresql] Fixed issue of incorrect translation of contitional expressions including comparison with nullable fields

Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0/Translator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ public override string Translate(SqlCompilerContext context, object literalValue
286286
return TranslateByteArrayLiteral((byte[]) literalValue);
287287
}
288288
if (literalType == WellKnownTypes.GuidType) {
289-
return QuoteString(SqlHelper.GuidToString((Guid) literalValue));
289+
return string.Format("uuid'{0}'", SqlHelper.GuidToString((Guid) literalValue));
290290
}
291291
if (literalType == WellKnownTypes.DateTimeOffsetType) {
292292
return ((DateTimeOffset) literalValue).ToString(DateTimeOffsetFormatString);

Orm/Xtensive.Orm.SqlServer/Sql.Drivers.SqlServer/v09/Translator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,8 @@ public override string Translate(SqlCompilerContext context, object literalValue
539539
builder.AppendHexArray(array);
540540
return builder.ToString();
541541
}
542-
if (literalType==typeof(Guid))
543-
return QuoteString(literalValue.ToString());
542+
if (literalType == typeof(Guid))
543+
return string.Format("CAST ({0} AS UNIQUEIDENTIFIER)", QuoteString(literalValue.ToString()));
544544
if (literalType==typeof (Int64))
545545
return String.Format("CAST({0} as BIGINT)", literalValue);
546546
return base.Translate(context, literalValue);

Orm/Xtensive.Orm.SqlServer/Sql.Drivers.SqlServer/v09/TypeMapper.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ internal class TypeMapper : Sql.TypeMapper
2222

2323
private ValueRange<DateTime> dateTimeRange;
2424

25+
public override bool IsParameterCastRequired(Type type)
26+
{
27+
switch (Type.GetTypeCode(type)) {
28+
case TypeCode.Byte:
29+
case TypeCode.SByte:
30+
case TypeCode.Int16:
31+
case TypeCode.UInt16:
32+
return true;
33+
}
34+
if (type == typeof(Guid)) {
35+
return true;
36+
}
37+
38+
return base.IsParameterCastRequired(type);
39+
}
40+
2541
public override void BindSByte(DbParameter parameter, object value)
2642
{
2743
parameter.DbType = DbType.Int16;

Orm/Xtensive.Orm.Tests/Issues/IssueJira0421_DateTimeAddXxx.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,21 @@ public void AddSecondsTest()
115115
[Test]
116116
public void AddMillisecondsTest()
117117
{
118-
CheckNotMySql55();
118+
CheckNotMySql55NorSqlServer2005();
119119
RunAllTestsDouble(value => e => e.Today.AddMilliseconds(value) == today.AddMilliseconds(value));
120120
}
121121

122-
private void CheckNotMySql55()
122+
private void CheckNotMySql55NorSqlServer2005()
123123
{
124-
if (StorageProviderInfo.Instance.CheckProviderIs(StorageProvider.MySql)
125-
&& StorageProviderInfo.Instance.CheckProviderVersionIsAtMost(StorageProviderVersion.MySql56)) {
124+
var storageProviderInfo = StorageProviderInfo.Instance;
125+
if (storageProviderInfo.CheckProviderIs(StorageProvider.MySql)
126+
&& storageProviderInfo.CheckProviderVersionIsAtMost(StorageProviderVersion.MySql56)) {
126127
throw new IgnoreException("Test requires MySQL version greater than 5.5");
127128
}
129+
if (storageProviderInfo.CheckProviderIs(StorageProvider.SqlServer)
130+
&& storageProviderInfo.CheckProviderVersionIsAtMost(StorageProviderVersion.SqlServer2005)) {
131+
throw new IgnoreException("MS SQL Server 2005rounds miliseconds of DateTime so test is inconsistent.");
132+
}
128133
}
129134
}
130135
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Copyright (C) 2024 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
4+
5+
using System;
6+
using System.Linq;
7+
using System.Linq.Expressions;
8+
using NUnit.Framework;
9+
using Xtensive.Orm.Configuration;
10+
using Xtensive.Orm.Tests.Issues.IssueJira0803_ReuseOfJoiningExpressionCausesWrongTranslationModel;
11+
12+
namespace Xtensive.Orm.Tests.Issues.IssueJira0803_ReuseOfJoiningExpressionCausesWrongTranslationModel
13+
{
14+
[HierarchyRoot]
15+
public class TestEntity : Entity
16+
{
17+
[Field, Key]
18+
public int Id { get; private set; }
19+
20+
[Field(Nullable = false)]
21+
public string Name { get; set; }
22+
23+
[Field]
24+
public string Description { get; set; }
25+
26+
[Field]
27+
public string Text { get; set; }
28+
29+
public TestEntity(Session session)
30+
: base(session)
31+
{
32+
}
33+
}
34+
}
35+
36+
namespace Xtensive.Orm.Tests.Issues
37+
{
38+
public sealed class IssueJira0803_ReuseOfJoiningExpressionCausesWrongTranslation : AutoBuildTest
39+
{
40+
protected override DomainConfiguration BuildConfiguration()
41+
{
42+
var configuration = base.BuildConfiguration();
43+
configuration.UpgradeMode = DomainUpgradeMode.Recreate;
44+
configuration.Types.Register(typeof(TestEntity));
45+
return configuration;
46+
}
47+
48+
protected override void PopulateData()
49+
{
50+
using (var session = Domain.OpenSession())
51+
using (var tx = session.OpenTransaction()) {
52+
_ = new TestEntity(session) { Name = "1", Description = "test", Text = "text" };
53+
_ = new TestEntity(session) { Name = "1", Description = "test", Text = "text" };
54+
_ = new TestEntity(session) { Name = "1", Description = null, Text = "text" };
55+
56+
tx.Complete();
57+
}
58+
}
59+
60+
[Test]
61+
public void LeftJoinOneVariableUsage()
62+
{
63+
Expression<Func<TestEntity, int>> key = it => it.Id;
64+
65+
using (var session = Domain.OpenSession())
66+
using (var tx = session.OpenTransaction()) {
67+
68+
var leftJoinWithExpression = session.Query.All<TestEntity>()
69+
.LeftJoin(session.Query.All<TestEntity>().Where(it => it.Description == null),
70+
o => o.Id,
71+
key,
72+
(o, i) => o)
73+
.Where(it => it.Text != null)
74+
.Select(it => it.Id)
75+
.Distinct()
76+
.ToList();
77+
78+
Assert.AreEqual(3, leftJoinWithExpression.Count);
79+
80+
leftJoinWithExpression = session.Query.All<TestEntity>()
81+
.LeftJoin(session.Query.All<TestEntity>().Where(it => it.Description == null),
82+
key,
83+
i => i.Id,
84+
(o, i) => o)
85+
.Where(it => it.Text != null)
86+
.Select(it => it.Id)
87+
.Distinct()
88+
.ToList();
89+
90+
Assert.AreEqual(3, leftJoinWithExpression.Count);
91+
}
92+
}
93+
94+
[Test]
95+
public void LeftJoinTwoVariableUsage()
96+
{
97+
Expression<Func<TestEntity, int>> key = it => it.Id;
98+
99+
using (var session = Domain.OpenSession())
100+
using (var tx = session.OpenTransaction()) {
101+
102+
var ex = Assert.Throws<QueryTranslationException>(() =>
103+
_ = session.Query.All<TestEntity>()
104+
.LeftJoin(session.Query.All<TestEntity>().Where(it => it.Description == null),
105+
key,
106+
key,
107+
(o, i) => o)
108+
.Where(it => it.Text != null)
109+
.Select(it => it.Id)
110+
.Distinct()
111+
.ToList());
112+
113+
Assert.That(ex.InnerException, Is.InstanceOf<NotSupportedException>());
114+
}
115+
}
116+
117+
[Test]
118+
public void InnerJoinOneVariableUsage()
119+
{
120+
Expression<Func<TestEntity, int>> key = it => it.Id;
121+
122+
using (var session = Domain.OpenSession())
123+
using (var tx = session.OpenTransaction()) {
124+
125+
var leftJoinWithExpression = session.Query.All<TestEntity>()
126+
.Join(session.Query.All<TestEntity>().Where(it => it.Description == null),
127+
o => o.Id,
128+
key,
129+
(o, i) => o)
130+
.Where(it => it.Text != null)
131+
.Select(it => it.Id)
132+
.Distinct()
133+
.ToList();
134+
135+
Assert.AreEqual(1, leftJoinWithExpression.Count);
136+
137+
leftJoinWithExpression = session.Query.All<TestEntity>()
138+
.Join(session.Query.All<TestEntity>().Where(it => it.Description == null),
139+
key,
140+
i => i.Id,
141+
(o, i) => o)
142+
.Where(it => it.Text != null)
143+
.Select(it => it.Id)
144+
.Distinct()
145+
.ToList();
146+
147+
Assert.AreEqual(1, leftJoinWithExpression.Count);
148+
}
149+
}
150+
151+
[Test]
152+
public void InnerJoinTwoVariableUsage()
153+
{
154+
Expression<Func<TestEntity, int>> key = it => it.Id;
155+
156+
using (var session = Domain.OpenSession())
157+
using (var tx = session.OpenTransaction()) {
158+
159+
var ex = Assert.Throws<QueryTranslationException>(() =>
160+
_ = session.Query.All<TestEntity>()
161+
.Join(session.Query.All<TestEntity>().Where(it => it.Description == null),
162+
key,
163+
key,
164+
(o, i) => o)
165+
.Where(it => it.Text != null)
166+
.Select(it => it.Id)
167+
.Distinct()
168+
.ToList());
169+
170+
Assert.That(ex.InnerException, Is.InstanceOf<NotSupportedException>());
171+
}
172+
}
173+
}
174+
}

0 commit comments

Comments
 (0)