diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs index 8f35ff821a..47aa1c4490 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs @@ -188,7 +188,7 @@ private static async Task> TryCreateCoreContextAsy // If the query would go to gateway, but we have a partition key, // then try seeing if we can execute as a passthrough using client side only logic. // This is to short circuit the need to go to the gateway to get the query plan. - if (cosmosQueryContext.QueryClient.ByPassQueryParsing() + if (cosmosQueryContext.QueryClient.BypassQueryParsing() && inputParameters.PartitionKey.HasValue) { bool parsed; @@ -586,7 +586,7 @@ private static async Task GetPartitionedQueryExec CancellationToken cancellationToken) { PartitionedQueryExecutionInfo partitionedQueryExecutionInfo; - if (cosmosQueryContext.QueryClient.ByPassQueryParsing()) + if (cosmosQueryContext.QueryClient.BypassQueryParsing()) { // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop, so need to bypass in that case. // We are also now bypassing this for 32 bit host process running even on Windows as there are many 32 bit apps that will not work without this diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/CosmosQueryClient.cs b/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/CosmosQueryClient.cs index ac093cadce..3fa4cb90e7 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/CosmosQueryClient.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/QueryClient/CosmosQueryClient.cs @@ -98,7 +98,7 @@ public abstract Task ExecuteQueryPlanRequestAsync bool forceRefresh, ITrace trace); - public abstract bool ByPassQueryParsing(); + public abstract bool BypassQueryParsing(); public abstract Task ForceRefreshCollectionCacheAsync( string collectionLink, diff --git a/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs b/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs index daf47e151c..1c5a9ef21f 100644 --- a/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs +++ b/Microsoft.Azure.Cosmos/src/Query/v3Query/CosmosQueryClientCore.cs @@ -285,7 +285,7 @@ public override async Task> GetTargetPartitionKeyRangesA } } - public override bool ByPassQueryParsing() + public override bool BypassQueryParsing() { return CustomTypeExtensions.ByPassQueryParsing(); } diff --git a/Microsoft.Azure.Cosmos/src/SqlObjects/SqlPropertyName.cs b/Microsoft.Azure.Cosmos/src/SqlObjects/SqlPropertyName.cs index 059e799d99..e7f859ff18 100644 --- a/Microsoft.Azure.Cosmos/src/SqlObjects/SqlPropertyName.cs +++ b/Microsoft.Azure.Cosmos/src/SqlObjects/SqlPropertyName.cs @@ -68,12 +68,7 @@ sealed class SqlPropertyName : SqlObject private SqlPropertyName(string value) { - if (string.IsNullOrWhiteSpace(value)) - { - throw new ArgumentException($"{nameof(value)} must not be null, empty, or whitespace."); - } - - this.Value = value; + this.Value = value ?? throw new ArgumentNullException(nameof(value)); } public string Value { get; } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosGatewayTimeoutTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosGatewayTimeoutTests.cs index 8b4728c122..f50319f65f 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosGatewayTimeoutTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosGatewayTimeoutTests.cs @@ -163,7 +163,7 @@ public DisableServiceInterop( { } - public override bool ByPassQueryParsing() + public override bool BypassQueryParsing() { return true; } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/BypassQueryParsingTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/BypassQueryParsingTests.cs index a0c821c72d..4db276f4ce 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/BypassQueryParsingTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/BypassQueryParsingTests.cs @@ -1,5 +1,6 @@ namespace Microsoft.Azure.Cosmos.EmulatorTests.Query { + using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -14,9 +15,28 @@ public sealed class BypassQueryParsingTests : QueryTestsBase public async Task TestBypassQueryParsingWithNonePartitionKey() { int documentCount = 400; - QueryRequestOptions feedOptions = new QueryRequestOptions { PartitionKey = PartitionKey.None }; + string query = "SELECT VALUE r.numberField FROM r"; - IReadOnlyList expected = Enumerable.Range(0, documentCount).ToList(); + IReadOnlyList expectedOutput = Enumerable.Range(0, documentCount).Select(i => i.ToString()).ToList(); + + await this.ValidateQueryBypassWithNonePartitionKey(documentCount, query, expectedOutput); + } + + [TestMethod] + [TestCategory("Query")] + public async Task TestBypassQueryParsingWithNonePartitionKeyEmptyPropertyName() + { + int documentCount = 400; + + string query = @"SELECT VALUE { """" : r.numberField } FROM r"; + IReadOnlyList expectedOutput = Enumerable.Range(0, documentCount).Select(i => String.Format("{{\"\":{0}}}", i)).ToList(); + + await this.ValidateQueryBypassWithNonePartitionKey(documentCount, query, expectedOutput); + } + + private async Task ValidateQueryBypassWithNonePartitionKey(int documentCount, string query, IReadOnlyList expectedOutput) + { + QueryRequestOptions feedOptions = new QueryRequestOptions { PartitionKey = PartitionKey.None }; async Task ImplementationAsync(Container container, IReadOnlyList documents) { @@ -34,9 +54,9 @@ async Task ImplementationAsync(Container container, IReadOnlyList cosmosQueryClientCore); List items = await RunQueryAsync(containerWithBypassParsing, query, feedOptions); - int[] actual = items.Cast().Select(x => (int)Number64.ToLong(x.Value)).ToArray(); + string[] actualOutput = items.Select(x => x.ToString()).ToArray(); - Assert.IsTrue(expected.SequenceEqual(actual)); + Assert.IsTrue(expectedOutput.SequenceEqual(actualOutput)); } IReadOnlyList documents = CreateDocuments(documentCount); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/MockCosmosQueryClient.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/MockCosmosQueryClient.cs index 11d51403b1..6dd861ec88 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/MockCosmosQueryClient.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/MockCosmosQueryClient.cs @@ -35,7 +35,7 @@ public MockCosmosQueryClient( public int QueryPlanCalls { get; private set; } - public override bool ByPassQueryParsing() + public override bool BypassQueryParsing() { return this.forceQueryPlanGatewayElseServiceInterop; } 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 fad65e80db..1e7d4e1e40 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 @@ -927,7 +927,7 @@ internal class TestCosmosQueryClient : CosmosQueryClient { public override Action OnExecuteScalarQueryCallback => throw new NotImplementedException(); - public override bool ByPassQueryParsing() + public override bool BypassQueryParsing() { return false; }