From ea269c99b54a2ac2a4394edbcb50b2ed0cb6c0b0 Mon Sep 17 00:00:00 2001 From: Aditya Kotalwar <94020786+akotalwar@users.noreply.github.com> Date: Thu, 14 Dec 2023 10:41:39 -0800 Subject: [PATCH] [Internal] Query: Adds ClientQL Compatibility Level support on client (#4177) * Added ability to accept the AllowOptimisticDirectExecution flag from the backend and use that flag to decide if the Ode pipeline should be used or not. * Added comment and removed extra spacing * Added test coverage * Added exception handling logic * Resolved comments * Added null check for key parameter * Removed changes to common test infra * Removed all changes from QueryPartitionProviderTestInstance * Remove changes pt2 * Removed the dictionary in QueryPartitionProvider and added a bool instead * Updated GetClientDisableOptimisticDirectExecution() * Fixed comments * Revert QueryIterator.cs * Undoing changes to settings.json * Undoing changes to QueryIterator.cs * Updated error message * Made functions static * Cast to bool instead of recasting in GetClientDisableOptimisticDirectExecution() * Added clientQLCompatibilityLevel support on client * Updated assert * Updated client tests to use Data Contract serializer and deserializer * Added support to obtain the distribution plan payload on the client * Added binary support * Removed CheckCompatibilityLevelFlagInQuerySpec() * Renamed ParseElementsFromRestStream() * Updated test response * Switched to using binary json navigator * Using local variable before type check * Updated name to DistributionPlanSpec * Added support to test multiple distribution plan samples * Removed binary sample * Updated binary test * Added ignore flag * Fixed merge conflicts 2.0 * Resolved comments * Updated function name * Removed an unnecessary assert * Fixed comment * Improved debug assert message * Added checks to confirm that resourceType is document before getting distributionPlan * Removed changes to resourceManagement.yml --- .../src/Query/Core/DistributionPlanSpec.cs | 31 + .../AggregateQueryPipelineStage.Client.cs | 1 + .../AggregateQueryPipelineStage.Compute.cs | 2 + ...OrderByCrossPartitionQueryPipelineStage.cs | 8 + ...arallelCrossPartitionQueryPipelineStage.cs | 1 + .../DCount/DCountQueryPipelineStage.Client.cs | 1 + .../DCountQueryPipelineStage.Compute.cs | 2 + .../DistinctQueryPipelineStage.Client.cs | 2 + .../DistinctQueryPipelineStage.Compute.cs | 1 + .../GroupByQueryPipelineStage.Client.cs | 1 + .../GroupByQueryPipelineStage.Compute.cs | 2 + ...misticDirectExecutionQueryPipelineStage.cs | 10 +- .../Core/Pipeline/Pagination/QueryPage.cs | 4 + .../Skip/SkipQueryPipelineStage.Client.cs | 1 + .../Skip/SkipQueryPipelineStage.Compute.cs | 1 + .../SkipEmptyPageQueryPipelineStage.cs | 3 + .../Take/TakeQueryPipelineStage.Client.cs | 1 + .../Take/TakeQueryPipelineStage.Compute.cs | 1 + .../src/Query/Core/SqlQuerySpec.cs | 9 +- .../Query/v3Query/CosmosQueryClientCore.cs | 77 +- .../ReadFeedCrossFeedRangeAsyncEnumerator.cs | 6 +- .../ClientTests.cs | 126 +- .../Pagination/FlakyDocumentContainer.cs | 1 + .../Pagination/InMemoryContainer.cs | 1 + .../OrderByQueryResultTests.cs | 6 +- .../Binary/BinarySample.json | 10 + .../Text/AggregateEnumerable.json | 689 ++++++++++ .../Text/ArrayCreateScalar.json | 645 ++++++++++ .../DistributionPlans/Text/BinaryScalar.json | 659 ++++++++++ .../Text/Distinct-SelectEnumerable.json | 332 +++++ .../Text/GroupByEnumerable.json | 1137 +++++++++++++++++ .../DistributionPlans/Text/LiteralScalar.json | 359 ++++++ .../Text/SelectManyEnumerable.json | 396 ++++++ .../Text/SimpleEnumerable.json | 121 ++ .../Text/SystemFunctionCallScalar.json | 354 +++++ .../Text/TakeEnumerable.json | 337 +++++ ...misticDirectExecutionQueryBaselineTests.cs | 76 +- .../AggressivePrefetchPipelineTests.cs | 1 + .../Query/Pipeline/MockQueryPipelineStage.cs | 1 + ...ByCrossPartitionQueryPipelineStageTests.cs | 1 + .../SkipEmptyPageQueryPipelineStageTests.cs | 4 +- 41 files changed, 5327 insertions(+), 94 deletions(-) create mode 100644 Microsoft.Azure.Cosmos/src/Query/Core/DistributionPlanSpec.cs create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Binary/BinarySample.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/AggregateEnumerable.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/ArrayCreateScalar.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/BinaryScalar.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/Distinct-SelectEnumerable.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/GroupByEnumerable.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/LiteralScalar.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SelectManyEnumerable.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SimpleEnumerable.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SystemFunctionCallScalar.json create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/TakeEnumerable.json diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/DistributionPlanSpec.cs b/Microsoft.Azure.Cosmos/src/Query/Core/DistributionPlanSpec.cs new file mode 100644 index 0000000000..119e2b4b02 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Query/Core/DistributionPlanSpec.cs @@ -0,0 +1,31 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// ------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Query.Core +{ + using System; + + internal sealed class DistributionPlanSpec + { + public DistributionPlanSpec(string backendDistributionPlan, string clientDistributionPlan) + { + if (string.IsNullOrEmpty(backendDistributionPlan)) + { + throw new ArgumentException("Backend distribution plan cannot be null or empty."); + } + + if (string.IsNullOrEmpty(clientDistributionPlan)) + { + throw new ArgumentException("Client distribution plan cannot be null or empty."); + } + + this.BackendDistributionPlan = backendDistributionPlan; + this.ClientDistributionPlan = clientDistributionPlan; + } + + public string BackendDistributionPlan { get; } + + public string ClientDistributionPlan { get; } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Aggregate/AggregateQueryPipelineStage.Client.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Aggregate/AggregateQueryPipelineStage.Client.cs index aab5a723f8..ddaea9aaa5 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Aggregate/AggregateQueryPipelineStage.Client.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Aggregate/AggregateQueryPipelineStage.Client.cs @@ -126,6 +126,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: default, responseLengthInBytes: responseLengthBytes, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: default); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Aggregate/AggregateQueryPipelineStage.Compute.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Aggregate/AggregateQueryPipelineStage.Compute.cs index 4cd0de254e..8a34e69a8a 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Aggregate/AggregateQueryPipelineStage.Compute.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Aggregate/AggregateQueryPipelineStage.Compute.cs @@ -146,6 +146,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: queryState); @@ -169,6 +170,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: default, responseLengthInBytes: default, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: default); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/OrderBy/OrderByCrossPartitionQueryPipelineStage.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/OrderBy/OrderByCrossPartitionQueryPipelineStage.cs index 10c3b0ee5e..43f4176de3 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/OrderBy/OrderByCrossPartitionQueryPipelineStage.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/OrderBy/OrderByCrossPartitionQueryPipelineStage.cs @@ -115,6 +115,7 @@ private async ValueTask MoveNextAsync_Initialize_FromBeginningAsync( activityId: string.Empty, responseLengthInBytes: 0, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: this.state)); @@ -153,6 +154,7 @@ private async ValueTask MoveNextAsync_Initialize_FromBeginningAsync( activityId: string.IsNullOrEmpty(page.ActivityId) ? Guid.NewGuid().ToString() : page.ActivityId, responseLengthInBytes: page.ResponseLengthInBytes, cosmosQueryExecutionInfo: page.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: page.DisallowContinuationTokenMessage, additionalHeaders: page.AdditionalHeaders, state: null)); @@ -173,6 +175,7 @@ private async ValueTask MoveNextAsync_Initialize_FromBeginningAsync( activityId: page.ActivityId, responseLengthInBytes: page.ResponseLengthInBytes, cosmosQueryExecutionInfo: page.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: page.DisallowContinuationTokenMessage, additionalHeaders: page.AdditionalHeaders, state: this.state)); @@ -235,6 +238,7 @@ private async ValueTask MoveNextAsync_Initialize_FilterAsync( activityId: string.IsNullOrEmpty(page.ActivityId) ? Guid.NewGuid().ToString() : page.ActivityId, responseLengthInBytes: page.ResponseLengthInBytes, cosmosQueryExecutionInfo: page.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: page.DisallowContinuationTokenMessage, additionalHeaders: page.AdditionalHeaders, state: null)); @@ -278,6 +282,7 @@ private async ValueTask MoveNextAsync_Initialize_FilterAsync( activityId: page.ActivityId, responseLengthInBytes: page.ResponseLengthInBytes, cosmosQueryExecutionInfo: page.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: page.DisallowContinuationTokenMessage, additionalHeaders: page.AdditionalHeaders, state: InitializingQueryState)); @@ -426,6 +431,7 @@ private ValueTask MoveNextAsync_DrainPageAsync(ITrace trace) activityId: default, responseLengthInBytes: 0, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: currentEnumerator.Current.Result.Page.AdditionalHeaders, state: this.state)); @@ -481,6 +487,7 @@ private ValueTask MoveNextAsync_DrainPageAsync(ITrace trace) activityId: default, responseLengthInBytes: 0, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: currentEnumerator?.Current.Result.Page.AdditionalHeaders, state: this.state)); @@ -543,6 +550,7 @@ public ValueTask MoveNextAsync(ITrace trace) activityId: Guid.NewGuid().ToString(), responseLengthInBytes: 0, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: null)); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/Parallel/ParallelCrossPartitionQueryPipelineStage.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/Parallel/ParallelCrossPartitionQueryPipelineStage.cs index c9ccb31653..b84a36870e 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/Parallel/ParallelCrossPartitionQueryPipelineStage.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CrossPartition/Parallel/ParallelCrossPartitionQueryPipelineStage.cs @@ -122,6 +122,7 @@ public async ValueTask MoveNextAsync(ITrace trace) backendQueryPage.ActivityId, backendQueryPage.ResponseLengthInBytes, backendQueryPage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, backendQueryPage.DisallowContinuationTokenMessage, backendQueryPage.AdditionalHeaders, queryState); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/DCount/DCountQueryPipelineStage.Client.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/DCount/DCountQueryPipelineStage.Client.cs index 86a1a000fe..162408e6ff 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/DCount/DCountQueryPipelineStage.Client.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/DCount/DCountQueryPipelineStage.Client.cs @@ -107,6 +107,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: default, responseLengthInBytes: responseLengthBytes, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: additionalHeaders, state: default); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/DCount/DCountQueryPipelineStage.Compute.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/DCount/DCountQueryPipelineStage.Compute.cs index 9068017ee5..0970be1706 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/DCount/DCountQueryPipelineStage.Compute.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/DCount/DCountQueryPipelineStage.Compute.cs @@ -128,6 +128,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: queryState); @@ -151,6 +152,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: default, responseLengthInBytes: default, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: default); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Distinct/DistinctQueryPipelineStage.Client.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Distinct/DistinctQueryPipelineStage.Client.cs index fbde8890ee..c250193a60 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Distinct/DistinctQueryPipelineStage.Client.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Distinct/DistinctQueryPipelineStage.Client.cs @@ -173,6 +173,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: state); @@ -185,6 +186,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: ClientDistinctQueryPipelineStage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: null); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Distinct/DistinctQueryPipelineStage.Compute.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Distinct/DistinctQueryPipelineStage.Compute.cs index 571cfd9694..06921710c4 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Distinct/DistinctQueryPipelineStage.Compute.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Distinct/DistinctQueryPipelineStage.Compute.cs @@ -131,6 +131,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: ComputeDistinctQueryPipelineStage.UseTryGetContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: queryState); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/GroupBy/GroupByQueryPipelineStage.Client.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/GroupBy/GroupByQueryPipelineStage.Client.cs index dad99bb26b..5d82409a19 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/GroupBy/GroupByQueryPipelineStage.Client.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/GroupBy/GroupByQueryPipelineStage.Client.cs @@ -120,6 +120,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: default, responseLengthInBytes: responseLengthInBytes, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: ClientGroupByQueryPipelineStage.ContinuationTokenNotSupportedWithGroupBy, additionalHeaders: addtionalHeaders, state: default); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/GroupBy/GroupByQueryPipelineStage.Compute.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/GroupBy/GroupByQueryPipelineStage.Compute.cs index 7b1963c7b0..2183952a1d 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/GroupBy/GroupByQueryPipelineStage.Compute.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/GroupBy/GroupByQueryPipelineStage.Compute.cs @@ -142,6 +142,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: null, additionalHeaders: sourcePage.AdditionalHeaders, state: state); @@ -172,6 +173,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: default, responseLengthInBytes: default, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: state); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/OptimisticDirectExecution/OptimisticDirectExecutionQueryPipelineStage.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/OptimisticDirectExecution/OptimisticDirectExecutionQueryPipelineStage.cs index e62ecf41f0..c968c0b34f 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/OptimisticDirectExecution/OptimisticDirectExecutionQueryPipelineStage.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/OptimisticDirectExecution/OptimisticDirectExecutionQueryPipelineStage.cs @@ -47,7 +47,6 @@ private OptimisticDirectExecutionQueryPipelineStage(TryCatch> FallbackQueryPipelineStageFactory(CosmosElement continuationToken); @@ -165,6 +164,7 @@ public static TryCatch MonadicCreate( private sealed class OptimisticDirectExecutionQueryPipelineImpl : IQueryPipelineStage { + private const int ClientQLCompatibilityLevel = 1; private readonly QueryPartitionRangePageAsyncEnumerator queryPartitionRangePageAsyncEnumerator; private OptimisticDirectExecutionQueryPipelineImpl( @@ -230,6 +230,7 @@ public async ValueTask MoveNextAsync(ITrace trace) backendQueryPage.ActivityId, backendQueryPage.ResponseLengthInBytes, backendQueryPage.CosmosQueryExecutionInfo, + backendQueryPage.DistributionPlanSpec, disallowContinuationTokenMessage: null, backendQueryPage.AdditionalHeaders, queryState); @@ -268,10 +269,15 @@ public static TryCatch MonadicCreate( return TryCatch.FromException(monadicExtractState.Exception); } + SqlQuerySpec updatedSqlQuerySpec = new SqlQuerySpec(sqlQuerySpec.QueryText, sqlQuerySpec.Parameters) + { + ClientQLCompatibilityLevel = ClientQLCompatibilityLevel + }; + FeedRangeState feedRangeState = monadicExtractState.Result; QueryPartitionRangePageAsyncEnumerator partitionPageEnumerator = new QueryPartitionRangePageAsyncEnumerator( documentContainer, - sqlQuerySpec, + updatedSqlQuerySpec, feedRangeState, partitionKey, queryPaginationOptions, diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Pagination/QueryPage.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Pagination/QueryPage.cs index 1fea010222..eab1f61c79 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Pagination/QueryPage.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Pagination/QueryPage.cs @@ -27,6 +27,7 @@ public QueryPage( string activityId, long responseLengthInBytes, Lazy cosmosQueryExecutionInfo, + DistributionPlanSpec distributionPlanSpec, string disallowContinuationTokenMessage, IReadOnlyDictionary additionalHeaders, QueryState state) @@ -35,6 +36,7 @@ public QueryPage( this.Documents = documents ?? throw new ArgumentNullException(nameof(documents)); this.ResponseLengthInBytes = responseLengthInBytes < 0 ? throw new ArgumentOutOfRangeException(nameof(responseLengthInBytes)) : responseLengthInBytes; this.CosmosQueryExecutionInfo = cosmosQueryExecutionInfo; + this.DistributionPlanSpec = distributionPlanSpec; this.DisallowContinuationTokenMessage = disallowContinuationTokenMessage; } @@ -44,6 +46,8 @@ public QueryPage( public Lazy CosmosQueryExecutionInfo { get; } + public DistributionPlanSpec DistributionPlanSpec { get; } + public string DisallowContinuationTokenMessage { get; } protected override ImmutableHashSet DerivedClassBannedHeaders => QueryPage.BannedHeaders; diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Skip/SkipQueryPipelineStage.Client.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Skip/SkipQueryPipelineStage.Client.cs index 5a4c6a3bbe..7f80df9930 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Skip/SkipQueryPipelineStage.Client.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Skip/SkipQueryPipelineStage.Client.cs @@ -144,6 +144,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: state); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Skip/SkipQueryPipelineStage.Compute.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Skip/SkipQueryPipelineStage.Compute.cs index 29412a1b2b..a7cd0ddea2 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Skip/SkipQueryPipelineStage.Compute.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Skip/SkipQueryPipelineStage.Compute.cs @@ -125,6 +125,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: state); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/SkipEmptyPageQueryPipelineStage.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/SkipEmptyPageQueryPipelineStage.cs index 17c6aa4e90..95be4d4003 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/SkipEmptyPageQueryPipelineStage.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/SkipEmptyPageQueryPipelineStage.cs @@ -56,6 +56,7 @@ public async ValueTask MoveNextAsync(ITrace trace) activityId: Guid.Empty.ToString(), responseLengthInBytes: this.cumulativeResponseLengthInBytes, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: this.cumulativeAdditionalHeaders, state: default); @@ -92,6 +93,7 @@ public async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes + this.cumulativeResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: default); @@ -117,6 +119,7 @@ public async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes + this.cumulativeResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: sourcePage.State); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Take/TakeQueryPipelineStage.Client.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Take/TakeQueryPipelineStage.Client.cs index b67a8c3a47..2d403ae45a 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Take/TakeQueryPipelineStage.Client.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Take/TakeQueryPipelineStage.Client.cs @@ -231,6 +231,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: state); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Take/TakeQueryPipelineStage.Compute.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Take/TakeQueryPipelineStage.Compute.cs index f897a559a9..7e1e8d6f62 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Take/TakeQueryPipelineStage.Compute.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/Take/TakeQueryPipelineStage.Compute.cs @@ -148,6 +148,7 @@ public override async ValueTask MoveNextAsync(ITrace trace) activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, + distributionPlanSpec: default, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, additionalHeaders: sourcePage.AdditionalHeaders, state: queryState); diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/SqlQuerySpec.cs b/Microsoft.Azure.Cosmos/src/Query/Core/SqlQuerySpec.cs index d03eb25629..67a684965b 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/SqlQuerySpec.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/SqlQuerySpec.cs @@ -14,7 +14,7 @@ namespace Microsoft.Azure.Cosmos.Query.Core internal sealed class SqlQuerySpec { private SqlParameterCollection parameters; - + /// /// Initializes a new instance of the class for the Azure Cosmos DB service. /// @@ -52,6 +52,13 @@ public SqlQuerySpec(string queryText, SqlParameterCollection parameters) [DataMember(Name = "query")] public string QueryText { get; set; } + /// + /// Gets or sets the ClientQL Compatibility Level supported by the client. + /// + /// The integer value representing the compatibility of the client. + [DataMember(Name = "clientQLCompatibilityLevel", EmitDefaultValue = false)] + public int? ClientQLCompatibilityLevel { get; set; } + /// /// Gets or sets the instance, which represents the collection of Azure Cosmos DB query parameters. /// diff --git a/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs b/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs index 78fe2c985d..a805786ca6 100644 --- a/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs +++ b/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs @@ -6,9 +6,11 @@ namespace Microsoft.Azure.Cosmos { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; + using System.Text; using System.Threading; using System.Threading.Tasks; @@ -329,9 +331,26 @@ private static TryCatch GetCosmosElementResponse( } long responseLengthBytes = memoryStream.Length; - CosmosArray documents = CosmosQueryClientCore.ParseElementsFromRestStream( + CosmosQueryClientCore.ParseRestStream( memoryStream, - resourceType); + resourceType, + out CosmosArray documents, + out CosmosObject distributionPlan); + + DistributionPlanSpec distributionPlanSpec = null; + + if (distributionPlan != null) + { + bool backendPlan = distributionPlan.TryGetValue("backendDistributionPlan", out CosmosElement backendDistributionPlan); + bool clientPlan = distributionPlan.TryGetValue("clientDistributionPlan", out CosmosElement clientDistributionPlan); + + Debug.Assert(clientPlan == backendPlan, "Response Body Contract was violated. Out of the backend and client plans, only one is present in the distribution plan."); + + if (backendPlan && clientPlan) + { + distributionPlanSpec = new DistributionPlanSpec(backendDistributionPlan.ToString(), clientDistributionPlan.ToString()); + } + } QueryState queryState; if (cosmosResponseMessage.Headers.ContinuationToken != null) @@ -366,6 +385,7 @@ private static TryCatch GetCosmosElementResponse( cosmosResponseMessage.Headers.ActivityId, responseLengthBytes, cosmosQueryExecutionInfo, + distributionPlanSpec, disallowContinuationTokenMessage: null, additionalHeaders, queryState); @@ -438,10 +458,13 @@ private Task GetRoutingMapProviderAsync() /// /// The memory stream response for the query REST response Azure Cosmos /// The resource type - /// An array of CosmosElements parsed from the response body. - public static CosmosArray ParseElementsFromRestStream( + /// An array of CosmosElements parsed from the response body + /// An object containing the distribution plan for the client + public static void ParseRestStream( Stream stream, - ResourceType resourceType) + ResourceType resourceType, + out CosmosArray documents, + out CosmosObject distributionPlan) { if (!(stream is MemoryStream memoryStream)) { @@ -465,7 +488,25 @@ public static CosmosArray ParseElementsFromRestStream( // "_attachments": "attachments\/", // "_ts": 1501107886 // }], - // "_count": 1 + // "_count": 1, + // "_distributionPlan": { + // "backendDistributionPlan": { + // "query": "\nSELECT Count(r.a) AS count_a\nFROM r", + // "obfuscatedQuery": "{\"query\":\"SELECT Count(r.a) AS p1\\nFROM r\",\"parameters\":[]}", + // "shape": "{\"Select\":{\"Type\":\"List\",\"AggCount\":1},\"From\":{\"Expr\":\"Aliased\"}}", + // "signature":-4885972563975185329, + // "shapeSignature":-6171928203673877984, + // "queryIL": {...}, + // "noSpatial": true, + // "language": "QueryIL" + // }, + // "coordinatorDistributionPlan": { + // "clientQL": { + // "Kind": "Input", + // "Name": "root" + // } + // } + // } // } // You want to create a CosmosElement for each document in "Documents". @@ -493,7 +534,29 @@ public static CosmosArray ParseElementsFromRestStream( throw new InvalidOperationException($"QueryResponse did not have an array of : {resourceName}"); } - return cosmosArray; + documents = cosmosArray; + + if (resourceType == ResourceType.Document && jsonNavigator.TryGetObjectProperty(jsonNavigator.GetRootNode(), "_distributionPlan", out ObjectProperty distributionPlanObjectProperty)) + { + switch (CosmosElement.Dispatch(jsonNavigator, distributionPlanObjectProperty.ValueNode)) + { + case CosmosString binaryDistributionPlan: + byte[] binaryJson = Convert.FromBase64String(binaryDistributionPlan.Value); + IJsonNavigator binaryJsonNavigator = JsonNavigator.Create(binaryJson); + IJsonNavigatorNode binaryJsonNavigatorNode = binaryJsonNavigator.GetRootNode(); + distributionPlan = CosmosObject.Create(binaryJsonNavigator, binaryJsonNavigatorNode); + break; + case CosmosObject textDistributionPlan: + distributionPlan = textDistributionPlan; + break; + default: + throw new InvalidOperationException($"Response Body Contract was violated. QueryResponse did not have property: {resourceName}"); + } + } + else + { + distributionPlan = null; + } } } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/ReadFeed/ReadFeedCrossFeedRangeAsyncEnumerator.cs b/Microsoft.Azure.Cosmos/src/ReadFeed/ReadFeedCrossFeedRangeAsyncEnumerator.cs index 95fb8b23cf..996b1eaf78 100644 --- a/Microsoft.Azure.Cosmos/src/ReadFeed/ReadFeedCrossFeedRangeAsyncEnumerator.cs +++ b/Microsoft.Azure.Cosmos/src/ReadFeed/ReadFeedCrossFeedRangeAsyncEnumerator.cs @@ -43,9 +43,11 @@ public async ValueTask MoveNextAsync() CrossFeedRangeState crossFeedRangeState = innerReadFeedPage.State; ReadFeedCrossFeedRangeState? state = crossFeedRangeState != null ? new ReadFeedCrossFeedRangeState(crossFeedRangeState.Value) : (ReadFeedCrossFeedRangeState?)null; - CosmosArray documents = CosmosQueryClientCore.ParseElementsFromRestStream( + CosmosQueryClientCore.ParseRestStream( innerReadFeedPage.Page.Content, - Documents.ResourceType.Document); + Documents.ResourceType.Document, + out CosmosArray documents, + out CosmosObject distributionPlan); ReadFeedPage page = new ReadFeedPage( documents, innerReadFeedPage.Page.RequestCharge, diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTests.cs index 9bbbb980e3..cbe1343106 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ClientTests.cs @@ -13,6 +13,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using System.Net.Http; using System.Net.Security; using System.Reflection; + using System.Runtime.Serialization.Json; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; @@ -511,157 +512,105 @@ public void SqlQuerySpecSerializationTest() { Action verifyJsonSerialization = (expectedText, query) => { - string actualText = JsonConvert.SerializeObject(query); + string actualText = SerializeQuerySpecToJson(query); + SqlQuerySpec querySpec = DeserializeJsonToQuerySpec(actualText); + string otherText = SerializeQuerySpecToJson(querySpec); Assert.AreEqual(expectedText, actualText); - - SqlQuerySpec otherQuery = JsonConvert.DeserializeObject(actualText); - string otherText = JsonConvert.SerializeObject(otherQuery); Assert.AreEqual(expectedText, otherText); }; Action verifyJsonSerializationText = (text) => { - SqlQuerySpec query = JsonConvert.DeserializeObject(text); - string otherText = JsonConvert.SerializeObject(query); + + SqlQuerySpec querySpec = DeserializeJsonToQuerySpec(text); + string otherText = SerializeQuerySpecToJson(querySpec); Assert.AreEqual(text, otherText); }; // Verify serialization - verifyJsonSerialization("{\"query\":null}", new SqlQuerySpec()); - verifyJsonSerialization("{\"query\":\"SELECT 1\"}", new SqlQuerySpec("SELECT 1")); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[{\"name\":null,\"value\":null}]}", + verifyJsonSerialization("{\"parameters\":[],\"query\":null}", new SqlQuerySpec()); + verifyJsonSerialization("{\"parameters\":[],\"query\":\"SELECT 1\"}", new SqlQuerySpec("SELECT 1")); + verifyJsonSerialization("{\"parameters\":[{\"name\":null,\"value\":null}],\"query\":\"SELECT 1\"}", new SqlQuerySpec() { QueryText = "SELECT 1", Parameters = new SqlParameterCollection() { new SqlParameter() } }); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[" + + verifyJsonSerialization("{\"parameters\":[" + "{\"name\":\"@p1\",\"value\":5}" + - "]}", + "],\"query\":\"SELECT 1\"}", new SqlQuerySpec() { QueryText = "SELECT 1", Parameters = new SqlParameterCollection() { new SqlParameter("@p1", 5) } }); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[" + + verifyJsonSerialization("{\"parameters\":[" + "{\"name\":\"@p1\",\"value\":5}," + "{\"name\":\"@p1\",\"value\":true}" + - "]}", + "],\"query\":\"SELECT 1\"}", new SqlQuerySpec() { QueryText = "SELECT 1", Parameters = new SqlParameterCollection() { new SqlParameter("@p1", 5), new SqlParameter("@p1", true) } }); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[" + + verifyJsonSerialization("{\"parameters\":[" + "{\"name\":\"@p1\",\"value\":\"abc\"}" + - "]}", + "],\"query\":\"SELECT 1\"}", new SqlQuerySpec() { QueryText = "SELECT 1", Parameters = new SqlParameterCollection() { new SqlParameter("@p1", "abc") } }); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[" + + verifyJsonSerialization("{\"parameters\":[" + "{\"name\":\"@p1\",\"value\":[1,2,3]}" + - "]}", + "],\"query\":\"SELECT 1\"}", new SqlQuerySpec() { QueryText = "SELECT 1", Parameters = new SqlParameterCollection() { new SqlParameter("@p1", new int[] { 1, 2, 3 }) } }); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[" + - "{\"name\":\"@p1\",\"value\":{\"a\":[1,2,3]}}" + - "]}", - new SqlQuerySpec() - { - QueryText = "SELECT 1", - Parameters = new SqlParameterCollection() { new SqlParameter("@p1", JObject.Parse("{\"a\":[1,2,3]}")) } - }); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[" + - "{\"name\":\"@p1\",\"value\":{\"a\":[1,2,3]}}" + - "]}", - new SqlQuerySpec() - { - QueryText = "SELECT 1", - Parameters = new SqlParameterCollection() { new SqlParameter("@p1", new JRaw("{\"a\":[1,2,3]}")) } - }); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[" + - "{\"name\":\"@p1\",\"value\":{\"a\":[1,2,3]}}" + - "]}", - new SqlQuerySpec() - { - QueryText = "SELECT 1", - Parameters = new SqlParameterCollection() { new SqlParameter("@p1", new JRaw("{\"a\":[1,2,3]}")) }, - }); - verifyJsonSerialization("{\"query\":\"SELECT 1\",\"parameters\":[" + - "{\"name\":\"@p1\",\"value\":{\"a\":[1,2,3]}}" + - "]}", - new SqlQuerySpec() - { - QueryText = "SELECT 1", - Parameters = new SqlParameterCollection() { new SqlParameter("@p1", new JRaw("{\"a\":[1,2,3]}")) }, - }); // Verify roundtrips - verifyJsonSerializationText("{\"query\":null}"); - verifyJsonSerializationText("{\"query\":\"SELECT 1\"}"); + verifyJsonSerializationText("{\"parameters\":[],\"query\":null}"); + verifyJsonSerializationText("{\"parameters\":[],\"query\":\"SELECT 1\"}"); verifyJsonSerializationText( "{" + - "\"query\":\"SELECT 1\"," + "\"parameters\":[" + "{\"name\":null,\"value\":null}" + - "]" + + "]," + "\"query\":\"SELECT 1\"" + "}"); verifyJsonSerializationText( "{" + - "\"query\":\"SELECT 1\"," + "\"parameters\":[" + "{\"name\":\"@p1\",\"value\":null}" + - "]" + + "]," + "\"query\":\"SELECT 1\"" + "}"); verifyJsonSerializationText( "{" + - "\"query\":\"SELECT 1\"," + "\"parameters\":[" + "{\"name\":\"@p1\",\"value\":true}" + - "]" + + "]," + "\"query\":\"SELECT 1\"" + "}"); verifyJsonSerializationText( "{" + - "\"query\":\"SELECT 1\"," + "\"parameters\":[" + "{\"name\":\"@p1\",\"value\":false}" + - "]" + + "]," + "\"query\":\"SELECT 1\"" + "}"); verifyJsonSerializationText( "{" + - "\"query\":\"SELECT 1\"," + "\"parameters\":[" + "{\"name\":\"@p1\",\"value\":123}" + - "]" + + "]," + "\"query\":\"SELECT 1\"" + "}"); verifyJsonSerializationText( "{" + - "\"query\":\"SELECT 1\"," + "\"parameters\":[" + "{\"name\":\"@p1\",\"value\":\"abc\"}" + - "]" + - "}"); - verifyJsonSerializationText( - "{" + - "\"query\":\"SELECT 1\"," + - "\"parameters\":[" + - "{\"name\":\"@p1\",\"value\":{\"a\":[1,2,\"abc\"]}}" + - "]" + - "}"); - verifyJsonSerializationText( - "{" + - "\"query\":\"SELECT 1\"," + - "\"parameters\":[" + - "{\"name\":\"@p1\",\"value\":{\"a\":[1,2,\"abc\"]}}" + - "]" + + "]," + "\"query\":\"SELECT 1\"" + "}"); } @@ -977,6 +926,29 @@ public static IReadOnlyList GetActiveConnections() return connections; } } + + private static string SerializeQuerySpecToJson(SqlQuerySpec querySpec) + { + string queryText; + using (MemoryStream stream = new MemoryStream()) + { + new DataContractJsonSerializer(typeof(SqlQuerySpec), new[] { typeof(object[]), typeof(int[]), typeof(SqlParameterCollection) }).WriteObject(stream, querySpec); + queryText = Encoding.UTF8.GetString(stream.ToArray()); + } + + return queryText; + } + + private static SqlQuerySpec DeserializeJsonToQuerySpec(string queryText) + { + SqlQuerySpec querySpec; + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(queryText))) + { + querySpec = (SqlQuerySpec)new DataContractJsonSerializer(typeof(SqlQuerySpec), new[] { typeof(object[]), typeof(int[]), typeof(SqlParameterCollection) }).ReadObject(stream); + } + + return querySpec; + } } internal static class StringHelper diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/FlakyDocumentContainer.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/FlakyDocumentContainer.cs index cc038ff4ed..132d575905 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/FlakyDocumentContainer.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/FlakyDocumentContainer.cs @@ -170,6 +170,7 @@ public async Task> MonadicQueryAsync( activityId: Guid.NewGuid().ToString(), responseLengthInBytes: "[]".Length, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: feedRangeState.State ?? StateForStartedButNoDocumentsReturned)); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs index 5c6e8961e7..7d17786159 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs @@ -649,6 +649,7 @@ public virtual Task> MonadicQueryAsync( activityId: Guid.NewGuid().ToString(), responseLengthInBytes: 1337, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: additionalHeaders.ToImmutable(), state: queryState))); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/ContinuationTokens/OrderByQueryResultTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/ContinuationTokens/OrderByQueryResultTests.cs index 7207f897be..3ca62e4057 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/ContinuationTokens/OrderByQueryResultTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/ContinuationTokens/OrderByQueryResultTests.cs @@ -29,9 +29,11 @@ public void TestOrderByUndefined() MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(testResponse)); - CosmosArray documents = CosmosQueryClientCore.ParseElementsFromRestStream( + CosmosQueryClientCore.ParseRestStream( memoryStream, - Documents.ResourceType.Document); + Documents.ResourceType.Document, + out CosmosArray documents, + out CosmosObject distributionPlan); List orderByQueryResults = documents.Select(x => new OrderByQueryResult(x)).ToList(); Assert.AreEqual(14, orderByQueryResults.Count); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Binary/BinarySample.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Binary/BinarySample.json new file mode 100644 index 0000000000..6a42acce6b --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Binary/BinarySample.json @@ -0,0 +1,10 @@ +{ + "_rid": "AgAAAP-tzwk=", + "Documents": [ + { + "count_a": 30 + } + ], + "_count": 1, + "_distributionPlan": "gOsBBJdiYWNrZW5kRGlzdHJpYnV0aW9uUGxhbussA4VxdWVyeaQKU0VMRUNUIENvdW50KHIuYSkgQVMgY291bnRfYQpGUk9NIHKPb2JmdXNjYXRlZFF1ZXJ5u3sicXVlcnkiOiJTRUxFQ1QgQ291bnQoci5hKSBBUyBwMVxuRlJPTSByIiwicGFyYW1ldGVycyI6W119hXNoYXBlwEF7IlNlbGVjdCI6eyJUeXBlIjoiTGlzdCIsIkFnZ0NvdW50IjoxfSwiRnJvbSI6eyJFeHByIjoiQWxpYXNlZCJ9fYlzaWduYXR1cmXLT1z0DdeJMbyOc2hhcGVTaWduYXR1cmXLIMLNwP\/nWKqHcXVlcnlJTOmKRXhwcmVzc2lvbusOAoRLaW5kiUFnZ3JlZ2F0ZTfqQsQhAYRFbnVtiEl0ZW1UeXBl6i\/EIQGEQmFzZYxCYXNlVHlwZUtpbmSGTnVtYmVykUV4Y2x1ZGVzVW5kZWZpbmVk0sQmAephxCEBh0J1aWx0aW6JU2lnbmF0dXJl6jfEOwHqFcQhAcRJAcROAYdWYXJpYW50xGIB0YpSZXN1bHRUeXBl6hDEIQHESQHETgHEWwHEYgHSjE9wZXJhdG9yS2luZIVDb3VudJBTb3VyY2VFeHByZXNzaW9u60ABxCEBhlNlbGVjdDfqG8QhAcQ2AcQ7AeoQxCEBxEkBxE4BxJ8BxGIB0YhEZWxlZ2F0ZerexCEBkFNjYWxhckV4cHJlc3Npb2436hDEIQHESQHETgHEnwHEYgHRkERlY2xhcmVkVmFyaWFibGXqITaCdjCIVW5pcXVlSWQAN+oQxCEBxEkBxE4BxJ8BxGIB0sQTAep+xCEBi1Byb3BlcnR5UmVmN+oQxCEBxEkBxE4BxJ8BxGIB0cQTAepIxCEBi1ZhcmlhYmxlUmVmN+oQxCEBxEkBxE4BxJ8BxGIB0ohWYXJpYWJsZeobNoJ2MMRgAgA36hDEIQHESQHETgHEnwHEYgHSjFByb3BlcnR5TmFtZYFhxNsB6irEIQGFSW5wdXQ36hvEIQHENgHEOwHqEMQhAcRJAcROAcSfAcRiAdI2gXKJbm9TcGF0aWFs0ohsYW5ndWFnZYdRdWVyeUlMlmNsaWVudERpc3RyaWJ1dGlvblBsYW7piGNsaWVudFFM6pfEIQHE8gHESQLqCDaCdjDEYAICxBMB6lHEIQGMT2JqZWN0Q3JlYXRlik9iamVjdEtpbmSGT2JqZWN0ilByb3BlcnRpZXPh6iE2h2NvdW50X2HEEwHqE8QhAcSsAsTLAuoINoJ2MMRgAgLE2wHqKcQhAcQmAcQmAeoNxCEBxH0BxMgBg1N1bcTbAeoMxCEBxAgDNoRyb290" +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/AggregateEnumerable.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/AggregateEnumerable.json new file mode 100644 index 0000000000..5dc3fd15c6 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/AggregateEnumerable.json @@ -0,0 +1,689 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [ + {} + ], + "_count": 1, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT max(r.a+r.b) FROM r", + "obfuscatedQuery": "{\"query\":\"SELECT max((r.a + r.b))\\nFROM r\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"AggCount\":1},\"From\":{\"Expr\":\"Aliased\"}}", + "signature": 1617577102403904921, + "shapeSignature": -2200556368766744533, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + } + }, + "Index": 0 + } + ] + }, + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + } + }, + "Index": 1 + } + ] + } + }, + "SourceExpression": { + "Kind": "Aggregate", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + }, + "Aggregate": { + "Kind": "Tuple", + "Signature": { + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": false + } + ] + }, + "ResultType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + }, + "Items": [ + { + "Kind": "Builtin", + "Signature": { + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": false + }, + "ResultType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "OperatorKind": "Max" + }, + { + "Kind": "Builtin", + "Signature": { + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": false + }, + "ResultType": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + }, + "OperatorKind": "Count" + } + ] + }, + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expression": { + "Kind": "TupleCreate", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Items": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + }, + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ] + } + }, + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": false + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": false + }, + "OperatorKind": "Add", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + }, + "RightExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "b" + } + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 4, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 4, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "r" + } + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 2 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "$1", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 2 + } + } + } + ] + }, + "SourceExpression": { + "Kind": "Aggregate", + "Aggregate": { + "Kind": "Builtin", + "OperatorKind": "Max" + }, + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 8 + }, + "Expression": { + "Kind": "Mux", + "ConditionExpression": { + "Kind": "BinaryOperator", + "OperatorKind": "And", + "LeftExpression": { + "Kind": "BinaryOperator", + "OperatorKind": "NotEqual", + "LeftExpression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 8 + } + }, + "Index": 1 + }, + "RightExpression": { + "Kind": "Literal", + "Literal": { + "Kind": "Number", + "Value": 0 + } + } + }, + "RightExpression": { + "Kind": "UnaryOperator", + "OperatorKind": "Not", + "Expression": { + "Kind": "SystemFunctionCall", + "FunctionKind": "Is_Defined", + "Arguments": [ + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 8 + } + }, + "Index": 0 + } + ] + } + } + }, + "LeftExpression": { + "Kind": "Literal", + "Literal": { + "Kind": "Array", + "Items": [] + } + }, + "RightExpression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 8 + } + }, + "Index": 0 + } + }, + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 7 + }, + "Expression": { + "Kind": "TupleCreate", + "Items": [ + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 7 + } + }, + "Index": 0 + }, + "Index": 0 + }, + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 7 + } + }, + "Index": 1 + } + ] + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/ArrayCreateScalar.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/ArrayCreateScalar.json new file mode 100644 index 0000000000..c72a4a964e --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/ArrayCreateScalar.json @@ -0,0 +1,645 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [], + "_count": 0, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT DISTINCT [r.a, r.b] as arr FROM r", + "obfuscatedQuery": "{\"query\":\"SELECT DISTINCT [r.a, r.b] AS p1\\nFROM r\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"Distinct\":true},\"From\":{\"Expr\":\"Aliased\"}}", + "signature": -4859180975618908982, + "shapeSignature": 1900106125401909581, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 0 + } + ] + }, + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 1 + } + ] + } + ] + } + }, + "SourceExpression": { + "Kind": "Distinct", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Expressions": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 0 + }, + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 1 + } + ], + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "TupleCreate", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Items": [ + { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + }, + { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "b" + } + ] + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "r" + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "arr", + "Expression": { + "Kind": "ArrayCreate", + "ArrayKind": "Array", + "Items": [ + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "Index": 0 + }, + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "Index": 1 + } + ] + } + } + ] + }, + "SourceExpression": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expressions": [ + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "Index": 0 + }, + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "Index": 1 + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6 + }, + "Expression": { + "Kind": "TupleCreate", + "Items": [ + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 6 + } + }, + "Index": 0 + }, + "Index": 0 + }, + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 6 + } + }, + "Index": 1 + }, + "Index": 0 + } + ] + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/BinaryScalar.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/BinaryScalar.json new file mode 100644 index 0000000000..1fb50c5439 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/BinaryScalar.json @@ -0,0 +1,659 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [], + "_count": 0, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT DISTINCT r.a AND r.b FROM r", + "obfuscatedQuery": "{\"query\":\"SELECT DISTINCT (r.a AND r.b)\\nFROM r\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"Distinct\":true},\"From\":{\"Expr\":\"Aliased\"}}", + "signature": 8670442764837589376, + "shapeSignature": -830497809479614178, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 0 + } + ] + }, + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 1 + } + ] + } + ] + } + }, + "SourceExpression": { + "Kind": "Distinct", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Expressions": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 0 + }, + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 1 + } + ], + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "TupleCreate", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Items": [ + { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + }, + { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "b" + } + ] + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "r" + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 1 + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 1 + } + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "$1", + "Expression": { + "Kind": "BinaryOperator", + "OperatorKind": "And", + "LeftExpression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "Index": 0 + }, + "RightExpression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "Index": 1 + } + } + } + ] + }, + "SourceExpression": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expressions": [ + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "Index": 0 + }, + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "Index": 1 + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6 + }, + "Expression": { + "Kind": "TupleCreate", + "Items": [ + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 6 + } + }, + "Index": 0 + }, + "Index": 0 + }, + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 6 + } + }, + "Index": 1 + }, + "Index": 0 + } + ] + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/Distinct-SelectEnumerable.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/Distinct-SelectEnumerable.json new file mode 100644 index 0000000000..8d7afcca65 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/Distinct-SelectEnumerable.json @@ -0,0 +1,332 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [], + "_count": 0, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT DISTINCT r.a FROM r", + "obfuscatedQuery": "{\"query\":\"SELECT DISTINCT r.a\\nFROM r\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"Distinct\":true},\"From\":{\"Expr\":\"Aliased\"}}", + "signature": 5623696622904809165, + "shapeSignature": -7071247513508949191, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ] + } + ] + } + }, + "SourceExpression": { + "Kind": "Distinct", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ], + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "r" + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "a", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + } + } + ] + }, + "SourceExpression": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6 + }, + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 6 + } + }, + "Index": 0 + }, + "Index": 0 + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/GroupByEnumerable.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/GroupByEnumerable.json new file mode 100644 index 0000000000..fb4e7ae38c --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/GroupByEnumerable.json @@ -0,0 +1,1137 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [], + "_count": 0, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT r.a, max(r.b) FROM r GROUP BY r.a", + "obfuscatedQuery": "{\"query\":\"SELECT r.a, max(r.b)\\nFROM r\\nGROUP BY r.a\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"AggCount\":1},\"From\":{\"Expr\":\"Aliased\"},\"GroupBy\":{\"ItemCount\":1}}", + "signature": 5885090021484876333, + "shapeSignature": 4401005608116703893, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 7, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + ] + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 7, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + ] + } + } + }, + "Index": 0 + } + ] + }, + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 7, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + ] + } + } + }, + "Index": 1 + }, + "Index": 0 + } + ] + }, + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + }, + "Expression": { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 7, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + ] + } + } + }, + "Index": 1 + }, + "Index": 1 + } + ] + } + }, + "SourceExpression": { + "Kind": "GroupBy", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + ] + } + }, + "Keys": [ + { + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + ], + "Aggregates": [ + { + "Kind": "Tuple", + "Signature": { + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "ResultType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + ] + } + }, + "Items": [ + { + "Kind": "Builtin", + "Signature": { + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "ResultType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "OperatorKind": "Max" + }, + { + "Kind": "Builtin", + "Signature": { + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "ResultType": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + }, + "OperatorKind": "Count" + } + ] + } + ], + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + ] + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + ] + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Expression": { + "Kind": "TupleCreate", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + ] + }, + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 0 + }, + { + "Kind": "TupleCreate", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Items": [ + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 1 + }, + { + "Kind": "TupleItemRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Variable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + } + }, + "Index": 1 + } + ] + } + ] + } + }, + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "TupleCreate", + "Type": { + "Kind": "Tuple", + "Types": [ + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + ] + }, + "Items": [ + { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + }, + { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "b" + } + ] + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 4, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 4, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "r" + } + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 2 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "a", + "Expression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 2 + } + }, + "Index": 0 + } + }, + { + "Name": "$1", + "Expression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 2 + } + }, + "Index": 1 + } + } + ] + }, + "SourceExpression": { + "Kind": "GroupBy", + "KeyCount": 1, + "Aggregates": [ + { + "Kind": "Builtin", + "OperatorKind": "Max" + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 9 + }, + "Expression": { + "Kind": "TupleCreate", + "Items": [ + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 9 + } + }, + "Index": 0 + }, + { + "Kind": "Mux", + "ConditionExpression": { + "Kind": "BinaryOperator", + "OperatorKind": "And", + "LeftExpression": { + "Kind": "BinaryOperator", + "OperatorKind": "NotEqual", + "LeftExpression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 9 + } + }, + "Index": 1 + }, + "Index": 1 + }, + "RightExpression": { + "Kind": "Literal", + "Literal": { + "Kind": "Number", + "Value": 0 + } + } + }, + "RightExpression": { + "Kind": "UnaryOperator", + "OperatorKind": "Not", + "Expression": { + "Kind": "SystemFunctionCall", + "FunctionKind": "Is_Defined", + "Arguments": [ + { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 9 + } + }, + "Index": 1 + }, + "Index": 0 + } + ] + } + } + }, + "LeftExpression": { + "Kind": "Literal", + "Literal": { + "Kind": "Array", + "Items": [] + } + }, + "RightExpression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "TupleItemRef", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 9 + } + }, + "Index": 1 + }, + "Index": 0 + } + } + ] + }, + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 8 + }, + "Expression": { + "Kind": "TupleCreate", + "Items": [ + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 8 + } + }, + "Index": 0 + }, + "Index": 0 + }, + { + "Kind": "TupleCreate", + "Items": [ + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 8 + } + }, + "Index": 1 + }, + "Index": 0 + }, + { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 8 + } + }, + "Index": 2 + } + ] + } + ] + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/LiteralScalar.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/LiteralScalar.json new file mode 100644 index 0000000000..999880ebdb --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/LiteralScalar.json @@ -0,0 +1,359 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [], + "_count": 0, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT DISTINCT r.a = 5 as EqualsFive FROM r", + "obfuscatedQuery": "{\"query\":\"SELECT DISTINCT (r.a = 5) AS p1__10\\nFROM r\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"Distinct\":true},\"From\":{\"Expr\":\"Aliased\"}}", + "signature": 8545592500936011639, + "shapeSignature": -767125698482361778, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ] + } + ] + } + }, + "SourceExpression": { + "Kind": "Distinct", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ], + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "r" + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 1 + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 1 + } + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "EqualsFive", + "Expression": { + "Kind": "BinaryOperator", + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + }, + "RightExpression": { + "Kind": "Literal", + "Literal": { + "Kind": "Number", + "Value": 5 + } + } + } + } + ] + }, + "SourceExpression": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6 + }, + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 6 + } + }, + "Index": 0 + }, + "Index": 0 + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SelectManyEnumerable.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SelectManyEnumerable.json new file mode 100644 index 0000000000..60bdcb8027 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SelectManyEnumerable.json @@ -0,0 +1,396 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [], + "_count": 0, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT (SELECT VALUE Count(1) FROM a2 IN c.a WHERE a2 = 435) as s\r\nFROM c\r\nGROUP BY c.a", + "obfuscatedQuery": "{\"query\":\"SELECT (SELECT VALUE Count(1)\\nFROM r1 IN c.a\\nWHERE (r1 = 440.01)) AS s\\nFROM c\\nGROUP BY c.a\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\"},\"From\":{\"Expr\":\"Aliased\"},\"GroupBy\":{\"ItemCount\":1}}", + "signature": -1004994291944242492, + "shapeSignature": 7117013218658174347, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 18, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "v0", + "UniqueId": 18, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ] + } + ] + } + }, + "SourceExpression": { + "Kind": "Distinct", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 7, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "v0", + "UniqueId": 7, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ], + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 15, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 15, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "c" + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 16 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "s", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 16 + } + } + } + ] + }, + "SourceExpression": { + "Kind": "SelectMany", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 7 + }, + "SelectorExpression": { + "Kind": "Aggregate", + "Aggregate": { + "Kind": "Builtin", + "OperatorKind": "Count" + }, + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v1", + "UniqueId": 9 + }, + "Expression": { + "Kind": "Literal", + "Literal": { + "Kind": "Number", + "Value": 1 + } + }, + "SourceExpression": { + "Kind": "Where", + "DeclaredVariable": { + "Name": "v1", + "UniqueId": 9 + }, + "Expression": { + "Kind": "BinaryOperator", + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v1", + "UniqueId": 9 + } + }, + "RightExpression": { + "Kind": "Literal", + "Literal": { + "Kind": "Number", + "Value": 435 + } + } + }, + "SourceExpression": { + "Kind": "ScalarAsEnumerable", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 7 + } + }, + "EnumerationKind": "ArrayItems" + } + } + } + }, + "SourceExpression": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 7 + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 7 + } + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 19 + }, + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 19 + } + }, + "Index": 0 + }, + "Index": 0 + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SimpleEnumerable.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SimpleEnumerable.json new file mode 100644 index 0000000000..b491479a58 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SimpleEnumerable.json @@ -0,0 +1,121 @@ +{ + "_rid": "AgAAALHVPPs=", + "Documents": [ + { + "count_a": 30 + } + ], + "_count": 1, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "\nSELECT Count(r.a) AS count_a\nFROM r", + "obfuscatedQuery": "{\"query\":\"SELECT Count(r.a) AS p1\\nFROM r\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"AggCount\":1},\"From\":{\"Expr\":\"Aliased\"}}", + "signature": -4885972563975185329, + "shapeSignature": -6171928203673877984, + "queryIL": { + "Expression": { + "Kind": "Aggregate", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + }, + "Aggregate": { + "Kind": "Builtin", + "Signature": { + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "ResultType": { + "Kind": "Base", + "BaseTypeKind": "Number", + "ExcludesUndefined": true + } + }, + "OperatorKind": "Count" + }, + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 4, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 4, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "r" + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Input", + "Name": "root" + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SystemFunctionCallScalar.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SystemFunctionCallScalar.json new file mode 100644 index 0000000000..f29698aaf4 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/SystemFunctionCallScalar.json @@ -0,0 +1,354 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [], + "_count": 0, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT DISTINCT IS_INTEGER(r.a) FROM r", + "obfuscatedQuery": "{\"query\":\"SELECT DISTINCT IS_INTEGER(r.a)\\nFROM r\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"Distinct\":true},\"From\":{\"Expr\":\"Aliased\"}}", + "signature": -4972642973329292581, + "shapeSignature": 4685047233331412499, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "v0", + "UniqueId": 5, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ] + } + ] + } + }, + "SourceExpression": { + "Kind": "Distinct", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "s0", + "UniqueId": 3, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ], + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 2, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "r" + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 1 + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 1 + } + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "$1", + "Expression": { + "Kind": "SystemFunctionCall", + "FunctionKind": "Is_Integer", + "Arguments": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + } + ] + } + } + ] + }, + "SourceExpression": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 3 + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 3 + } + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6 + }, + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 6 + } + }, + "Index": 0 + }, + "Index": 0 + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/TakeEnumerable.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/TakeEnumerable.json new file mode 100644 index 0000000000..4b1395e995 --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/DistributionPlans/Text/TakeEnumerable.json @@ -0,0 +1,337 @@ +{ + "_rid": "7+JyAOgQsps=", + "Documents": [], + "_count": 0, + "_distributionPlan": { + "backendDistributionPlan": { + "query": "SELECT DISTINCT c.a FROM c OFFSET 2 LIMIT 5", + "obfuscatedQuery": "{\"query\":\"SELECT DISTINCT c.a\\nFROM c\\nOFFSET 2 LIMIT 5\",\"parameters\":[]}", + "shape": "{\"Select\":{\"Type\":\"List\",\"Distinct\":true},\"From\":{\"Expr\":\"Aliased\"},\"OffsetLimit\":{\"Offset\":2,\"Limit\":5}}", + "signature": -4272373468412855685, + "shapeSignature": -4443273821025974173, + "queryIL": { + "Expression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expression": { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "ArrayCreate", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Array", + "ExcludesUndefined": true + }, + "ArrayKind": "Array", + "Items": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "v0", + "UniqueId": 6, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ] + } + ] + } + }, + "SourceExpression": { + "Kind": "Distinct", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 4, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Variable": { + "Name": "s0", + "UniqueId": 4, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + } + } + ], + "SourceExpression": { + "Kind": "Select", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "v0", + "UniqueId": 0, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "a" + } + }, + "SourceExpression": { + "Kind": "Where", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Delegate": { + "Kind": "ScalarExpression", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "DeclaredVariable": { + "Name": "r", + "UniqueId": 3, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Expression": { + "Kind": "BinaryOperator", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Boolean", + "ExcludesUndefined": false + }, + "OperatorKind": "Equal", + "LeftExpression": { + "Kind": "PropertyRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": false + }, + "Expression": { + "Kind": "VariableRef", + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + }, + "Variable": { + "Name": "r", + "UniqueId": 3, + "Type": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + } + }, + "PropertyName": "pk" + }, + "RightExpression": { + "Kind": "Literal", + "Type": { + "Kind": "Base", + "BaseTypeKind": "String", + "ExcludesUndefined": true + }, + "Literal": { + "Kind": "String", + "Value": "90850703-b087-4580-91ee-e4a3918c3e85" + } + } + } + }, + "SourceExpression": { + "Kind": "Input", + "Type": { + "Kind": "Enum", + "ItemType": { + "Kind": "Base", + "BaseTypeKind": "Variant", + "ExcludesUndefined": true + } + }, + "Name": "c" + } + } + } + } + } + }, + "noSpatial": true, + "language": "QueryIL" + }, + "clientDistributionPlan": { + "clientQL": { + "Kind": "Take", + "SkipValue": 2, + "TakeValue": 5, + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 4 + }, + "Expression": { + "Kind": "ObjectCreate", + "ObjectKind": "Object", + "Properties": [ + { + "Name": "a", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 4 + } + } + } + ] + }, + "SourceExpression": { + "Kind": "Distinct", + "DeclaredVariable": { + "Name": "s0", + "UniqueId": 4 + }, + "Expressions": [ + { + "Kind": "VariableRef", + "Variable": { + "Name": "s0", + "UniqueId": 4 + } + } + ], + "SourceExpression": { + "Kind": "Select", + "DeclaredVariable": { + "Name": "v0", + "UniqueId": 7 + }, + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "ArrayIndexer", + "Expression": { + "Kind": "VariableRef", + "Variable": { + "Name": "v0", + "UniqueId": 7 + } + }, + "Index": 0 + }, + "Index": 0 + }, + "SourceExpression": { + "Kind": "Input", + "Name": "root" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs index 8ec63b59ae..d236b73a56 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/OptimisticDirectExecutionQueryBaselineTests.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Net; + using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; @@ -31,6 +32,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Newtonsoft.Json; + using Newtonsoft.Json.Linq; [TestClass] public class OptimisticDirectExecutionQueryBaselineTests : BaselineTests @@ -579,6 +581,72 @@ private async Task ValidateErrorMessageWithModifiedOdeFlags(OptimisticDirectExec } } + [TestMethod] + public async Task TestTextDistributionPlanParsingFromStream() + { + string textPath = "../../../Query/DistributionPlans/Text"; + string[] filePaths = Directory.GetFiles(textPath); + + foreach (string filePath in filePaths) + { + string testResponse = File.ReadAllText(filePath); + JObject jsonObject = JObject.Parse(testResponse); + + string expectedBackendPlan = jsonObject["_distributionPlan"]["backendDistributionPlan"].ToString(); + expectedBackendPlan = RemoveJsonFormattingFromString(expectedBackendPlan); + + string expectedClientPlan = jsonObject["_distributionPlan"]["clientDistributionPlan"].ToString(); + expectedClientPlan = RemoveJsonFormattingFromString(expectedClientPlan); + + MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(testResponse)); + CosmosQueryClientCore.ParseRestStream( + memoryStream, + Documents.ResourceType.Document, + out CosmosArray documents, + out CosmosObject distributionPlan); + + if (distributionPlan.TryGetValue("backendDistributionPlan", out CosmosElement backendDistributionPlan) && + distributionPlan.TryGetValue("clientDistributionPlan", out CosmosElement clientDistributionPlan)) + { + Assert.AreEqual(expectedBackendPlan, RemoveJsonFormattingFromString(backendDistributionPlan.ToString())); + Assert.AreEqual(expectedClientPlan, RemoveJsonFormattingFromString(clientDistributionPlan.ToString())); + } + else + { + Assert.Fail(); + } + } + } + + [TestMethod] + public async Task TestBinaryDistributionPlanParsingFromStream() + { + string expectedBackendPlan = "{\"query\":\"\\nSELECT Count(r.a) AS count_a\\nFROM r\",\"obfuscatedQuery\":\"{\\\"query\\\":\\\"SELECT Count(r.a) AS p1\\\\nFROM r\\\",\\\"parameters\\\":[]}\",\"shape\":\"{\\\"Select\\\":{\\\"Type\\\":\\\"List\\\",\\\"AggCount\\\":1},\\\"From\\\":{\\\"Expr\\\":\\\"Aliased\\\"}}\",\"signature\":-4885972563975185329,\"shapeSignature\":-6171928203673877984,\"queryIL\":{\"Expression\":{\"Kind\":\"Aggregate\",\"Type\":{\"Kind\":\"Enum\",\"ItemType\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Number\",\"ExcludesUndefined\":true}},\"Aggregate\":{\"Kind\":\"Builtin\",\"Signature\":{\"ItemType\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Variant\",\"ExcludesUndefined\":false},\"ResultType\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Number\",\"ExcludesUndefined\":true}},\"OperatorKind\":\"Count\"},\"SourceExpression\":{\"Kind\":\"Select\",\"Type\":{\"Kind\":\"Enum\",\"ItemType\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Variant\",\"ExcludesUndefined\":false}},\"Delegate\":{\"Kind\":\"ScalarExpression\",\"Type\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Variant\",\"ExcludesUndefined\":false},\"DeclaredVariable\":{\"Name\":\"v0\",\"UniqueId\":0,\"Type\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Variant\",\"ExcludesUndefined\":true}},\"Expression\":{\"Kind\":\"PropertyRef\",\"Type\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Variant\",\"ExcludesUndefined\":false},\"Expression\":{\"Kind\":\"VariableRef\",\"Type\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Variant\",\"ExcludesUndefined\":true},\"Variable\":{\"Name\":\"v0\",\"UniqueId\":0,\"Type\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Variant\",\"ExcludesUndefined\":true}}},\"PropertyName\":\"a\"}},\"SourceExpression\":{\"Kind\":\"Input\",\"Type\":{\"Kind\":\"Enum\",\"ItemType\":{\"Kind\":\"Base\",\"BaseTypeKind\":\"Variant\",\"ExcludesUndefined\":true}},\"Name\":\"r\"}}}},\"noSpatial\":true,\"language\":\"QueryIL\"}"; + string expectedClientPlan = "{\"clientQL\":{\"Kind\":\"Select\",\"DeclaredVariable\":{\"Name\":\"v0\",\"UniqueId\":2},\"Expression\":{\"Kind\":\"ObjectCreate\",\"ObjectKind\":\"Object\",\"Properties\":[{\"Name\":\"count_a\",\"Expression\":{\"Kind\":\"VariableRef\",\"Variable\":{\"Name\":\"v0\",\"UniqueId\":2}}}]},\"SourceExpression\":{\"Kind\":\"Aggregate\",\"Aggregate\":{\"Kind\":\"Builtin\",\"OperatorKind\":\"Sum\"},\"SourceExpression\":{\"Kind\":\"Input\",\"Name\":\"root\"}}}}"; + + string textPath = "../../../Query/DistributionPlans/Binary"; + string[] filePaths = Directory.GetFiles(textPath); + string testResponse = File.ReadAllText(filePaths[0]); + + MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(testResponse)); + CosmosQueryClientCore.ParseRestStream( + memoryStream, + Documents.ResourceType.Document, + out CosmosArray documents, + out CosmosObject distributionPlan); + + if (distributionPlan.TryGetValue("backendDistributionPlan", out CosmosElement backendDistributionPlan) && + distributionPlan.TryGetValue("clientDistributionPlan", out CosmosElement clientDistributionPlan)) + { + Assert.IsTrue(backendDistributionPlan.ToString().Equals(expectedBackendPlan)); + Assert.IsTrue(clientDistributionPlan.ToString().Equals(expectedClientPlan)); + } + else + { + Assert.Fail(); + } + } + // Creates a gone exception after the first MoveNexyAsync() call. This allows for the pipeline to return some documents before failing private static async Task ExecuteGoneExceptionOnODEPipeline(bool isMultiPartition) { @@ -644,6 +712,11 @@ private static async Task TestHandlingOfFailedFallbackPipeline(bool isMult return false; } + private static string RemoveJsonFormattingFromString(string jsonString) + { + return jsonString.Replace(" ", string.Empty).Replace("\t", string.Empty).Replace("\n", string.Empty).Replace("\r", string.Empty); + } + private static async Task<(MergeTestUtil, IQueryPipelineStage)> CreateFallbackPipelineTestInfrastructure(int numItems, bool isFailedFallbackPipelineTest, bool isMultiPartition, QueryRequestOptions queryRequestOptions) { List documents = new List(); @@ -1012,6 +1085,7 @@ public override async Task> MonadicQueryAsync( activityId: Guid.NewGuid().ToString(), responseLengthInBytes: 1337, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: additionalHeaders.ToImmutable(), state: queryPage.Result.Result.State))); @@ -1033,7 +1107,6 @@ public MergeTestUtil(bool isFailedFallbackPipelineTest) this.IsFailedFallbackPipelineTest = isFailedFallbackPipelineTest; } -#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously public async Task ShouldReturnFailure() { this.MoveNextCounter++; @@ -1061,7 +1134,6 @@ public async Task ShouldReturnFailure() return null; } -#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/AggressivePrefetchPipelineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/AggressivePrefetchPipelineTests.cs index f49285c325..102e532477 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/AggressivePrefetchPipelineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/AggressivePrefetchPipelineTests.cs @@ -244,6 +244,7 @@ public override async Task> MonadicQueryAsync( activityId: "E7980B1F-436E-44DF-B7A5-655C56D38648", responseLengthInBytes: 48, cosmosQueryExecutionInfo: new Lazy(() => new CosmosQueryExecutionInfo(false, false)), + distributionPlanSpec: default, disallowContinuationTokenMessage: null, additionalHeaders: null, state: continuationToken); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/MockQueryPipelineStage.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/MockQueryPipelineStage.cs index bc0c912c82..282b025031 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/MockQueryPipelineStage.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/MockQueryPipelineStage.cs @@ -59,6 +59,7 @@ public override ValueTask MoveNextAsync(ITrace trace) activityId: Guid.NewGuid().ToString(), responseLengthInBytes: default, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: state); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/OrderByCrossPartitionQueryPipelineStageTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/OrderByCrossPartitionQueryPipelineStageTests.cs index 52062c8afb..f1042ee6fb 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/OrderByCrossPartitionQueryPipelineStageTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/OrderByCrossPartitionQueryPipelineStageTests.cs @@ -287,6 +287,7 @@ public async Task TestFormattedFiltersForTargetPartitionWithContinuationTokenAsy activityId: string.Empty, responseLengthInBytes: 0, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: default); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/SkipEmptyPageQueryPipelineStageTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/SkipEmptyPageQueryPipelineStageTests.cs index 7f0f3f93d9..1b88966a8c 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/SkipEmptyPageQueryPipelineStageTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/SkipEmptyPageQueryPipelineStageTests.cs @@ -129,16 +129,18 @@ public enum PageType { Empty, NonEmpty, Error }; activityId: Guid.NewGuid().ToString(), responseLengthInBytes: "[]".Length, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: new QueryState(CosmosString.Create("Empty")))); private static readonly TryCatch NonEmpty = TryCatch.FromResult(new QueryPage( - documents: new List { CosmosElement.Parse("42") }, + documents: new List { CosmosElement.Parse("42") }, requestCharge: 100, activityId: Guid.NewGuid().ToString(), responseLengthInBytes: "[42]".Length, cosmosQueryExecutionInfo: default, + distributionPlanSpec: default, disallowContinuationTokenMessage: default, additionalHeaders: default, state: new QueryState(CosmosString.Create("NonEmpty"))));