Skip to content

Commit 3364faf

Browse files
committed
No extra select wrapping because of TypeId calculated column
Queries of a lot of entities have type Id as constant value column included to sql query and this cause SELECT ... FROM (SELECT) queries where outer select just used all the fields from inner select. For some cases such wrapping was turned off.
1 parent 024206d commit 3364faf

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

Extensions/Xtensive.Orm.BulkOperations.Tests/Other.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,5 +242,34 @@ public void In()
242242
trx.Complete();
243243
}
244244
}
245+
246+
[Test]
247+
public void InWithCombinationWithFieldUsageinUpdate()
248+
{
249+
using (Session session = Domain.OpenSession())
250+
using (TransactionScope trx = session.OpenTransaction()) {
251+
var idsToUpdate = new[] { 99, 100, 102 };
252+
var prefix = "abc";
253+
254+
var bar1 = new Bar(session, 100) { Name = "test1", Count = 3 };
255+
var bar2 = new Bar(session, 101) { Name = "test2", Count = 4 };
256+
var bar3 = new Bar(session, 102) { Name = "test3", Count = 5 };
257+
session.SaveChanges();
258+
259+
var updatedCount = session.Query.All<Bar>()
260+
.Where(b => b.Id.In(IncludeAlgorithm.ComplexCondition, idsToUpdate))
261+
.Update(bar => new Bar(session) { Name = prefix + bar.Name });
262+
Assert.That(updatedCount, Is.EqualTo(2));
263+
264+
var all = session.Query.All<Bar>().Where(b=> b.Id == 100 || b.Id == 101 || b.Id == 102).ToList();
265+
var updatedEntities = all.Where(b => b.Id.In(idsToUpdate));
266+
Assert.That(updatedEntities.All(e => e.Name.StartsWith(prefix)), Is.True);
267+
268+
var leftEntities = all.Where(b => !b.Id.In(idsToUpdate));
269+
Assert.That(leftEntities.All(e => e.Name.StartsWith(prefix)), Is.False);
270+
271+
trx.Complete();
272+
}
273+
}
245274
}
246275
}

Orm/Xtensive.Orm/Orm/Providers/SqlCompiler.Helpers.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ private static bool IsColumnStub(SqlColumn column)
178178
return false;
179179
}
180180

181+
private static bool IsTypeIdColumn(SqlColumn column)
182+
{
183+
if (column is SqlUserColumn)
184+
return (StringComparer.InvariantCultureIgnoreCase.Compare(column.Name, "TypeId") == 0);
185+
var cRef = column as SqlColumnRef;
186+
if (!ReferenceEquals(null, cRef))
187+
return (StringComparer.InvariantCultureIgnoreCase.Compare(column.Name, "TypeId") == 0);
188+
return false;
189+
}
190+
181191
private static SqlColumnStub ExtractColumnStub(SqlColumn column)
182192
{
183193
var columnStub = column as SqlColumnStub;
@@ -211,6 +221,10 @@ private static bool ShouldUseQueryReference(CompilableProvider origin, SqlProvid
211221
.Where(i => i >= 0)
212222
.ToList();
213223
var containsCalculatedColumns = calculatedColumnIndexes.Count > 0;
224+
var typeIdIsOnlyCalculatedColumn = (calculatedColumnIndexes.Count == 1)
225+
? IsTypeIdColumn(sourceSelect.Columns[calculatedColumnIndexes[0]])
226+
: false;
227+
214228
var rowNumberIsUsed = calculatedColumnIndexes.Count > 0 && sourceSelect.Columns
215229
.Select((c, i) => new { c, i })
216230
.Any(a => calculatedColumnIndexes.Contains(a.i) && ExtractUserColumn(a.c).Expression is SqlRowNumber);
@@ -298,7 +312,7 @@ private static bool ShouldUseQueryReference(CompilableProvider origin, SqlProvid
298312
return orderingOverCalculatedColumn;
299313
}
300314

301-
return containsCalculatedColumns || distinctIsUsed || pagingIsUsed || groupByIsUsed;
315+
return (containsCalculatedColumns && !typeIdIsOnlyCalculatedColumn) || distinctIsUsed || pagingIsUsed || groupByIsUsed;
302316
}
303317

304318
private SqlExpression GetOrderByExpression(SqlExpression expression, SortProvider provider, int index)

0 commit comments

Comments
 (0)