Skip to content

Commit c19f314

Browse files
authored
Optimize BuildTypedQuery() (#432)
* Optimize `BuildTypedQuery()` * fix inserting to the end
1 parent 4f83848 commit c19f314

File tree

4 files changed

+31
-46
lines changed

4 files changed

+31
-46
lines changed

Orm/Xtensive.Orm/Orm/Providers/SqlCompiler.Index.cs

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@
44
// Created by: Denis Krjuchkov
55
// Created: 2009.11.13
66

7-
using System;
8-
using System.Collections.Concurrent;
9-
using System.Collections.Generic;
10-
using System.Linq;
11-
using System.Linq.Expressions;
12-
using Xtensive.Core;
13-
using Xtensive.Linq;
14-
using Xtensive.Orm.Internals;
157
using Xtensive.Orm.Model;
168
using Xtensive.Orm.Rse.Providers;
179
using Xtensive.Reflection;
@@ -24,22 +16,7 @@ namespace Xtensive.Orm.Providers
2416
{
2517
public partial class SqlCompiler
2618
{
27-
protected readonly struct QueryAndBindings
28-
{
29-
public SqlSelect Query { get; }
30-
public List<QueryParameterBinding> Bindings { get; }
31-
32-
public QueryAndBindings(SqlSelect initialQuery)
33-
{
34-
Query = initialQuery;
35-
Bindings = new List<QueryParameterBinding>();
36-
}
37-
public QueryAndBindings(SqlSelect initialQuery, List<QueryParameterBinding> bindings)
38-
{
39-
Query = initialQuery;
40-
Bindings = bindings;
41-
}
42-
}
19+
protected record struct QueryAndBindings(SqlSelect Query, List<QueryParameterBinding> Bindings);
4320

4421
private TypeMapping int32TypeMapping;
4522

@@ -54,17 +31,13 @@ internal protected override SqlProvider VisitIndex(IndexProvider provider)
5431
protected QueryAndBindings BuildProviderQuery(IndexInfo index)
5532
{
5633
if (index.IsVirtual) {
57-
if ((index.Attributes & IndexAttributes.Union) > 0)
58-
return BuildUnionQuery(index);
59-
if ((index.Attributes & IndexAttributes.Join) > 0)
60-
return BuildJoinQuery(index);
61-
if ((index.Attributes & IndexAttributes.Filtered) > 0)
62-
return BuildFilteredQuery(index);
63-
if ((index.Attributes & IndexAttributes.View) > 0)
64-
return BuildViewQuery(index);
65-
if ((index.Attributes & IndexAttributes.Typed) > 0)
66-
return BuildTypedQuery(index);
67-
throw new NotSupportedException(String.Format(Strings.ExUnsupportedIndex, index.Name, index.Attributes));
34+
var attrs = index.Attributes;
35+
return (attrs & IndexAttributes.Union) > 0 ? BuildUnionQuery(index)
36+
: (attrs & IndexAttributes.Join) > 0 ? BuildJoinQuery(index)
37+
: (attrs & IndexAttributes.Filtered) > 0 ? BuildFilteredQuery(index)
38+
: (attrs & IndexAttributes.View) > 0 ? BuildViewQuery(index)
39+
: (attrs & IndexAttributes.Typed) > 0 ? BuildTypedQuery(index)
40+
: throw new NotSupportedException(String.Format(Strings.ExUnsupportedIndex, index.Name, index.Attributes));
6841
}
6942
return BuildTableQuery(index);
7043
}
@@ -98,7 +71,7 @@ private QueryAndBindings BuildTableQuery(IndexInfo index)
9871
queryColumns.Add(tableRef[lookup[c.Field]]);
9972
}
10073
}
101-
return new QueryAndBindings(query);
74+
return new QueryAndBindings(query, []);
10275
}
10376

10477
private QueryAndBindings BuildUnionQuery(IndexInfo index)
@@ -285,10 +258,9 @@ private QueryAndBindings BuildTypedQuery(IndexInfo index)
285258
var baseQueryAndBindings = BuildProviderQuery(underlyingIndex);
286259
var baseQuery = baseQueryAndBindings.Query;
287260
var bindings = baseQueryAndBindings.Bindings;
288-
var query = SqlDml.Select(baseQuery.From);
261+
var query = SqlDml.Select(baseQuery.From, baseQuery.Columns.Count + 1);
289262
query.Where = baseQuery.Where;
290263

291-
var baseColumns = baseQuery.Columns.ToList();
292264
var typeIdColumnIndex = index.Columns
293265
.Select((c, i) => (c.Field, i))
294266
.Single(p => p.Field.IsTypeId && p.Field.IsSystem).i;
@@ -332,8 +304,19 @@ private QueryAndBindings BuildTypedQuery(IndexInfo index)
332304
}
333305

334306
var typeIdColumnRef = SqlDml.ColumnRef(typeIdColumn, WellKnown.TypeIdFieldName);
335-
baseColumns.Insert(typeIdColumnIndex, typeIdColumnRef);
336-
query.Columns.AddRange(baseColumns);
307+
var queryColumns = query.Columns;
308+
bool inserted = false;
309+
int i = 0;
310+
foreach (var column in baseQuery.Columns) {
311+
if (i++ == typeIdColumnIndex) {
312+
queryColumns.Add(typeIdColumnRef);
313+
inserted = true;
314+
}
315+
queryColumns.Add(column);
316+
}
317+
if (!inserted) {
318+
queryColumns.Add(typeIdColumnRef);
319+
}
337320

338321
return new QueryAndBindings(query, bindings);
339322
}

Orm/Xtensive.Orm/Sql/Dml/Collections/SqlColumnCollection.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public void Insert(int index, SqlExpression expression, string alias) =>
6565
/// Initializes new instance of this type.
6666
/// </summary>
6767
public SqlColumnCollection() { }
68+
public SqlColumnCollection(int capacity) : base(capacity) { }
6869

6970
/// <summary>
7071
/// Initializes new instance of this type.

Orm/Xtensive.Orm/Sql/Dml/Statements/SqlSelect.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class SqlSelect
1717
ISqlQueryExpression
1818
{
1919
private readonly SqlUserColumn asterisk = SqlDml.Column(SqlDml.Asterisk);
20-
private readonly SqlColumnCollection columns = new();
20+
private readonly SqlColumnCollection columns;
2121
private SqlLockType _lock;
2222
private SqlColumnCollection groupBy;
2323
private SqlExpression having;
@@ -256,15 +256,16 @@ IEnumerator IEnumerable.GetEnumerator()
256256

257257
// Constructors
258258

259-
internal SqlSelect(SqlTable from)
260-
: this()
259+
internal SqlSelect(SqlTable from, int? capacity = null)
260+
: this(capacity ?? from.Columns.Count)
261261
{
262262
From = from;
263263
}
264264

265-
internal SqlSelect()
265+
internal SqlSelect(int? capacity = null)
266266
: base(SqlNodeType.Select)
267267
{
268+
columns = capacity.HasValue ? new(capacity.Value) : new();
268269
}
269270
}
270271
}

Orm/Xtensive.Orm/Sql/SqlDml.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,10 +1691,10 @@ public static SqlSelect Select(SqlExpression expression)
16911691
return result;
16921692
}
16931693

1694-
public static SqlSelect Select(SqlTable table)
1694+
public static SqlSelect Select(SqlTable table, int? capacity = null)
16951695
{
16961696
ArgumentNullException.ThrowIfNull(table);
1697-
return new SqlSelect(table);
1697+
return new SqlSelect(table, capacity);
16981698
}
16991699

17001700
#endregion

0 commit comments

Comments
 (0)