示例#1
0
        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));
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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));
        }
示例#4
0
        /// <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));
 }
示例#9
0
        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);
        }
示例#10
0
        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);
        }
示例#11
0
        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);
        }
示例#12
0
        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);
        }
示例#15
0
        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));
        }
示例#16
0
        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);
        }
示例#18
0
        // 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;
        }
示例#19
0
 protected override Provider VisitContainsTable(ContainsTableProvider provider)
 {
     sortOrder = new DirectionCollection <int>();
     return(provider);
 }
示例#20
0
 protected override Provider VisitFreeText(FreeTextProvider provider)
 {
     sortOrder = new DirectionCollection <int>();
     return(provider);
 }
示例#21
0
 protected override Provider VisitStore(StoreProvider provider)
 {
     sortOrder = new DirectionCollection <int>();
     return(provider);
 }
示例#22
0
 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>());
 }
示例#23
0
        // 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();
        }
示例#25
0
 public static CompilableProvider OrderBy(this CompilableProvider source, DirectionCollection <int> columnIndexes)
 {
     return(new SortProvider(source, columnIndexes));
 }