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)); }
private async Task <CosmosQueryExecutionContext> CreateItemQueryExecutionContextAsync( CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); CosmosContainerSettings containerSettings = await this.GetContainerSettingsAsync(cancellationToken); this.cosmosQueryContext.ContainerResourceId = containerSettings.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.cosmosQueryContext.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. PartitionKeyDefinition partitionKeyDefinition; object partitionKeyDefinitionObject; if (this.cosmosQueryContext.QueryRequestOptions?.Properties != null && this.cosmosQueryContext.QueryRequestOptions.Properties.TryGetValue(InternalPartitionKeyDefinitionProperty, out partitionKeyDefinitionObject)) { if (partitionKeyDefinitionObject is PartitionKeyDefinition definition) { partitionKeyDefinition = definition; } else { throw new ArgumentException( "partitionkeydefinition has invalid type", nameof(partitionKeyDefinitionObject)); } } else { partitionKeyDefinition = containerSettings.PartitionKey; } partitionedQueryExecutionInfo = await QueryPlanRetriever.GetQueryPlanWithServiceInteropAsync( this.cosmosQueryContext.QueryClient, this.cosmosQueryContext.SqlQuerySpec, partitionKeyDefinition, cancellationToken); } List <PartitionKeyRange> targetRanges = await GetTargetPartitionKeyRangesAsync( this.cosmosQueryContext.QueryClient, this.cosmosQueryContext.ResourceLink.OriginalString, partitionedQueryExecutionInfo, containerSettings, this.cosmosQueryContext.QueryRequestOptions); CosmosQueryContext rewrittenComosQueryContext; if (!string.IsNullOrEmpty(partitionedQueryExecutionInfo.QueryInfo.RewrittenQuery)) { // We need pass down the rewritten query. SqlQuerySpec rewrittenQuerySpec = new SqlQuerySpec() { QueryText = partitionedQueryExecutionInfo.QueryInfo.RewrittenQuery, Parameters = this.cosmosQueryContext.SqlQuerySpec.Parameters }; rewrittenComosQueryContext = new CosmosQueryContext( this.cosmosQueryContext.QueryClient, this.cosmosQueryContext.ResourceTypeEnum, this.cosmosQueryContext.OperationTypeEnum, this.cosmosQueryContext.ResourceType, rewrittenQuerySpec, this.cosmosQueryContext.QueryRequestOptions, this.cosmosQueryContext.ResourceLink, this.cosmosQueryContext.IsContinuationExpected, this.cosmosQueryContext.CorrelatedActivityId, this.cosmosQueryContext.IsContinuationExpected, this.cosmosQueryContext.AllowNonValueAggregateQuery, this.cosmosQueryContext.ContainerResourceId); } else { rewrittenComosQueryContext = this.cosmosQueryContext; } return(await CreateSpecializedDocumentQueryExecutionContextAsync( rewrittenComosQueryContext, partitionedQueryExecutionInfo, targetRanges, containerSettings.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.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); } } return(await this.CreateFromPartitionedQuerExecutionInfoAsync( partitionedQueryExecutionInfo, containerQueryProperties, cancellationToken)); }