Example #1
0
        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));
        }
Example #3
0
        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));
        }