Beispiel #1
0
            /// <inheritdoc />
            public override void WriteNumberValue(Number64 value)
            {
                if (value.IsInteger)
                {
                    this.WriteIntegerInternal(Number64.ToLong(value));
                }
                else
                {
                    this.WriteDoubleInternal(Number64.ToDouble(value));
                }

                this.bufferedContexts.Peek().Count++;
            }
        public static MockQueryPipelineStage Create(
            IReadOnlyList <IReadOnlyList <CosmosElement> > pages,
            CosmosElement continuationToken)
        {
            MockQueryPipelineStage stage = new MockQueryPipelineStage(pages);

            if (continuationToken != null)
            {
                CosmosNumber index = continuationToken as CosmosNumber;
                stage.PageIndex = Number64.ToLong(index.Value);
            }

            return(stage);
        }
Beispiel #3
0
        private static int GetResponseCount(Stream stream)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                stream.CopyTo(memoryStream);
                CosmosObject element = CosmosObject.CreateFromBuffer(memoryStream.ToArray());
                if (!element.TryGetValue("_count", out CosmosElement value))
                {
                    Assert.Fail();
                }

                return((int)Number64.ToLong(((CosmosNumber)value).Value));
            }
        }
Beispiel #4
0
        public override long?AsInteger()
        {
            long?value;

            if (this.IsInteger)
            {
                value = Number64.ToLong(this.GetValue());
            }
            else
            {
                value = null;
            }

            return(value);
        }
        public async Task DCount()
        {
            List <CosmosObject> documents = new List <CosmosObject>();

            for (int i = 0; i < 250; i++)
            {
                documents.Add(CosmosObject.Parse($"{{\"pk\" : {i}, \"val\": {i % 49} }}"));
            }

            List <CosmosElement> documentsQueried = await ExecuteQueryAsync(
                query : "SELECT VALUE COUNT(1) FROM (SELECT DISTINCT VALUE c.val FROM c)",
                documents : documents);

            Assert.AreEqual(expected: 1, actual: documentsQueried.Count);
            Assert.IsTrue(documentsQueried[0] is CosmosNumber);
            CosmosNumber result = documentsQueried[0] as CosmosNumber;

            Assert.AreEqual(expected: 49, actual: Number64.ToLong(result.Value));
        }
        public static SqlNumberLiteral Create(Number64 number64)
        {
            SqlNumberLiteral sqlNumberLiteral;

            if (number64.IsDouble)
            {
                if (!SqlNumberLiteral.FrequentDoubles.TryGetValue(Number64.ToDouble(number64), out sqlNumberLiteral))
                {
                    sqlNumberLiteral = new SqlNumberLiteral(number64);
                }
            }
            else
            {
                if (!SqlNumberLiteral.FrequentLongs.TryGetValue(Number64.ToLong(number64), out sqlNumberLiteral))
                {
                    sqlNumberLiteral = new SqlNumberLiteral(number64);
                }
            }

            return(sqlNumberLiteral);
        }
            /// <summary>
            /// Initializes a new instance of the AverageInfo class.
            /// </summary>
            public static TryCatch <AverageInfo> TryCreateFromCosmosElement(CosmosElement cosmosElement)
            {
                if (cosmosElement == null)
                {
                    throw new ArgumentNullException($"{nameof(cosmosElement)} must not be null.");
                }

                if (!(cosmosElement is CosmosObject cosmosObject))
                {
                    return(TryCatch <AverageInfo> .FromException(
                               new ArgumentException($"{nameof(cosmosElement)} must be an object.")));
                }

                double?sum;

                if (cosmosObject.TryGetValue(SumName, out CosmosElement sumPropertyValue))
                {
                    if (!(sumPropertyValue is CosmosNumber cosmosSum))
                    {
                        return(TryCatch <AverageInfo> .FromException(
                                   new ArgumentException($"value for the {SumName} field was not a number")));
                    }

                    sum = Number64.ToDouble(cosmosSum.Value);
                }
                else
                {
                    sum = null;
                }

                if (!cosmosObject.TryGetValue(CountName, out CosmosNumber cosmosCount))
                {
                    return(TryCatch <AverageInfo> .FromException(
                               new ArgumentException($"value for the {CountName} field was not a number")));
                }

                long count = Number64.ToLong(cosmosCount.Value);

                return(TryCatch <AverageInfo> .FromResult(new AverageInfo(sum, count)));
            }
Beispiel #8
0
        public static TryCatch <IAggregator> TryCreate(CosmosElement continuationToken)
        {
            long partialCount;

            if (continuationToken != null)
            {
                if (!(continuationToken is CosmosNumber cosmosPartialCount))
                {
                    return(TryCatch <IAggregator> .FromException(
                               new MalformedContinuationTokenException($@"Invalid count continuation token: ""{continuationToken}"".")));
                }

                partialCount = Number64.ToLong(cosmosPartialCount.Value);
            }
            else
            {
                partialCount = 0;
            }

            return(TryCatch <IAggregator> .FromResult(
                       new CountAggregator(initialCount : partialCount)));
        }
Beispiel #9
0
        private static IEnumerable <CosmosElement> ExecuteSelectClause(
            IEnumerable <IGrouping <GroupByKey, CosmosElement> > groupings,
            SqlSelectClause sqlSelectClause)
        {
            IEnumerable <CosmosElement> dataSource = ProjectOnGroupings(
                groupings,
                sqlSelectClause);

            if (sqlSelectClause.HasDistinct)
            {
                dataSource = dataSource.Distinct();
            }

            if (sqlSelectClause.TopSpec != null)
            {
                CosmosNumber cosmosTopValue = (CosmosNumber)sqlSelectClause.TopSpec.TopExpresion.Accept(
                    ScalarExpressionEvaluator.Singleton,
                    input: null);
                long topCount = Number64.ToLong(cosmosTopValue.Value);
                dataSource = dataSource.Take((int)topCount);
            }

            return(dataSource);
        }
        public async Task Aggregates()
        {
            const int           DocumentCount = 250;
            List <CosmosObject> documents     = new List <CosmosObject>();

            for (int i = 0; i < DocumentCount; i++)
            {
                documents.Add(CosmosObject.Parse($"{{\"pk\" : {i} }}"));
            }

            List <CosmosElement> documentsQueried = await ExecuteQueryAsync(
                query : "SELECT VALUE COUNT(1) FROM c",
                documents : documents);

            Assert.AreEqual(expected: 1, actual: documentsQueried.Count);
            if (documentsQueried[0] is CosmosNumber number)
            {
                Assert.AreEqual(expected: DocumentCount, actual: Number64.ToLong(number.Value));
            }
            else
            {
                Assert.Fail();
            }
        }
        public static TryCatch <OrderByContinuationToken> TryCreateFromCosmosElement(CosmosElement cosmosElement)
        {
            if (!(cosmosElement is CosmosObject cosmosObject))
            {
                return(TryCatch <OrderByContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(OrderByContinuationToken)} is not an object: {cosmosElement}")));
            }

            if (!cosmosObject.TryGetValue(PropertyNames.CompositeToken, out CosmosElement compositeContinuationTokenElement))
            {
                return(TryCatch <OrderByContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(OrderByContinuationToken)} is missing field: '{PropertyNames.CompositeToken}': {cosmosElement}")));
            }

            TryCatch <ParallelContinuationToken> tryCompositeContinuation = ParallelContinuationToken.TryCreateFromCosmosElement(compositeContinuationTokenElement);

            if (!tryCompositeContinuation.Succeeded)
            {
                return(TryCatch <OrderByContinuationToken> .FromException(tryCompositeContinuation.Exception));
            }

            ParallelContinuationToken compositeContinuationToken = tryCompositeContinuation.Result;

            if (!cosmosObject.TryGetValue(PropertyNames.OrderByItems, out CosmosArray orderByItemsRaw))
            {
                return(TryCatch <OrderByContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(OrderByContinuationToken)} is missing field: '{PropertyNames.OrderByItems}': {cosmosElement}")));
            }

            List <OrderByItem> orderByItems = orderByItemsRaw.Select(x => OrderByItem.FromCosmosElement(x)).ToList();

            if (!cosmosObject.TryGetValue(PropertyNames.Rid, out CosmosString ridRaw))
            {
                return(TryCatch <OrderByContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(OrderByContinuationToken)} is missing field: '{PropertyNames.Rid}': {cosmosElement}")));
            }

            string rid = ridRaw.Value;

            if (!cosmosObject.TryGetValue(PropertyNames.SkipCount, out CosmosNumber64 skipCountRaw))
            {
                return(TryCatch <OrderByContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(OrderByContinuationToken)} is missing field: '{PropertyNames.SkipCount}': {cosmosElement}")));
            }

            int skipCount = (int)Number64.ToLong(skipCountRaw.GetValue());

            if (!cosmosObject.TryGetValue(PropertyNames.Filter, out CosmosElement filterRaw))
            {
                return(TryCatch <OrderByContinuationToken> .FromException(
                           new MalformedContinuationTokenException($"{nameof(OrderByContinuationToken)} is missing field: '{PropertyNames.Filter}': {cosmosElement}")));
            }

            string filter;

            if (filterRaw is CosmosString filterStringRaw)
            {
                filter = filterStringRaw.Value;
            }
            else
            {
                filter = null;
            }

            OrderByContinuationToken orderByContinuationToken = new OrderByContinuationToken(
                compositeContinuationToken,
                orderByItems,
                rid,
                skipCount,
                filter);

            return(TryCatch <OrderByContinuationToken> .FromResult(orderByContinuationToken));
        }
 public override long?AsInteger()
 {
     return(Number64.ToLong(this.number));
 }
 public override IEnumerable <Either <long, string> > Visit(SqlNumberPathExpression sqlObject)
 {
     this.tokens.Add(Number64.ToLong(sqlObject.Value.Value));
     sqlObject.ParentPath?.Accept(this);
     return(this.tokens);
 }
        public void Aggregate(CosmosElement localMinMax)
        {
            // If the value became undefinded at some point then it should stay that way.
            if (this.globalMinMax == Undefined)
            {
                return;
            }

            if (localMinMax == Undefined)
            {
                // If we got an undefined in the pipeline then the whole thing becomes undefined.
                this.globalMinMax = Undefined;
                return;
            }

            // Check to see if we got the higher precision result
            // and unwrap the object to get the actual item of interest
            if (localMinMax is CosmosObject cosmosObject)
            {
                if (cosmosObject.TryGetValue("count", out CosmosNumber countToken))
                {
                    // We know the object looks like: {"min": MIN(c.blah), "count": COUNT(c.blah)}
                    long count = Number64.ToLong(countToken.Value);
                    if (count == 0)
                    {
                        // Ignore the value since the continuation / partition had no results that matched the filter so min is undefined.
                        return;
                    }

                    if (!cosmosObject.TryGetValue("min", out CosmosElement min))
                    {
                        min = null;
                    }

                    if (!cosmosObject.TryGetValue("max", out CosmosElement max))
                    {
                        max = null;
                    }

                    if (min != null)
                    {
                        localMinMax = min;
                    }
                    else if (max != null)
                    {
                        localMinMax = max;
                    }
                    else
                    {
                        localMinMax = Undefined;
                    }
                }
            }

            if (!ItemComparer.IsMinOrMax(this.globalMinMax) && (!IsPrimitve(localMinMax) || !IsPrimitve(this.globalMinMax)))
            {
                // This means we are comparing non primitives which is undefined
                this.globalMinMax = Undefined;
                return;
            }

            // Finally do the comparision
            if (this.isMinAggregation)
            {
                if (ItemComparer.Instance.Compare(localMinMax, this.globalMinMax) < 0)
                {
                    this.globalMinMax = localMinMax;
                }
            }
            else
            {
                if (ItemComparer.Instance.Compare(localMinMax, this.globalMinMax) > 0)
                {
                    this.globalMinMax = localMinMax;
                }
            }
        }
        public async Task TestDistinct_ExecuteNextAsync()
        {
            async Task ImplementationAsync(Container container, IReadOnlyList <CosmosObject> documents)
            {
                #region Queries
                // To verify distint queries you can run it once without the distinct clause and run it through a hash set
                // then compare to the query with the distinct clause.
                List <(string, bool)> queries = new List <(string, bool)>()
                {
                    // basic distinct queries
                    ("SELECT {0} VALUE null", true),

                    // number value distinct queries
                    ("SELECT {0} VALUE c.income from c", true),

                    // string value distinct queries
                    ("SELECT {0} VALUE c.name from c", true),

                    // array value distinct queries
                    ("SELECT {0} VALUE c.children from c", true),

                    // object value distinct queries
                    ("SELECT {0} VALUE c.pet from c", true),

                    // scalar expressions distinct query
                    ("SELECT {0} VALUE c.age % 2 FROM c", true),

                    // distinct queries with order by
                    ("SELECT {0} VALUE c.age FROM c ORDER BY c.age", false),

                    // distinct queries with top and no matching order by
                    ("SELECT {0} TOP 2147483647 VALUE c.age FROM c", false),

                    // distinct queries with top and  matching order by
                    ("SELECT {0} TOP 2147483647 VALUE c.age FROM c ORDER BY c.age", false),

                    // distinct queries with aggregates
                    ("SELECT {0} VALUE MAX(c.age) FROM c", false),

                    // distinct queries with joins
                    ("SELECT {0} VALUE c.age FROM p JOIN c IN p.children", true),

                    // distinct queries in subqueries
                    ("SELECT {0} r.age, s FROM r JOIN (SELECT DISTINCT VALUE c FROM (SELECT 1 a) c) s WHERE r.age > 25", false),

                    // distinct queries in scalar subqeries
                    ("SELECT {0} p.name, (SELECT DISTINCT VALUE p.age) AS Age FROM p", true),

                    // select *
                    ("SELECT {0} * FROM c", true)
                };
                #endregion
                #region ExecuteNextAsync API
                // run the query with distinct and without + MockDistinctMap
                // Should receive same results
                // PageSize = 1 guarantees that the backend will return some duplicates.
                foreach ((string query, bool allowDCount) in queries)
                {
                    string queryWithoutDistinct = string.Format(query, "");

                    QueryRequestOptions requestOptions = new QueryRequestOptions()
                    {
                        MaxItemCount = 100, MaxConcurrency = 100
                    };
                    FeedIterator <CosmosElement> documentQueryWithoutDistinct = container.GetItemQueryIterator <CosmosElement>(
                        queryWithoutDistinct,
                        requestOptions: requestOptions);

                    MockDistinctMap      documentsSeen = new MockDistinctMap();
                    List <CosmosElement> documentsFromWithoutDistinct = new List <CosmosElement>();
                    while (documentQueryWithoutDistinct.HasMoreResults)
                    {
                        FeedResponse <CosmosElement> cosmosQueryResponse = await documentQueryWithoutDistinct.ReadNextAsync();

                        foreach (CosmosElement document in cosmosQueryResponse)
                        {
                            if (documentsSeen.Add(document, out UInt128 hash))
                            {
                                documentsFromWithoutDistinct.Add(document);
                            }
                            else
                            {
                                // No Op for debugging purposes.
                            }
                        }
                    }

                    foreach (int pageSize in new int[] { 1, 10, 100 })
                    {
                        string queryWithDistinct = string.Format(query, "DISTINCT");
                        List <CosmosElement>         documentsFromWithDistinct = new List <CosmosElement>();
                        FeedIterator <CosmosElement> documentQueryWithDistinct = container.GetItemQueryIterator <CosmosElement>(
                            queryWithDistinct,
                            requestOptions: requestOptions);

                        while (documentQueryWithDistinct.HasMoreResults)
                        {
                            FeedResponse <CosmosElement> cosmosQueryResponse = await documentQueryWithDistinct.ReadNextAsync();

                            documentsFromWithDistinct.AddRange(cosmosQueryResponse);
                        }

                        Assert.AreEqual(documentsFromWithDistinct.Count, documentsFromWithoutDistinct.Count);
                        for (int i = 0; i < documentsFromWithDistinct.Count; i++)
                        {
                            CosmosElement documentFromWithDistinct    = documentsFromWithDistinct.ElementAt(i);
                            CosmosElement documentFromWithoutDistinct = documentsFromWithoutDistinct.ElementAt(i);
                            Assert.AreEqual(
                                expected: documentFromWithoutDistinct,
                                actual: documentFromWithDistinct,
                                message: $"{documentFromWithDistinct} did not match {documentFromWithoutDistinct} at index {i} for {queryWithDistinct}, with page size: {pageSize} on a container");
                        }

                        if (allowDCount)
                        {
                            string queryWithDCount = $"SELECT VALUE COUNT(1) FROM({queryWithDistinct})";

                            List <CosmosElement>         documentsWithDCount     = new List <CosmosElement>();
                            FeedIterator <CosmosElement> documentQueryWithDCount = container.GetItemQueryIterator <CosmosElement>(
                                queryWithDCount,
                                requestOptions: requestOptions);

                            while (documentQueryWithDCount.HasMoreResults)
                            {
                                FeedResponse <CosmosElement> cosmosQueryResponse = await documentQueryWithDCount.ReadNextAsync();

                                documentsWithDCount.AddRange(cosmosQueryResponse);
                            }

                            Assert.AreEqual(1, documentsWithDCount.Count);
                            long dcount = Number64.ToLong((documentsWithDCount.First() as CosmosNumber).Value);
                            Assert.AreEqual(documentsFromWithoutDistinct.Count, dcount);
                        }
                    }
                }
                #endregion
            }

            await this.TestQueryDistinctBaseAsync(ImplementationAsync);
        }
Beispiel #16
0
        public async Task TestPassthroughQueryAsync()
        {
            string[] inputDocs = new[]
            {
                @"{""id"":""documentId1"",""key"":""A"",""prop"":3,""shortArray"":[{""a"":5}]}",
                @"{""id"":""documentId2"",""key"":""A"",""prop"":2,""shortArray"":[{""a"":6}]}",
                @"{""id"":""documentId3"",""key"":""A"",""prop"":1,""shortArray"":[{""a"":7}]}",
                @"{""id"":""documentId4"",""key"":5,""prop"":3,""shortArray"":[{""a"":5}]}",
                @"{""id"":""documentId5"",""key"":5,""prop"":2,""shortArray"":[{""a"":6}]}",
                @"{""id"":""documentId6"",""key"":5,""prop"":1,""shortArray"":[{""a"":7}]}",
                @"{""id"":""documentId10"",""prop"":3,""shortArray"":[{""a"":5}]}",
                @"{""id"":""documentId11"",""prop"":2,""shortArray"":[{""a"":6}]}",
                @"{""id"":""documentId12"",""prop"":1,""shortArray"":[{""a"":7}]}",
            };

            await this.CreateIngestQueryDeleteAsync(
                ConnectionModes.Direct,
                CollectionTypes.SinglePartition | CollectionTypes.MultiPartition,
                inputDocs,
                ImplementationAsync,
                "/key");

            async Task ImplementationAsync(Container container, IReadOnlyList <CosmosObject> documents)
            {
                foreach (int maxDegreeOfParallelism in new int[] { 1, 100 })
                {
                    foreach (int maxItemCount in new int[] { 10, 100 })
                    {
                        QueryRequestOptions feedOptions = new QueryRequestOptions
                        {
                            MaxBufferedItemCount = 7000,
                            MaxConcurrency       = maxDegreeOfParallelism,
                            MaxItemCount         = maxItemCount,
                        };

                        foreach (string query in new string[]
                        {
                            "SELECT * FROM c WHERE c.key = 5",
                            "SELECT * FROM c WHERE c.key = 5 ORDER BY c._ts",
                        })
                        {
                            feedOptions.TestSettings = new TestInjections(simulate429s: false, simulateEmptyPages: false, responseStats: new TestInjections.ResponseStats());
                            List <CosmosElement> queryResults = await QueryTestsBase.RunQueryAsync(
                                container,
                                query,
                                feedOptions);

                            Assert.IsTrue(feedOptions.TestSettings.Stats.PipelineType.HasValue);
                            Assert.AreEqual(TestInjections.PipelineType.Passthrough, feedOptions.TestSettings.Stats.PipelineType.Value);

                            Assert.AreEqual(
                                3,
                                queryResults.Count,
                                $"query: {query} failed with {nameof(maxDegreeOfParallelism)}: {maxDegreeOfParallelism}, {nameof(maxItemCount)}: {maxItemCount}");
                        }

                        {
                            feedOptions.TestSettings = new TestInjections(simulate429s: false, simulateEmptyPages: false, responseStats: new TestInjections.ResponseStats());

                            string query = "SELECT TOP 2 c.id FROM c WHERE c.key = 5";
                            List <CosmosElement> queryResults = await QueryTestsBase.RunQueryAsync(
                                container,
                                query,
                                feedOptions);

                            Assert.IsTrue(feedOptions.TestSettings.Stats.PipelineType.HasValue);
                            Assert.AreEqual(TestInjections.PipelineType.Passthrough, feedOptions.TestSettings.Stats.PipelineType.Value);

                            Assert.AreEqual(
                                2,
                                queryResults.Count,
                                $"query: {query} failed with {nameof(maxDegreeOfParallelism)}: {maxDegreeOfParallelism}, {nameof(maxItemCount)}: {maxItemCount}");
                        }

                        {
                            feedOptions.TestSettings = new TestInjections(simulate429s: false, simulateEmptyPages: false, responseStats: new TestInjections.ResponseStats());

                            string query = "SELECT c.id FROM c WHERE c.key = 5 OFFSET 1 LIMIT 1";
                            List <CosmosElement> queryResults = await QueryTestsBase.RunQueryAsync(
                                container,
                                query,
                                feedOptions);

                            Assert.IsTrue(feedOptions.TestSettings.Stats.PipelineType.HasValue);
                            Assert.AreEqual(TestInjections.PipelineType.Passthrough, feedOptions.TestSettings.Stats.PipelineType.Value);

                            Assert.AreEqual(
                                1,
                                queryResults.Count,
                                $"query: {query} failed with {nameof(maxDegreeOfParallelism)}: {maxDegreeOfParallelism}, {nameof(maxItemCount)}: {maxItemCount}");
                        }

                        {
                            feedOptions.TestSettings = new TestInjections(simulate429s: false, simulateEmptyPages: false, responseStats: new TestInjections.ResponseStats());

                            string query = "SELECT VALUE COUNT(1) FROM c WHERE c.key = 5";
                            List <CosmosElement> queryResults = await QueryTestsBase.RunQueryAsync(
                                container,
                                query,
                                feedOptions);

                            Assert.IsTrue(feedOptions.TestSettings.Stats.PipelineType.HasValue);
                            Assert.AreEqual(TestInjections.PipelineType.Specialized, feedOptions.TestSettings.Stats.PipelineType.Value);

                            Assert.AreEqual(
                                1,
                                queryResults.Count,
                                $"query: {query} failed with {nameof(maxDegreeOfParallelism)}: {maxDegreeOfParallelism}, {nameof(maxItemCount)}: {maxItemCount}");

                            Assert.AreEqual(
                                3,
                                Number64.ToLong((queryResults.First() as CosmosNumber64).GetValue()),
                                $"query: {query} failed with {nameof(maxDegreeOfParallelism)}: {maxDegreeOfParallelism}, {nameof(maxItemCount)}: {maxItemCount}");
                        }

                        {
                            feedOptions.TestSettings = new TestInjections(simulate429s: false, simulateEmptyPages: false, responseStats: new TestInjections.ResponseStats());

                            string query = "SELECT VALUE c.key FROM c WHERE c.key = 5 GROUP BY c.key";
                            List <CosmosElement> queryResults = await QueryTestsBase.RunQueryCombinationsAsync(
                                container,
                                query,
                                feedOptions,
                                QueryDrainingMode.HoldState | QueryDrainingMode.CosmosElementContinuationToken);

                            Assert.IsTrue(feedOptions.TestSettings.Stats.PipelineType.HasValue);
                            Assert.AreEqual(TestInjections.PipelineType.Specialized, feedOptions.TestSettings.Stats.PipelineType.Value);

                            Assert.AreEqual(
                                1,
                                queryResults.Count,
                                $"query: {query} failed with {nameof(maxDegreeOfParallelism)}: {maxDegreeOfParallelism}, {nameof(maxItemCount)}: {maxItemCount}");
                        }

                        {
                            feedOptions.TestSettings = new TestInjections(simulate429s: false, simulateEmptyPages: false, responseStats: new TestInjections.ResponseStats());

                            string query = "SELECT DISTINCT VALUE c.key FROM c WHERE c.key = 5";
                            List <CosmosElement> queryResults = await QueryTestsBase.RunQueryCombinationsAsync(
                                container,
                                query,
                                feedOptions,
                                QueryDrainingMode.HoldState | QueryDrainingMode.CosmosElementContinuationToken);

                            Assert.IsTrue(feedOptions.TestSettings.Stats.PipelineType.HasValue);
                            Assert.AreEqual(TestInjections.PipelineType.Specialized, feedOptions.TestSettings.Stats.PipelineType.Value);

                            Assert.AreEqual(
                                1,
                                queryResults.Count,
                                $"query: {query} failed with {nameof(maxDegreeOfParallelism)}: {maxDegreeOfParallelism}, {nameof(maxItemCount)}: {maxItemCount}");
                        }
                    }
                }
            }
        }
Beispiel #17
0
        /// <summary>
        /// Reads the next token from the reader.
        /// </summary>
        /// <returns>True if a token was read, else false.</returns>
        public override bool Read()
        {
            bool read = this.jsonReader.Read();

            if (!read)
            {
                this.SetToken(JsonToken.None);
                return(false);
            }

            JsonTokenType jsonTokenType = this.jsonReader.CurrentTokenType;
            JsonToken     newtonsoftToken;
            object        value;

            switch (jsonTokenType)
            {
            case JsonTokenType.BeginArray:
                newtonsoftToken = JsonToken.StartArray;
                value           = CosmosDBToNewtonsoftReader.Null;
                break;

            case JsonTokenType.EndArray:
                newtonsoftToken = JsonToken.EndArray;
                value           = CosmosDBToNewtonsoftReader.Null;
                break;

            case JsonTokenType.BeginObject:
                newtonsoftToken = JsonToken.StartObject;
                value           = CosmosDBToNewtonsoftReader.Null;
                break;

            case JsonTokenType.EndObject:
                newtonsoftToken = JsonToken.EndObject;
                value           = CosmosDBToNewtonsoftReader.Null;
                break;

            case JsonTokenType.String:
                newtonsoftToken = JsonToken.String;
                value           = this.jsonReader.GetStringValue();
                break;

            case JsonTokenType.Number:
                Number64 number64Value = this.jsonReader.GetNumberValue();
                if (number64Value.IsInteger)
                {
                    value           = Number64.ToLong(number64Value);
                    newtonsoftToken = JsonToken.Integer;
                }
                else
                {
                    value           = Number64.ToDouble(number64Value);
                    newtonsoftToken = JsonToken.Float;
                }
                break;

            case JsonTokenType.True:
                newtonsoftToken = JsonToken.Boolean;
                value           = CosmosDBToNewtonsoftReader.True;
                break;

            case JsonTokenType.False:
                newtonsoftToken = JsonToken.Boolean;
                value           = CosmosDBToNewtonsoftReader.False;
                break;

            case JsonTokenType.Null:
                newtonsoftToken = JsonToken.Null;
                value           = CosmosDBToNewtonsoftReader.Null;
                break;

            case JsonTokenType.FieldName:
                newtonsoftToken = JsonToken.PropertyName;
                value           = this.jsonReader.GetStringValue();
                break;

            case JsonTokenType.Int8:
                newtonsoftToken = JsonToken.Integer;
                value           = this.jsonReader.GetInt8Value();
                break;

            case JsonTokenType.Int16:
                newtonsoftToken = JsonToken.Integer;
                value           = this.jsonReader.GetInt16Value();
                break;

            case JsonTokenType.Int32:
                newtonsoftToken = JsonToken.Integer;
                value           = this.jsonReader.GetInt32Value();
                break;

            case JsonTokenType.Int64:
                newtonsoftToken = JsonToken.Integer;
                value           = this.jsonReader.GetInt64Value();
                break;

            case JsonTokenType.UInt32:
                newtonsoftToken = JsonToken.Integer;
                value           = this.jsonReader.GetUInt32Value();
                break;

            case JsonTokenType.Float32:
                newtonsoftToken = JsonToken.Float;
                value           = this.jsonReader.GetFloat32Value();
                break;

            case JsonTokenType.Float64:
                newtonsoftToken = JsonToken.Float;
                value           = this.jsonReader.GetFloat64Value();
                break;

            case JsonTokenType.Guid:
                newtonsoftToken = JsonToken.String;
                value           = this.jsonReader.GetGuidValue().ToString();
                break;

            case JsonTokenType.Binary:
                newtonsoftToken = JsonToken.Bytes;
                value           = this.jsonReader.GetBinaryValue().ToArray();
                break;

            default:
                throw new ArgumentException($"Unexpected jsonTokenType: {jsonTokenType}");
            }

            this.SetToken(newtonsoftToken, value);
            return(read);
        }
        /// <summary>
        /// Compares to objects and returns their partial sort relationship.
        /// </summary>
        /// <param name="element1">The first element to compare.</param>
        /// <param name="element2">The second element to compare.</param>
        /// <returns>
        /// Less than zero if obj1 comes before obj2 in the sort order.
        /// Zero if obj1 and obj2 are interchangeable in the sort order.
        /// Greater than zero if obj2 comes before obj1 in the sort order.
        /// </returns>
        public int Compare(CosmosElement element1, CosmosElement element2)
        {
            if (object.ReferenceEquals(element1, element2))
            {
                return(0);
            }

            if (object.ReferenceEquals(element1, MinValueItem.Singleton))
            {
                return(-1);
            }

            if (object.ReferenceEquals(element2, MinValueItem.Singleton))
            {
                return(1);
            }

            if (object.ReferenceEquals(element1, MaxValueItem.Singleton))
            {
                return(1);
            }

            if (object.ReferenceEquals(element2, MaxValueItem.Singleton))
            {
                return(-1);
            }

            if (element1 == Undefined)
            {
                return(-1);
            }

            if (element2 == Undefined)
            {
                return(1);
            }

            CosmosElementType type1 = element1.Type;

            int cmp = CompareTypes(element1, element2);

            if (cmp == 0)
            {
                // If they are the same type then you need to break the tie.
                switch (type1)
                {
                case CosmosElementType.Boolean:
                    cmp = Comparer <bool> .Default.Compare(
                        (element1 as CosmosBoolean).Value,
                        (element2 as CosmosBoolean).Value);

                    break;

                case CosmosElementType.Null:
                    // All nulls are the same.
                    cmp = 0;
                    break;

                case CosmosElementType.Number:
                    CosmosNumber number1 = element1 as CosmosNumber;
                    CosmosNumber number2 = element2 as CosmosNumber;
                    if (number1.NumberType == CosmosNumberType.Number64)
                    {
                        // Both are Number64, so compare as Number64
                        cmp = number1.Value.CompareTo(number2.Value);
                    }
                    else
                    {
                        // We have a number with precision
                        if (number2.Value.IsInteger)
                        {
                            // compare as longs, since all types have an implicit conversion with full fidelity.
                            long integer1 = Number64.ToLong(number1.Value);
                            long integer2 = Number64.ToLong(number2.Value);
                            cmp = Comparer <long> .Default.Compare(integer1, integer2);
                        }
                        else
                        {
                            // compare as doubles, since all types have an implicit conversion with full fidelity.
                            double double1 = Number64.ToDouble(number1.Value);
                            double double2 = Number64.ToDouble(number2.Value);
                            cmp = Comparer <double> .Default.Compare(double1, double2);
                        }
                    }

                    break;

                case CosmosElementType.String:
                    CosmosString string1 = element1 as CosmosString;
                    CosmosString string2 = element2 as CosmosString;
                    cmp = string.CompareOrdinal(
                        string1.Value,
                        string2.Value);
                    break;

                case CosmosElementType.Guid:
                    CosmosGuid guid1 = element1 as CosmosGuid;
                    CosmosGuid guid2 = element2 as CosmosGuid;
                    cmp = guid1.Value.CompareTo(guid2.Value);
                    break;

                case CosmosElementType.Binary:
                    CosmosBinary binary1 = element1 as CosmosBinary;
                    CosmosBinary binary2 = element2 as CosmosBinary;
                    cmp = ItemComparer.CompareTo(binary1, binary2);
                    break;

                case CosmosElementType.Array:
                case CosmosElementType.Object:
                {
                    UInt128 hash1 = DistinctHash.GetHash(element1);
                    UInt128 hash2 = DistinctHash.GetHash(element2);
                    return(hash1.CompareTo(hash2));
                }

                default:
                    throw new ArgumentException($"Unknown: {nameof(CosmosElementType)}: {type1}");
                }
            }

            return(cmp);
        }