public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateAsync(
            CosmosQueryContext queryContext,
            CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams,
            CosmosElement requestContinuationToken,
            CancellationToken cancellationToken)
        {
            Debug.Assert(
                initParams.PartitionedQueryExecutionInfo.QueryInfo.HasOrderBy,
                "OrderBy~Context must have order by query info.");

            if (queryContext == null)
            {
                throw new ArgumentNullException(nameof(queryContext));
            }

            cancellationToken.ThrowIfCancellationRequested();

            // TODO (brchon): For now we are not honoring non deterministic ORDER BY queries, since there is a bug in the continuation logic.
            // We can turn it back on once the bug is fixed.
            // This shouldn't hurt any query results.
            OrderByItemProducerTreeComparer        orderByItemProducerTreeComparer = new OrderByItemProducerTreeComparer(initParams.PartitionedQueryExecutionInfo.QueryInfo.OrderBy.ToArray());
            CosmosOrderByItemQueryExecutionContext context = new CosmosOrderByItemQueryExecutionContext(
                initPararms: queryContext,
                maxConcurrency: initParams.MaxConcurrency,
                maxItemCount: initParams.MaxItemCount,
                maxBufferedItemCount: initParams.MaxBufferedItemCount,
                consumeComparer: orderByItemProducerTreeComparer,
                testSettings: initParams.TestSettings);

            IReadOnlyList <string>    orderByExpressions = initParams.PartitionedQueryExecutionInfo.QueryInfo.OrderByExpressions;
            IReadOnlyList <SortOrder> sortOrders         = initParams.PartitionedQueryExecutionInfo.QueryInfo.OrderBy;

            if (orderByExpressions.Count != sortOrders.Count)
            {
                throw new ArgumentException("order by expressions count does not match sort order");
            }

            IReadOnlyList <OrderByColumn> columns = orderByExpressions
                                                    .Zip(sortOrders, (expression, order) => new OrderByColumn(expression, order))
                                                    .ToList();

            return((await context.TryInitializeAsync(
                        sqlQuerySpec: initParams.SqlQuerySpec,
                        requestContinuation: requestContinuationToken,
                        collectionRid: initParams.CollectionRid,
                        partitionKeyRanges: initParams.PartitionKeyRanges,
                        initialPageSize: initParams.InitialPageSize,
                        orderByColumns: columns,
                        cancellationToken: cancellationToken))
                   .Try <IDocumentQueryExecutionComponent>(() => context));
        }
Beispiel #2
0
 /// <summary>
 /// Initializes a new instance of the CosmosOrderByItemQueryExecutionContext class.
 /// </summary>
 /// <param name="initPararms">The params used to construct the base class.</param>
 /// For cross partition order by queries a query like "SELECT c.id, c.field_0 ORDER BY r.field_7 gets rewritten as:
 /// <![CDATA[
 /// SELECT r._rid, [{"item": r.field_7}] AS orderByItems, {"id": r.id, "field_0": r.field_0} AS payload
 /// FROM r
 /// WHERE({ document db - formattable order by query - filter})
 /// ORDER BY r.field_7]]>
 /// This is needed because we need to add additional filters to the query when we resume from a continuation,
 /// and it lets us easily parse out the _rid orderByItems, and payload without parsing the entire document (and having to remember the order by field).
 /// <param name="maxConcurrency">The max concurrency</param>
 /// <param name="maxBufferedItemCount">The max buffered item count</param>
 /// <param name="maxItemCount">Max item count</param>
 /// <param name="consumeComparer">Comparer used to internally compare documents from different sorted partitions.</param>
 /// <param name="testSettings">Test settings.</param>
 private CosmosOrderByItemQueryExecutionContext(
     CosmosQueryContext initPararms,
     int?maxConcurrency,
     int?maxItemCount,
     int?maxBufferedItemCount,
     OrderByItemProducerTreeComparer consumeComparer,
     TestInjections testSettings)
     : base(
         queryContext: initPararms,
         maxConcurrency: maxConcurrency,
         maxItemCount: maxItemCount,
         maxBufferedItemCount: maxBufferedItemCount,
         moveNextComparer: consumeComparer,
         fetchPrioirtyFunction: CosmosOrderByItemQueryExecutionContext.FetchPriorityFunction,
         equalityComparer: new OrderByEqualityComparer(consumeComparer),
         returnResultsInDeterministicOrder: true,
         testSettings: testSettings)
 {
 }