/// <summary> /// Gets the list of partition key ranges. /// 1. Check partition key range id /// 2. Check Partition key /// 3. Check the effective partition key /// 4. Get the range from the PartitionedQueryExecutionInfo /// </summary> internal static async Task <List <Documents.PartitionKeyRange> > GetTargetPartitionKeyRangesAsync( CosmosQueryClient queryClient, string resourceLink, PartitionedQueryExecutionInfo partitionedQueryExecutionInfo, ContainerQueryProperties containerQueryProperties, IDictionary <string, object> properties) { List <Documents.PartitionKeyRange> targetRanges; if (containerQueryProperties.EffectivePartitionKeyString != null) { targetRanges = await queryClient.GetTargetPartitionKeyRangesByEpkStringAsync( resourceLink, containerQueryProperties.ResourceId, containerQueryProperties.EffectivePartitionKeyString); } else if (TryGetEpkProperty(properties, out string effectivePartitionKeyString)) { targetRanges = await queryClient.GetTargetPartitionKeyRangesByEpkStringAsync( resourceLink, containerQueryProperties.ResourceId, effectivePartitionKeyString); } else { targetRanges = await queryClient.GetTargetPartitionKeyRangesAsync( resourceLink, containerQueryProperties.ResourceId, partitionedQueryExecutionInfo.QueryRanges); } return(targetRanges); }
public async Task <CosmosQueryExecutionContext> CreateFromPartitionedQuerExecutionInfoAsync( PartitionedQueryExecutionInfo partitionedQueryExecutionInfo, ContainerQueryProperties containerQueryProperties, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); List <Documents.PartitionKeyRange> targetRanges = await CosmosQueryExecutionContextFactory.GetTargetPartitionKeyRangesAsync( this.CosmosQueryContext.QueryClient, this.CosmosQueryContext.ResourceLink.OriginalString, partitionedQueryExecutionInfo, containerQueryProperties, this.inputParameters.Properties); if (!string.IsNullOrEmpty(partitionedQueryExecutionInfo.QueryInfo.RewrittenQuery)) { // We need pass down the rewritten query. this.inputParameters.SqlQuerySpec = new SqlQuerySpec() { QueryText = partitionedQueryExecutionInfo.QueryInfo.RewrittenQuery, Parameters = this.inputParameters.SqlQuerySpec.Parameters }; } return(await CosmosQueryExecutionContextFactory.CreateSpecializedDocumentQueryExecutionContextAsync( this.CosmosQueryContext, this.inputParameters, partitionedQueryExecutionInfo, targetRanges, containerQueryProperties.ResourceId, cancellationToken)); }
private async Task <CosmosQueryExecutionContext> CreateItemQueryExecutionContextAsync( CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); CosmosQueryClient cosmosQueryClient = this.CosmosQueryContext.QueryClient; ContainerQueryProperties containerQueryProperties = await cosmosQueryClient.GetCachedContainerQueryPropertiesAsync( this.CosmosQueryContext.ResourceLink, this.inputParameters.PartitionKey, cancellationToken); this.CosmosQueryContext.ContainerResourceId = containerQueryProperties.ResourceId; PartitionedQueryExecutionInfo partitionedQueryExecutionInfo; if (this.CosmosQueryContext.QueryClient.ByPassQueryParsing() && TestFlag) { // 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 partitionedQueryExecutionInfo = await QueryPlanRetriever.GetQueryPlanThroughGatewayAsync( this.CosmosQueryContext.QueryClient, this.inputParameters.SqlQuerySpec, this.CosmosQueryContext.ResourceLink, cancellationToken); } else { //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. Documents.PartitionKeyDefinition partitionKeyDefinition; object partitionKeyDefinitionObject; if (this.inputParameters.Properties != null && this.inputParameters.Properties.TryGetValue(InternalPartitionKeyDefinitionProperty, out partitionKeyDefinitionObject)) { if (partitionKeyDefinitionObject is Documents.PartitionKeyDefinition definition) { partitionKeyDefinition = definition; } else { throw new ArgumentException( "partitionkeydefinition has invalid type", nameof(partitionKeyDefinitionObject)); } } else { partitionKeyDefinition = containerQueryProperties.PartitionKeyDefinition; } partitionedQueryExecutionInfo = await QueryPlanRetriever.GetQueryPlanWithServiceInteropAsync( this.CosmosQueryContext.QueryClient, this.inputParameters.SqlQuerySpec, partitionKeyDefinition, this.inputParameters.PartitionKey != null, cancellationToken); } List <Documents.PartitionKeyRange> targetRanges = await CosmosQueryExecutionContextFactory.GetTargetPartitionKeyRangesAsync( this.CosmosQueryContext.QueryClient, this.CosmosQueryContext.ResourceLink.OriginalString, partitionedQueryExecutionInfo, containerQueryProperties, this.inputParameters.Properties); if (!string.IsNullOrEmpty(partitionedQueryExecutionInfo.QueryInfo.RewrittenQuery)) { // We need pass down the rewritten query. this.inputParameters.SqlQuerySpec = new SqlQuerySpec() { QueryText = partitionedQueryExecutionInfo.QueryInfo.RewrittenQuery, Parameters = this.inputParameters.SqlQuerySpec.Parameters }; } return(await CosmosQueryExecutionContextFactory.CreateSpecializedDocumentQueryExecutionContextAsync( this.CosmosQueryContext, this.inputParameters, partitionedQueryExecutionInfo, targetRanges, containerQueryProperties.ResourceId, cancellationToken)); }
private async Task <CosmosQueryExecutionContext> CreateItemQueryExecutionContextAsync( CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); string continuationToken = this.inputParameters.InitialUserContinuationToken; if (this.inputParameters.InitialUserContinuationToken != null) { if (!PipelineContinuationToken.TryParse( continuationToken, out PipelineContinuationToken pipelineContinuationToken)) { throw this.CosmosQueryContext.QueryClient.CreateBadRequestException( $"Malformed {nameof(PipelineContinuationToken)}: {continuationToken}."); } if (PipelineContinuationToken.IsTokenFromTheFuture(pipelineContinuationToken)) { throw this.CosmosQueryContext.QueryClient.CreateBadRequestException( $"{nameof(PipelineContinuationToken)} Continuation token is from a newer version of the SDK. Upgrade the SDK to avoid this issue.\n {continuationToken}."); } if (!PipelineContinuationToken.TryConvertToLatest( pipelineContinuationToken, out PipelineContinuationTokenV1_1 latestVersionPipelineContinuationToken)) { throw this.CosmosQueryContext.QueryClient.CreateBadRequestException( $"{nameof(PipelineContinuationToken)}: '{continuationToken}' is no longer supported."); } continuationToken = latestVersionPipelineContinuationToken.SourceContinuationToken; this.inputParameters.InitialUserContinuationToken = continuationToken; if (latestVersionPipelineContinuationToken.QueryPlan != null) { this.inputParameters.PartitionedQueryExecutionInfo = latestVersionPipelineContinuationToken.QueryPlan; } } CosmosQueryClient cosmosQueryClient = this.CosmosQueryContext.QueryClient; ContainerQueryProperties containerQueryProperties = await cosmosQueryClient.GetCachedContainerQueryPropertiesAsync( this.CosmosQueryContext.ResourceLink, this.inputParameters.PartitionKey, cancellationToken); this.CosmosQueryContext.ContainerResourceId = containerQueryProperties.ResourceId; PartitionedQueryExecutionInfo partitionedQueryExecutionInfo; if (this.inputParameters.PartitionedQueryExecutionInfo != null) { partitionedQueryExecutionInfo = this.inputParameters.PartitionedQueryExecutionInfo; } else { if (this.CosmosQueryContext.QueryClient.ByPassQueryParsing()) { // 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 partitionedQueryExecutionInfo = await QueryPlanRetriever.GetQueryPlanThroughGatewayAsync( this.CosmosQueryContext.QueryClient, this.inputParameters.SqlQuerySpec, this.CosmosQueryContext.ResourceLink, cancellationToken); } else { //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. Documents.PartitionKeyDefinition partitionKeyDefinition; object partitionKeyDefinitionObject; if (this.inputParameters.Properties != null && this.inputParameters.Properties.TryGetValue(InternalPartitionKeyDefinitionProperty, out partitionKeyDefinitionObject)) { if (partitionKeyDefinitionObject is Documents.PartitionKeyDefinition definition) { partitionKeyDefinition = definition; } else { throw new ArgumentException( "partitionkeydefinition has invalid type", nameof(partitionKeyDefinitionObject)); } } else { partitionKeyDefinition = containerQueryProperties.PartitionKeyDefinition; } partitionedQueryExecutionInfo = await QueryPlanRetriever.GetQueryPlanWithServiceInteropAsync( this.CosmosQueryContext.QueryClient, this.inputParameters.SqlQuerySpec, partitionKeyDefinition, this.inputParameters.PartitionKey != null, cancellationToken); } } this.partitionedQueryExecutionInfo = partitionedQueryExecutionInfo; return(await this.CreateFromPartitionedQuerExecutionInfoAsync( partitionedQueryExecutionInfo, containerQueryProperties, cancellationToken)); }