Skip to content
18 changes: 9 additions & 9 deletions Orm/Xtensive.Orm/Orm/Model/ColumnGroup.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (C) 2003-2010 Xtensive LLC.
// All rights reserved.
// For conditions of distribution and use, see license.
// Copyright (C) 2008-2021 Xtensive LLC.
// This code is distributed under MIT license terms.
// See the License.txt file in the project root for more information.
// Created by: Alexey Kochetov
// Created: 2008.08.01

Expand Down Expand Up @@ -28,12 +28,12 @@ public sealed class ColumnGroup
/// <summary>
/// Gets the indexes of key columns.
/// </summary>
public ReadOnlyList<int> Keys { get; private set; }
public IReadOnlyList<int> Keys { get; private set; }

/// <summary>
/// Gets the indexes of all columns.
/// </summary>
public ReadOnlyList<int> Columns { get; private set; }
public IReadOnlyList<int> Columns { get; private set; }


// Constructors
Expand All @@ -55,11 +55,11 @@ public ColumnGroup(TypeInfoRef type, IEnumerable<int> keys, IEnumerable<int> col
/// <param name="type">The type.</param>
/// <param name="keys">The keys.</param>
/// <param name="columns">The columns.</param>
public ColumnGroup(TypeInfoRef type, IList<int> keys, IList<int> columns)
public ColumnGroup(TypeInfoRef type, IReadOnlyList<int> keys, IReadOnlyList<int> columns)
{
TypeInfoRef = type;
Keys = new ReadOnlyList<int>(keys);
Columns = new ReadOnlyList<int>(columns);
Keys = keys;
Columns = columns;
}
}
}
}
26 changes: 15 additions & 11 deletions Orm/Xtensive.Orm/Orm/Providers/SqlCompiler.Index.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (C) 2009-2010 Xtensive LLC.
// This code is distributed under MIT license terms.
// See the License.txt file in the project root for more information.
// Copyright (C) 2009-2021 Xtensive LLC.
// All rights reserved.
// For conditions of distribution and use, see license.
// Created by: Denis Krjuchkov
// Created: 2009.11.13

Expand All @@ -15,7 +15,7 @@

namespace Xtensive.Orm.Providers
{
partial class SqlCompiler
partial class SqlCompiler
{
protected override SqlProvider VisitFreeText(FreeTextProvider provider)
{
Expand Down Expand Up @@ -65,18 +65,22 @@ private SqlSelect BuildTableQuery(IndexInfo index)
atRootPolicy = true;
}

SqlSelect query;
var indexColumns = index.Columns;
var tableRef = SqlDml.TableRef(table);
var query = SqlDml.Select(tableRef);
var queryColumns = query.Columns;
queryColumns.Capacity = queryColumns.Count + indexColumns.Count;
if (!atRootPolicy) {
var tableRef = SqlDml.TableRef(table);
query = SqlDml.Select(tableRef);
query.Columns.AddRange(index.Columns.Select(c => tableRef[c.Name]));
foreach (var c in indexColumns) {
queryColumns.Add(tableRef[c.Name]);
}
}
else {
var root = index.ReflectedType.GetRoot().AffectedIndexes.First(i => i.IsPrimary);
var lookup = root.Columns.ToDictionary(c => c.Field, c => c.Name);
var tableRef = SqlDml.TableRef(table);
query = SqlDml.Select(tableRef);
query.Columns.AddRange(index.Columns.Select(c => tableRef[lookup[c.Field]]));
foreach (var c in indexColumns) {
queryColumns.Add(tableRef[lookup[c.Field]]);
}
}
return query;
}
Expand Down
22 changes: 8 additions & 14 deletions Orm/Xtensive.Orm/Orm/Rse/ColumnCollection.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (C) 2003-2010 Xtensive LLC.
// All rights reserved.
// For conditions of distribution and use, see license.
// Copyright (C) 2007-2021 Xtensive LLC.
// This code is distributed under MIT license terms.
// See the License.txt file in the project root for more information.
// Created by: Alexey Kochetov
// Created: 2007.09.24

Expand Down Expand Up @@ -37,12 +37,6 @@ public Column this[string fullName] {
}
}

private void BuildNameIndex()
{
for (var index = 0; index < Count; index++)
nameIndex.Add(this[index].Name, index);
}

/// <summary>
/// Joins this collection with specified the column collection.
/// </summary>
Expand All @@ -59,7 +53,7 @@ public ColumnCollection Join(IEnumerable<Column> joined)
/// <param name="alias">The alias to add.</param>
/// <returns>Aliased collection of columns.</returns>
public ColumnCollection Alias(string alias)
{
{
ArgumentValidator.EnsureArgumentNotNullOrEmpty(alias, "alias");
return new ColumnCollection(this.Select(column => column.Clone(alias + "." + column.Name)));
}
Expand All @@ -71,10 +65,8 @@ public ColumnCollection Alias(string alias)
/// </summary>
/// <param name="collection">Collection of items to add.</param>
public ColumnCollection(IEnumerable<Column> collection)
: base(collection.ToList())
: this(collection.ToList())
{
nameIndex = new Dictionary<string, int>(Count);
BuildNameIndex();
}

/// <summary>
Expand All @@ -85,7 +77,9 @@ public ColumnCollection(List<Column> collection)
: base(collection)
{
nameIndex = new Dictionary<string, int>(Count);
BuildNameIndex();
for (var index = 0; index < Count; index++) {
nameIndex.Add(this[index].Name, index);
}
}
}
}
114 changes: 61 additions & 53 deletions Orm/Xtensive.Orm/Orm/Rse/RecordSetHeader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (C) 2003-2010 Xtensive LLC.
// All rights reserved.
// For conditions of distribution and use, see license.
// Copyright (C) 2007-2021 Xtensive LLC.
// This code is distributed under MIT license terms.
// See the License.txt file in the project root for more information.
// Created by: Alexey Kochetov
// Created: 2007.09.13

Expand Down Expand Up @@ -55,7 +55,7 @@ public int Length {
public DirectionCollection<int> Order { get; private set; }

/// <summary>
/// Gets the tuple descriptor describing
/// Gets the tuple descriptor describing
/// a set of <see cref="Order"/> columns.
/// </summary>
public TupleDescriptor OrderTupleDescriptor {
Expand Down Expand Up @@ -111,10 +111,10 @@ public RecordSetHeader Add(IEnumerable<Column> columns)
var newTupleDescriptor = TupleDescriptor.Create(newFieldTypes);

return new RecordSetHeader(
newTupleDescriptor,
newColumns,
ColumnGroups,
OrderTupleDescriptor,
newTupleDescriptor,
newColumns,
ColumnGroups,
OrderTupleDescriptor,
Order);
}

Expand All @@ -126,29 +126,37 @@ public RecordSetHeader Add(IEnumerable<Column> columns)
public RecordSetHeader Join(RecordSetHeader joined)
{
var columnCount = Columns.Count;
var newColumns = new List<Column>(Columns);
newColumns.AddRange(
from c in joined.Columns
select c.Clone(columnCount + c.Index));
var newColumns = new List<Column>(columnCount + joined.Columns.Count);
newColumns.AddRange(Columns);
foreach (var c in joined.Columns) {
newColumns.Add(c.Clone(columnCount + c.Index));
}

var newFieldTypes = new Type[newColumns.Count];
for (var i = 0; i < newColumns.Count; i++)
newFieldTypes[i] = newColumns[i].Type;
var newTupleDescriptor = TupleDescriptor.Create(newFieldTypes);

var groups = new List<ColumnGroup>(ColumnGroups);
groups.AddRange(
joined.ColumnGroups
.Select(g => new ColumnGroup(
g.TypeInfoRef,
g.Keys.Select(i => columnCount + i),
g.Columns.Select(i => columnCount + i))));

var columnGroupCount = ColumnGroups.Count;
var groups = new List<ColumnGroup>(columnGroupCount + joined.ColumnGroups.Count);
groups.AddRange(ColumnGroups);
foreach (var g in joined.ColumnGroups) {
var keys = new List<int>(g.Keys.Count);
foreach (var i in g.Keys) {
keys.Add(columnCount + i);
}
var columns = new List<int>(g.Columns.Count);
foreach (var i in g.Columns) {
columns.Add(columnCount + i);
}
groups.Add(new ColumnGroup(g.TypeInfoRef, keys, columns));
}

return new RecordSetHeader(
newTupleDescriptor,
newColumns,
newTupleDescriptor,
newColumns,
groups,
OrderTupleDescriptor,
OrderTupleDescriptor,
Order);
}

Expand All @@ -171,25 +179,25 @@ public RecordSetHeader Select(IEnumerable<int> selectedColumns)
var resultOrder = new DirectionCollection<int>(
Order
.Select(o => new KeyValuePair<int, Direction>(columnsMap[o.Key], o.Value))
.TakeWhile(o => o.Key >= 0));
.TakeWhile(o => o.Key >= 0));

var resultColumns = columns.Select((oldIndex, newIndex) => Columns[oldIndex].Clone(newIndex));

var resultGroups = ColumnGroups
.Where(g => g.Keys.All(k => columnsMap[k]>=0))
.Select(g => new ColumnGroup(
g.TypeInfoRef,
g.Keys.Select(k => columnsMap[k]),
g.Keys.Select(k => columnsMap[k]),
g.Columns
.Select(c => columnsMap[c])
.Where(c => c >= 0)));

return new RecordSetHeader(
resultTupleDescriptor,
resultColumns,
resultGroups,
null,
resultOrder);
resultTupleDescriptor,
resultColumns,
resultGroups,
null,
resultOrder);
}

/// <summary>
Expand Down Expand Up @@ -242,34 +250,34 @@ private static RecordSetHeader CreateHeader(IndexInfo indexInfo)
.Select(columnInfo => columnInfo.Key.ValueType)
.ToArray(indexInfoKeyColumns.Count);
var keyDescriptor = TupleDescriptor.Create(keyFieldTypes);

var resultColumns = indexInfoColumns.Select((c,i) => (Column) new MappedColumn(c,i,c.ValueType));
var resultGroups = new[]{indexInfo.Group};

return new RecordSetHeader(
resultTupleDescriptor,
resultColumns,
resultGroups,
keyDescriptor,
resultTupleDescriptor,
resultColumns,
resultGroups,
keyDescriptor,
order);
}

/// <inheritdoc/>
public override string ToString()
{
return Columns.Select(c => c.ToString()).ToCommaDelimitedString();
return Columns.Select(c => c.ToString()).ToCommaDelimitedString();
}


// Constructors

/// <summary>
/// Initializes a new instance of this class.
/// </summary>
/// <param name="tupleDescriptor">Descriptor of the result item.</param>
/// <param name="columns">Result columns.</param>
/// <param name="columns">Result columns.</param>
public RecordSetHeader(
TupleDescriptor tupleDescriptor,
TupleDescriptor tupleDescriptor,
IEnumerable<Column> columns)
: this(tupleDescriptor, columns, null, null, null)
{
Expand All @@ -279,11 +287,11 @@ public RecordSetHeader(
/// Initializes a new instance of this class.
/// </summary>
/// <param name="tupleDescriptor">Descriptor of the result item.</param>
/// <param name="columns">Result columns.</param>
/// <param name="columns">Result columns.</param>
/// <param name="columnGroups">Column groups.</param>
public RecordSetHeader(
TupleDescriptor tupleDescriptor,
IEnumerable<Column> columns,
TupleDescriptor tupleDescriptor,
IEnumerable<Column> columns,
IEnumerable<ColumnGroup> columnGroups)
: this(tupleDescriptor, columns, columnGroups, null, null)
{
Expand All @@ -293,14 +301,14 @@ public RecordSetHeader(
/// Initializes a new instance of this class.
/// </summary>
/// <param name="tupleDescriptor">Descriptor of the result item.</param>
/// <param name="columns">Result columns.</param>
/// <param name="columns">Result columns.</param>
/// <param name="orderKeyDescriptor">Descriptor of ordered columns.</param>
/// <param name="order">Result sort order.</param>
public RecordSetHeader(
TupleDescriptor tupleDescriptor,
IEnumerable<Column> columns,
TupleDescriptor tupleDescriptor,
IEnumerable<Column> columns,
TupleDescriptor orderKeyDescriptor,
DirectionCollection<int> order)
DirectionCollection<int> order)
: this(tupleDescriptor, columns, null, orderKeyDescriptor, order)
{
}
Expand All @@ -309,25 +317,25 @@ public RecordSetHeader(
/// Initializes a new instance of this class.
/// </summary>
/// <param name="tupleDescriptor">Descriptor of the result item.</param>
/// <param name="columns">Result columns.</param>
/// <param name="columns">Result columns.</param>
/// <param name="columnGroups">Column groups.</param>
/// <param name="orderKeyDescriptor">Descriptor of ordered columns.</param>
/// <param name="order">Result sort order.</param>
/// <exception cref="ArgumentOutOfRangeException"><c>columns.Count</c> is out of range.</exception>
public RecordSetHeader(
TupleDescriptor tupleDescriptor,
IEnumerable<Column> columns,
TupleDescriptor tupleDescriptor,
IEnumerable<Column> columns,
IEnumerable<ColumnGroup> columnGroups,
TupleDescriptor orderKeyDescriptor,
DirectionCollection<int> order)
DirectionCollection<int> order)
{
ArgumentValidator.EnsureArgumentNotNull(tupleDescriptor, "tupleDescriptor");
ArgumentValidator.EnsureArgumentNotNull(columns, "columns");

TupleDescriptor = tupleDescriptor;
// Unsafe perf. optimization: if you pass a list, it should be immutable!
Columns = columns is List<Column> columnList
? new ColumnCollection(columnList)
Columns = columns is List<Column> columnList
? new ColumnCollection(columnList)
: new ColumnCollection(columns);
if (tupleDescriptor.Count!=Columns.Count)
throw new ArgumentOutOfRangeException("columns.Count");
Expand All @@ -336,7 +344,7 @@ public RecordSetHeader(
? ColumnGroupCollection.Empty
// Unsafe perf. optimization: if you pass a list, it should be immutable!
: (columnGroups is List<ColumnGroup> columnGroupList
? new ColumnGroupCollection(columnGroupList)
? new ColumnGroupCollection(columnGroupList)
: new ColumnGroupCollection(columnGroups));

orderTupleDescriptor = orderKeyDescriptor ?? TupleDescriptor.Empty;
Expand Down
Loading