Exemplo n.º 1
0
        internal override async Task <PartitionedQueryExecutionInfo> GetPartitionedQueryExecutionInfoAsync(
            SqlQuerySpec sqlQuerySpec,
            PartitionKeyDefinition partitionKeyDefinition,
            bool requireFormattableOrderByQuery,
            bool isContinuationExpected,
            bool allowNonValueAggregateQuery,
            CancellationToken cancellationToken)
        {
            QueryPartitionProvider queryPartitionProvider = await this.DocumentQueryClient.GetQueryPartitionProviderAsync(cancellationToken);

            return(queryPartitionProvider.GetPartitionedQueryExecutionInfo(
                       sqlQuerySpec,
                       partitionKeyDefinition,
                       requireFormattableOrderByQuery,
                       isContinuationExpected,
                       allowNonValueAggregateQuery));
        }
Exemplo n.º 2
0
        public void TestInteropTest()
        {
            try
            {
                CosmosClient client = new CosmosClient(connectionString: null);
                Assert.Fail();
            }
            catch (ArgumentNullException)
            {
            }

            Assert.IsTrue(ServiceInteropWrapper.AssembliesExist.Value);

            string            configJson = "{}";
            IntPtr            provider;
            TryCatch <IntPtr> tryCreateServiceProvider = QueryPartitionProvider.TryCreateServiceProvider(configJson);

            Assert.IsFalse(tryCreateServiceProvider.Failed);
            // Don't leak on tests
            Marshal.Release(tryCreateServiceProvider.Result);
        }
Exemplo n.º 3
0
        internal override async Task <PartitionedQueryExecutionInfo> GetPartitionedQueryExecutionInfoAsync(
            SqlQuerySpec sqlQuerySpec,
            PartitionKeyDefinition partitionKeyDefinition,
            bool requireFormattableOrderByQuery,
            bool isContinuationExpected,
            bool allowNonValueAggregateQuery,
            bool hasLogicalPartitionKey,
            CancellationToken cancellationToken)
        {
            if (this.queryPartitionProvider == null)
            {
                try
                {
                    await this.semaphore.WaitAsync(cancellationToken);

                    if (this.queryPartitionProvider == null)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        IDictionary <string, object> queryConfiguration = await this.documentClient.GetQueryEngineConfigurationAsync();

                        this.queryPartitionProvider = new QueryPartitionProvider(queryConfiguration);
                    }
                }
                finally
                {
                    this.semaphore.Release();
                }
            }

            return(this.queryPartitionProvider.GetPartitionedQueryExecutionInfo(
                       this.CreateBadRequestException,
                       sqlQuerySpec,
                       partitionKeyDefinition,
                       requireFormattableOrderByQuery,
                       isContinuationExpected,
                       allowNonValueAggregateQuery,
                       hasLogicalPartitionKey));
        }
        public static IReadOnlyList <Range <string> > GetProvidedPartitionKeyRanges(
            Func <string, Exception> createBadRequestException,
            SqlQuerySpec querySpec,
            bool enableCrossPartitionQuery,
            bool parallelizeCrossPartitionQuery,
            bool isContinuationExpected,
            bool hasLogicalPartitionKey,
            PartitionKeyDefinition partitionKeyDefinition,
            QueryPartitionProvider queryPartitionProvider,
            string clientApiVersion,
            out QueryInfo queryInfo)
        {
            if (querySpec == null)
            {
                throw new ArgumentNullException("querySpec");
            }

            if (partitionKeyDefinition == null)
            {
                throw new ArgumentNullException("partitionKeyDefinition");
            }

            if (queryPartitionProvider == null)
            {
                throw new ArgumentNullException("queryPartitionProvider");
            }

            TryCatch <PartitionedQueryExecutionInfo> tryGetPartitionQueryExecutionInfo = queryPartitionProvider.TryGetPartitionedQueryExecutionInfo(
                querySpec: querySpec,
                partitionKeyDefinition: partitionKeyDefinition,
                requireFormattableOrderByQuery: VersionUtility.IsLaterThan(clientApiVersion, HttpConstants.Versions.v2016_11_14),
                isContinuationExpected: isContinuationExpected,
                allowNonValueAggregateQuery: false,
                hasLogicalPartitionKey: hasLogicalPartitionKey);

            if (!tryGetPartitionQueryExecutionInfo.Succeeded)
            {
                throw new BadRequestException(tryGetPartitionQueryExecutionInfo.Exception);
            }

            PartitionedQueryExecutionInfo queryExecutionInfo = tryGetPartitionQueryExecutionInfo.Result;

            if (queryExecutionInfo == null ||
                queryExecutionInfo.QueryRanges == null ||
                queryExecutionInfo.QueryInfo == null ||
                queryExecutionInfo.QueryRanges.Any(range => range.Min == null || range.Max == null))
            {
                DefaultTrace.TraceInformation("QueryPartitionProvider returned bad query info");
            }

            bool isSinglePartitionQuery = queryExecutionInfo.QueryRanges.Count == 1 && queryExecutionInfo.QueryRanges[0].IsSingleValue;

            bool queryFansOutToMultiplePartitions = partitionKeyDefinition.Paths.Count > 0 && !isSinglePartitionQuery;

            if (queryFansOutToMultiplePartitions)
            {
                if (!enableCrossPartitionQuery)
                {
                    throw new BadRequestException(RMResources.CrossPartitionQueryDisabled);
                }
                else
                {
                    bool queryNotServiceableByGateway = parallelizeCrossPartitionQuery ||
                                                        queryExecutionInfo.QueryInfo.HasTop ||
                                                        queryExecutionInfo.QueryInfo.HasOrderBy ||
                                                        queryExecutionInfo.QueryInfo.HasAggregates ||
                                                        queryExecutionInfo.QueryInfo.HasDistinct ||
                                                        queryExecutionInfo.QueryInfo.HasOffset ||
                                                        queryExecutionInfo.QueryInfo.HasLimit;

                    if (queryNotServiceableByGateway)
                    {
                        if (!IsSupportedPartitionedQueryExecutionInfo(queryExecutionInfo, clientApiVersion))
                        {
                            throw new BadRequestException(RMResources.UnsupportedCrossPartitionQuery);
                        }
                        else if (queryExecutionInfo.QueryInfo.HasAggregates && !IsAggregateSupportedApiVersion(clientApiVersion))
                        {
                            throw new BadRequestException(RMResources.UnsupportedCrossPartitionQueryWithAggregate);
                        }
                        else
                        {
                            DocumentClientException exception = new DocumentClientException(
                                RMResources.UnsupportedCrossPartitionQuery,
                                HttpStatusCode.BadRequest,
                                SubStatusCodes.CrossPartitionQueryNotServable);

                            exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                            throw exception;
                        }
                    }
                }
            }
            else
            {
                if (queryExecutionInfo.QueryInfo.HasAggregates && !isContinuationExpected)
                {
                    // For single partition query with aggregate functions and no continuation expected,
                    // we would try to accumulate the results for them on the SDK, if supported.

                    if (IsAggregateSupportedApiVersion(clientApiVersion))
                    {
                        DocumentClientException exception = new DocumentClientException(
                            RMResources.UnsupportedQueryWithFullResultAggregate,
                            HttpStatusCode.BadRequest,
                            SubStatusCodes.CrossPartitionQueryNotServable);

                        exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                        throw exception;
                    }
                    else
                    {
                        throw new BadRequestException(RMResources.UnsupportedQueryWithFullResultAggregate);
                    }
                }
                else if (queryExecutionInfo.QueryInfo.HasDistinct)
                {
                    // If the query has distinct then we have to reject it since the backend only returns
                    // elements that are distinct within a page and we need the client to do post distinct processing
                    DocumentClientException exception = new DocumentClientException(
                        RMResources.UnsupportedCrossPartitionQuery,
                        HttpStatusCode.BadRequest,
                        SubStatusCodes.CrossPartitionQueryNotServable);

                    exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                    throw exception;
                }
            }

            queryInfo = queryExecutionInfo.QueryInfo;
            return(queryExecutionInfo.QueryRanges);
        }
Exemplo n.º 5
0
        public static IReadOnlyList <Range <string> > GetProvidedPartitionKeyRanges(
            SqlQuerySpec querySpec,
            bool enableCrossPartitionQuery,
            bool parallelizeCrossPartitionQuery,
            bool isContinuationExpected,
            PartitionKeyDefinition partitionKeyDefinition,
            QueryPartitionProvider queryPartitionProvider,
            string clientApiVersion,
            out QueryInfo queryInfo)
        {
            if (querySpec == null)
            {
                throw new ArgumentNullException("querySpec");
            }

            if (partitionKeyDefinition == null)
            {
                throw new ArgumentNullException("partitionKeyDefinition");
            }

            if (queryPartitionProvider == null)
            {
                throw new ArgumentNullException("queryPartitionProvider");
            }

            PartitionedQueryExecutionInfo queryExecutionInfo = null;

            queryExecutionInfo = queryPartitionProvider.GetPartitionedQueryExecutionInfo(
                querySpec,
                partitionKeyDefinition,
                VersionUtility.IsLaterThan(clientApiVersion, HttpConstants.Versions.v2016_11_14),
                isContinuationExpected);

            if (queryExecutionInfo == null ||
                queryExecutionInfo.QueryRanges == null ||
                queryExecutionInfo.QueryInfo == null ||
                queryExecutionInfo.QueryRanges.Any(range => range.Min == null || range.Max == null))
            {
                DefaultTrace.TraceInformation("QueryPartitionProvider returned bad query info");
            }

            bool isSinglePartitionQuery = queryExecutionInfo.QueryRanges.Count == 1 && queryExecutionInfo.QueryRanges[0].IsSingleValue;

            if (partitionKeyDefinition.Paths.Count > 0 && !isSinglePartitionQuery)
            {
                if (!enableCrossPartitionQuery)
                {
                    throw new BadRequestException(RMResources.CrossPartitionQueryDisabled);
                }
                else
                {
                    if (parallelizeCrossPartitionQuery ||
                        (queryExecutionInfo.QueryInfo != null && (queryExecutionInfo.QueryInfo.HasTop || queryExecutionInfo.QueryInfo.HasOrderBy || queryExecutionInfo.QueryInfo.HasAggregates)))
                    {
                        if (!IsSupportedPartitionedQueryExecutionInfo(queryExecutionInfo, clientApiVersion))
                        {
                            throw new BadRequestException(RMResources.UnsupportedCrossPartitionQuery);
                        }
                        else if (queryExecutionInfo.QueryInfo.HasAggregates && !IsAggregateSupportedApiVersion(clientApiVersion))
                        {
                            throw new BadRequestException(RMResources.UnsupportedCrossPartitionQueryWithAggregate);
                        }
                        else
                        {
                            DocumentClientException exception = new DocumentClientException(
                                RMResources.UnsupportedCrossPartitionQuery,
                                HttpStatusCode.BadRequest,
                                SubStatusCodes.CrossPartitionQueryNotServable);

                            exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                            throw exception;
                        }
                    }
                }
            }
            // For single partition query with aggregate functions and no continuation expected,
            // we would try to accumulate the results for them on the SDK, if supported.
            else if (queryExecutionInfo.QueryInfo.HasAggregates && !isContinuationExpected)
            {
                if (IsAggregateSupportedApiVersion(clientApiVersion))
                {
                    DocumentClientException exception = new DocumentClientException(
                        RMResources.UnsupportedQueryWithFullResultAggregate,
                        HttpStatusCode.BadRequest,
                        SubStatusCodes.CrossPartitionQueryNotServable);

                    exception.Error.AdditionalErrorInfo = JsonConvert.SerializeObject(queryExecutionInfo);
                    throw exception;
                }
                else
                {
                    throw new BadRequestException(RMResources.UnsupportedQueryWithFullResultAggregate);
                }
            }

            queryInfo = queryExecutionInfo.QueryInfo;
            return(queryExecutionInfo.QueryRanges);
        }