public static async Task <IDocumentQueryExecutionContext> CreateDocumentQueryExecutionContextAsync( IDocumentQueryClient client, ResourceType resourceTypeEnum, Type resourceType, Expression expression, FeedOptions feedOptions, string resourceLink, bool isContinuationExpected, CancellationToken token, Guid correlatedActivityId) { ContainerProperties collection = null; if (resourceTypeEnum.IsCollectionChild()) { CollectionCache collectionCache = await client.GetCollectionCacheAsync(); using ( DocumentServiceRequest request = DocumentServiceRequest.Create( OperationType.Query, resourceTypeEnum, resourceLink, AuthorizationTokenType.Invalid)) //this request doesnt actually go to server { collection = await collectionCache.ResolveCollectionAsync(request, token); } if (feedOptions != null && feedOptions.PartitionKey != null && feedOptions.PartitionKey.Equals(Documents.PartitionKey.None)) { feedOptions.PartitionKey = Documents.PartitionKey.FromInternalKey(collection.GetNoneValue()); } } DocumentQueryExecutionContextBase.InitParams constructorParams = new DocumentQueryExecutionContextBase.InitParams( client, resourceTypeEnum, resourceType, expression, feedOptions, resourceLink, false, correlatedActivityId); // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop, so need to bypass in that case. // We are also now bypassing this for 32 bit host process running even on Windows as there are many 32 bit apps that will not work without this if (CustomTypeExtensions.ByPassQueryParsing()) { // We create a ProxyDocumentQueryExecutionContext that will be initialized with DefaultDocumentQueryExecutionContext // which will be used to send the query to Gateway and on getting 400(bad request) with 1004(cross partition query not servable), we initialize it with // PipelinedDocumentQueryExecutionContext by providing the partition query execution info that's needed(which we get from the exception returned from Gateway). ProxyDocumentQueryExecutionContext proxyQueryExecutionContext = ProxyDocumentQueryExecutionContext.Create( client, resourceTypeEnum, resourceType, expression, feedOptions, resourceLink, token, collection, isContinuationExpected, correlatedActivityId); return(proxyQueryExecutionContext); } DefaultDocumentQueryExecutionContext queryExecutionContext = await DefaultDocumentQueryExecutionContext.CreateAsync( constructorParams, isContinuationExpected, token); // If isContinuationExpected is false, we want to check if there are aggregates. if ( resourceTypeEnum.IsCollectionChild() && resourceTypeEnum.IsPartitioned() && (feedOptions.EnableCrossPartitionQuery || !isContinuationExpected)) { //todo:elasticcollections this may rely on information from collection cache which is outdated //if collection is deleted/created with same name. //need to make it not rely on information from collection cache. PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = await queryExecutionContext.GetPartitionedQueryExecutionInfoAsync( partitionKeyDefinition : collection.PartitionKey, requireFormattableOrderByQuery : true, isContinuationExpected : isContinuationExpected, allowNonValueAggregateQuery : true, hasLogicalPartitionKey : feedOptions.PartitionKey != null, cancellationToken : token); if (DocumentQueryExecutionContextFactory.ShouldCreateSpecializedDocumentQueryExecutionContext( resourceTypeEnum, feedOptions, partitionedQueryExecutionInfo, collection.PartitionKey, isContinuationExpected)) { List <PartitionKeyRange> targetRanges = await GetTargetPartitionKeyRangesAsync( queryExecutionContext, partitionedQueryExecutionInfo, collection, feedOptions); // Devnote this will get replace by the new v3 to v2 logic throw new NotSupportedException("v2 query excution context is currently not supported."); } } return(queryExecutionContext); }
public static async Task <IDocumentQueryExecutionContext> CreateDocumentQueryExecutionContextAsync( IDocumentQueryClient client, ResourceType resourceTypeEnum, Type resourceType, Expression expression, FeedOptions feedOptions, string resourceLink, bool isContinuationExpected, CancellationToken token, Guid correlatedActivityId) { DocumentQueryExecutionContextBase.InitParams constructorParams = new DocumentQueryExecutionContextBase.InitParams( client, resourceTypeEnum, resourceType, expression, feedOptions, resourceLink, false, correlatedActivityId); CosmosContainerSettings collection = null; if (resourceTypeEnum.IsCollectionChild()) { CollectionCache collectionCache = await client.GetCollectionCacheAsync(); using ( DocumentServiceRequest request = DocumentServiceRequest.Create( OperationType.Query, resourceTypeEnum, resourceLink, AuthorizationTokenType.Invalid)) //this request doesnt actually go to server { collection = await collectionCache.ResolveCollectionAsync(request, token); } } // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop, so need to bypass in that case. // We are also now bypassing this for 32 bit host process running even on Windows as there are many 32 bit apps that will not work without this if (CustomTypeExtensions.ByPassQueryParsing()) { // We create a ProxyDocumentQueryExecutionContext that will be initialized with DefaultDocumentQueryExecutionContext // which will be used to send the query to Gateway and on getting 400(bad request) with 1004(cross partition query not servable), we initialize it with // PipelinedDocumentQueryExecutionContext by providing the partition query execution info that's needed(which we get from the exception returned from Gateway). ProxyDocumentQueryExecutionContext proxyQueryExecutionContext = ProxyDocumentQueryExecutionContext.CreateAsync( client, resourceTypeEnum, resourceType, expression, feedOptions, resourceLink, token, collection, isContinuationExpected, correlatedActivityId); return(proxyQueryExecutionContext); } DefaultDocumentQueryExecutionContext queryExecutionContext = await DefaultDocumentQueryExecutionContext.CreateAsync( constructorParams, isContinuationExpected, token); // If isContinuationExpected is false, we want to check if there are aggregates. if ( resourceTypeEnum.IsCollectionChild() && resourceTypeEnum.IsPartitioned() && (feedOptions.EnableCrossPartitionQuery || !isContinuationExpected)) { //todo:elasticcollections this may rely on information from collection cache which is outdated //if collection is deleted/created with same name. //need to make it not rely on information from collection cache. PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = await queryExecutionContext.GetPartitionedQueryExecutionInfoAsync( collection.PartitionKey, true, isContinuationExpected, token); if (DocumentQueryExecutionContextFactory.ShouldCreateSpecializedDocumentQueryExecutionContext( resourceTypeEnum, feedOptions, partitionedQueryExecutionInfo, collection.PartitionKey, isContinuationExpected)) { List <PartitionKeyRange> targetRanges; if (!string.IsNullOrEmpty(feedOptions.PartitionKeyRangeId)) { targetRanges = new List <PartitionKeyRange> { await queryExecutionContext.GetTargetPartitionKeyRangeById( collection.ResourceId, feedOptions.PartitionKeyRangeId) }; } else { List <Range <string> > queryRanges = partitionedQueryExecutionInfo.QueryRanges; if (feedOptions.PartitionKey != null) { queryRanges = new List <Range <string> > { Range <string> .GetPointRange( feedOptions.PartitionKey.InternalKey.GetEffectivePartitionKeyString( collection.PartitionKey)) }; } targetRanges = await queryExecutionContext.GetTargetPartitionKeyRanges(collection.ResourceId, queryRanges); } return(await CreateSpecializedDocumentQueryExecutionContext( constructorParams, partitionedQueryExecutionInfo, targetRanges, collection.ResourceId, isContinuationExpected, token)); } } return(queryExecutionContext); }