private static RecordSetHeader CreateHeader(IndexInfo indexInfo) { TupleDescriptor resultTupleDescriptor = TupleDescriptor.Create( indexInfo.Columns.Select(columnInfo => columnInfo.ValueType)); var keyOrder = new List <KeyValuePair <int, Direction> >( indexInfo.KeyColumns.Select((p, i) => new KeyValuePair <int, Direction>(i, p.Value))); if (!indexInfo.IsPrimary) { var pkKeys = indexInfo.ReflectedType.Indexes.PrimaryIndex.KeyColumns; keyOrder.AddRange( indexInfo.ValueColumns .Select((c, i) => new Pair <Orm.Model.ColumnInfo, int>(c, i + indexInfo.KeyColumns.Count)) .Where(pair => pair.First.IsPrimaryKey) .Select(pair => new KeyValuePair <int, Direction>(pair.Second, pkKeys[pair.First]))); } var order = new DirectionCollection <int>(keyOrder); var keyDescriptor = TupleDescriptor.Create(indexInfo.KeyColumns.Select(columnInfo => columnInfo.Key.ValueType)); var resultColumns = indexInfo.Columns.Select((c, i) => (Column) new MappedColumn(c, i, c.ValueType)); var resultGroups = new[] { indexInfo.Group }; return(new RecordSetHeader( resultTupleDescriptor, resultColumns, resultGroups, keyDescriptor, order)); }
protected override Provider VisitAggregate(AggregateProvider provider) { var result = provider; var source = VisitCompilable(provider.Source); if (source != provider.Source) { var acds = provider.AggregateColumns .Select(ac => new AggregateColumnDescriptor(ac.Name, ac.SourceIndex, ac.AggregateType)); result = new AggregateProvider(source, provider.GroupColumnIndexes, acds.ToArray()); } if (sortOrder.Count > 0) { var selectOrdering = new DirectionCollection <int>(); foreach (var pair in sortOrder) { var columnIndex = result.GroupColumnIndexes.IndexOf(pair.Key); if (columnIndex < 0) { if (selectOrdering.Count > 0) { selectOrdering.Clear(); } break; } selectOrdering.Add(columnIndex, pair.Value); } sortOrder = selectOrdering; } return(result); }
/// <summary> /// Selects the specified columns from the header. /// </summary> /// <param name="selectedColumns">The indexes of columns to select.</param> /// <returns>A new header containing only specified columns.</returns> public RecordSetHeader Select(IEnumerable <int> selectedColumns) { var columns = new List <int>(selectedColumns); var columnsMap = new List <int>(Enumerable.Repeat(-1, Columns.Count)); for (int newIndex = 0; newIndex < columns.Count; newIndex++) { var oldIndex = columns[newIndex]; columnsMap[oldIndex] = newIndex; } var resultTupleDescriptor = Xtensive.Tuples.TupleDescriptor.Create(columns.Select(i => TupleDescriptor[i])); var resultOrder = new DirectionCollection <int>( Order .Select(o => new KeyValuePair <int, Direction>(columnsMap[o.Key], o.Value)) .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.Columns .Select(c => columnsMap[c]) .Where(c => c >= 0))); return(new RecordSetHeader( resultTupleDescriptor, resultColumns, resultGroups, null, resultOrder)); }
/// <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="groups">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, IEnumerable <ColumnGroup> groups, TupleDescriptor orderKeyDescriptor, DirectionCollection <int> order) { ArgumentValidator.EnsureArgumentNotNull(tupleDescriptor, "tupleDescriptor"); ArgumentValidator.EnsureArgumentNotNull(columns, "columns"); TupleDescriptor = tupleDescriptor; Columns = new ColumnCollection(columns); if (tupleDescriptor.Count != Columns.Count) { throw new ArgumentOutOfRangeException("columns.Count"); } ColumnGroups = groups == null ? ColumnGroupCollection.Empty : new ColumnGroupCollection(groups); orderTupleDescriptor = orderKeyDescriptor ?? TupleDescriptor.Empty; Order = order ?? new DirectionCollection <int>(); Order.Lock(true); }
protected override Provider VisitSort(SortProvider provider) { mappings[provider.Source] = Merge(mappings[provider], provider.Order.Keys); var source = VisitCompilable(provider.Source); var sourceMap = mappings[provider.Source]; var order = new DirectionCollection <int>(); foreach (var pair in provider.Order) { var index = sourceMap.IndexOf(pair.Key); if (index < 0) { throw Exceptions.InternalError(Strings.ExOrderKeyNotFoundInMapping, OrmLog.Instance); } order.Add(index, pair.Value); } mappings[provider] = sourceMap; if (source == provider.Source) { return(provider); } return(new SortProvider(source, order)); }
/// <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="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, IEnumerable <ColumnGroup> columnGroups, TupleDescriptor orderKeyDescriptor, 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) : new ColumnCollection(columns); if (tupleDescriptor.Count != Columns.Count) { throw new ArgumentOutOfRangeException("columns.Count"); } ColumnGroups = columnGroups == null ? ColumnGroupCollection.Empty // Unsafe perf. optimization: if you pass a list, it should be immutable! : (columnGroups is List <ColumnGroup> columnGroupList ? new ColumnGroupCollection(columnGroupList) : new ColumnGroupCollection(columnGroups)); orderTupleDescriptor = orderKeyDescriptor ?? TupleDescriptor.Empty; Order = order ?? new DirectionCollection <int>(); Order.Lock(true); }
/// <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="orderKeyDescriptor">Descriptor of ordered columns.</param> /// <param name="order">Result sort order.</param> public RecordSetHeader( TupleDescriptor tupleDescriptor, IEnumerable <Column> columns, TupleDescriptor orderKeyDescriptor, DirectionCollection <int> order) : this(tupleDescriptor, columns, null, orderKeyDescriptor, order) { }
/// <summary> /// Sorts the header in the specified order. /// </summary> /// <param name="sortOrder">Order to sort this header in.</param> /// <returns>A new sorted header.</returns> public RecordSetHeader Sort(DirectionCollection <int> sortOrder) { return(new RecordSetHeader( TupleDescriptor, Columns, ColumnGroups, TupleDescriptor, sortOrder)); }
protected override Provider VisitSort(SortProvider provider) { var source = VisitCompilable(provider.Source); sortOrder = provider.Order; if (consumerDescriptor.IsOrderSensitive) { return(new SortProvider(source, provider.Order)); } return(source); }
protected override Provider VisitPredicateJoin(PredicateJoinProvider provider) { var left = VisitCompilable(provider.Left); var leftOrder = sortOrder; var right = VisitCompilable(provider.Right); var rightOrder = sortOrder; var result = left == provider.Left && right == provider.Right ? provider : new PredicateJoinProvider(left, right, provider.Predicate, provider.JoinType); sortOrder = ComputeBinaryOrder(provider, leftOrder, rightOrder); return(result); }
protected override Provider VisitJoin(JoinProvider provider) { var left = VisitCompilable(provider.Left); var leftOrder = sortOrder; var right = VisitCompilable(provider.Right); var rightOrder = sortOrder; var result = left == provider.Left && right == provider.Right ? provider : new JoinProvider(left, right, provider.JoinType, provider.EqualIndexes); sortOrder = ComputeBinaryOrder(provider, leftOrder, rightOrder); return(result); }
protected override Provider VisitApply(ApplyProvider provider) { var left = VisitCompilable(provider.Left); var leftOrder = sortOrder; var right = VisitCompilable(provider.Right); var rightOrder = sortOrder; var result = left == provider.Left && right == provider.Right ? provider : new ApplyProvider(provider.ApplyParameter, left, right, provider.IsInlined, provider.SequenceType, provider.ApplyType); sortOrder = ComputeBinaryOrder(provider, leftOrder, rightOrder); return(result); }
public void Test() { DirectionCollection <string> collection = new DirectionCollection <string>(); collection["a"] = Direction.Negative; collection["b"] = Direction.Negative; collection["c"] = Direction.Positive; collection["d"] = Direction.Positive; collection["e"] = Direction.Negative; Assert.AreEqual(Direction.Negative, collection["a"]); Assert.AreEqual(Direction.Negative, collection["b"]); Assert.AreEqual(Direction.Positive, collection["c"]); Assert.AreEqual(Direction.Positive, collection["d"]); Assert.AreEqual(Direction.Negative, collection["e"]); }
public bool Extract(Expression expression) { var result = new Stack <Pair <LambdaExpression, Direction> >(); while (true) { if (expression.NodeType == ExpressionType.Call) { var call = (MethodCallExpression)expression; var method = QueryableVisitor.GetQueryableMethod(call); if (method != null && IsSort(method.Value)) { var source = call.Arguments[0]; var projection = call.Arguments[1].StripQuotes(); var direction = GetDirection(method.Value); result.Push(new Pair <LambdaExpression, Direction>(projection, direction)); expression = source; if (IsThenBy(method.Value)) { continue; } } } break; } if (result.Count == 0) { BaseExpression = null; SortExpressions = null; return(false); } BaseExpression = expression; SortExpressions = new DirectionCollection <LambdaExpression>(); foreach (var item in result) { SortExpressions.Add(item.First, item.Second); } return(true); }
protected override SqlProvider VisitRowNumber(RowNumberProvider provider) { var directionCollection = provider.Header.Order; if (directionCollection.Count == 0) { directionCollection = new DirectionCollection <int>(1); } var source = Compile(provider.Source); var query = ExtractSqlSelect(provider, source); var rowNumber = SqlDml.RowNumber(); query.Columns.Add(rowNumber, provider.Header.Columns.Last().Name); var columns = ExtractColumnExpressions(query); foreach (var order in directionCollection) { rowNumber.OrderBy.Add(columns[order.Key], order.Value == Direction.Positive); } return(CreateProvider(query, provider, source)); }
private CompilableProvider CorrectOrder(CompilableProvider visited) { var result = visited; if (sortOrder.Count > 0) { if (descriptor.IsSorter) { return(result); } if (descriptor.BreaksOrder) { sortOrder = new DirectionCollection <int>(); return(result); } if (consumerDescriptor.IsOrderSensitive && !descriptor.IsOrderSensitive) { result = InsertSortProvider(visited); } } return(result); }
protected override Provider VisitSelect(SelectProvider provider) { var result = provider; var source = VisitCompilable(provider.Source); if (source != provider.Source) { result = new SelectProvider(source, provider.ColumnIndexes); } if (sortOrder.Count > 0) { var selectOrdering = new DirectionCollection <int>(); var columnIndexes = result.ColumnIndexes; foreach (var pair in sortOrder) { var columnIndex = columnIndexes.IndexOf(pair.Key); if (columnIndex < 0) { if (selectOrdering.Count > 0) { selectOrdering.Clear(); } break; } selectOrdering.Add(columnIndex, pair.Value); } sortOrder = selectOrdering; } if (sortOrder.Count > 0 && provider.Header.Order.Count == 0 && !consumerDescriptor.BreaksOrder && !consumerDescriptor.PreservesOrder) { throw new InvalidOperationException(Strings.ExSelectProviderRemovesColumnsUsedForOrdering); } return(result); }
// Constructors /// <summary> /// Initializes a new instance of this class. /// </summary> /// <param name="providerType">Provider type.</param> /// <param name="source">The <see cref="UnaryProvider.Source"/> property value.</param> /// <param name="order">The <see cref="Order"/> property value.</param> protected OrderProviderBase(ProviderType providerType, CompilableProvider source, DirectionCollection <int> order) : base(providerType, source) { Order = order; }
protected override Provider VisitContainsTable(ContainsTableProvider provider) { sortOrder = new DirectionCollection <int>(); return(provider); }
protected override Provider VisitFreeText(FreeTextProvider provider) { sortOrder = new DirectionCollection <int>(); return(provider); }
protected override Provider VisitStore(StoreProvider provider) { sortOrder = new DirectionCollection <int>(); return(provider); }
private static DirectionCollection <int> ComputeBinaryOrder(BinaryProvider provider, DirectionCollection <int> leftOrder, DirectionCollection <int> rightOrder) { if (leftOrder.Count > 0) { return(new DirectionCollection <int>( leftOrder.Concat( rightOrder.Select(p => new KeyValuePair <int, Direction>(p.Key + provider.Left.Header.Length, p.Value))))); } return(new DirectionCollection <int>()); }
// Constructors private OrderingRewriter(Func <CompilableProvider, ProviderOrderingDescriptor> orderingDescriptorResolver) { ArgumentValidator.EnsureArgumentNotNull(orderingDescriptorResolver, "orderingDescriptorResolver"); descriptorResolver = orderingDescriptorResolver; sortOrder = new DirectionCollection <int>(); }
// Constructors /// <summary> /// Initializes a new instance of this class. /// </summary> /// <param name="source">The <see cref="UnaryProvider.Source"/> property value.</param> /// <param name="order">The <see cref="OrderProviderBase.Order"/> property value.</param> public SortProvider(CompilableProvider source, DirectionCollection <int> order) : base(ProviderType.Sort, source, order) { Initialize(); }
public static CompilableProvider OrderBy(this CompilableProvider source, DirectionCollection <int> columnIndexes) { return(new SortProvider(source, columnIndexes)); }