From 2c9f2a2a3d726bb168dd0aed82eb39703214f5d8 Mon Sep 17 00:00:00 2001 From: Neil Deshpande Date: Tue, 16 Sep 2025 23:44:55 -0700 Subject: [PATCH 1/2] Do not use passthrough context for collections with HPK --- .../src/Handler/RequestMessage.cs | 5 +- .../CosmosQueryExecutionContextFactory.cs | 7 +- .../Query/BypassQueryParsingTests.cs | 140 ++++++++++--- .../Query/QueryTestsBase.cs | 197 ++++++++++++------ 4 files changed, 253 insertions(+), 96 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs b/Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs index aa6d796df2..cd6be5f67b 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs @@ -385,9 +385,10 @@ private bool AssertPartitioningPropertiesAndHeaders() bool partitionKeyRangeIdExists = !string.IsNullOrEmpty(this.Headers.PartitionKeyRangeId); if (partitionKeyRangeIdExists) - { + { + OperationType op = this.OperationType; // Assert operation type is not write - if (this.OperationType != OperationType.Query && this.OperationType != OperationType.ReadFeed && this.OperationType != OperationType.Batch) + if (op != OperationType.Query && op != OperationType.QueryPlan && op != OperationType.ReadFeed && op != OperationType.Batch) { throw new ArgumentOutOfRangeException(RMResources.UnexpectedPartitionKeyRangeId); } diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs index 4364e5ce01..4a1c518fb9 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs @@ -191,7 +191,7 @@ private static async Task> TryCreateCoreContextAsy // 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() - && inputParameters.PartitionKey.HasValue) + && inputParameters.PartitionKey.HasValue && containerQueryProperties.PartitionKeyDefinition.Paths.Count <= 1) { bool parsed; SqlQuery sqlQuery; @@ -301,9 +301,10 @@ private static async Task> TryCreateFromPartitione } else { - bool singleLogicalPartitionKeyQuery = (inputParameters.PartitionKey.HasValue && targetRanges.Count == 1) + bool singleLogicalPartitionKeyQuery = ((inputParameters.PartitionKey.HasValue && targetRanges.Count == 1) || ((partitionedQueryExecutionInfo.QueryRanges.Count == 1) - && partitionedQueryExecutionInfo.QueryRanges[0].IsSingleValue); + && partitionedQueryExecutionInfo.QueryRanges[0].IsSingleValue)) + && containerQueryProperties.PartitionKeyDefinition.Paths.Count <= 1; bool serverStreamingQuery = !partitionedQueryExecutionInfo.QueryInfo.HasAggregates && !partitionedQueryExecutionInfo.QueryInfo.HasDistinct && !partitionedQueryExecutionInfo.QueryInfo.HasNonStreamingOrderBy 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 4db276f4ce..5485b9d16e 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 @@ -2,44 +2,116 @@ namespace Microsoft.Azure.Cosmos.EmulatorTests.Query { using System; using System.Collections.Generic; + using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.CosmosElements; + using Microsoft.Azure.Cosmos.Query.Core; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] [TestCategory("Query")] public sealed class BypassQueryParsingTests : QueryTestsBase { - [TestMethod] - public async Task TestBypassQueryParsingWithNonePartitionKey() + private const int DocumentCount = 400; + + private static readonly Documents.PartitionKeyDefinition HierarchicalPartitionKeyDefinition = new Documents.PartitionKeyDefinition { - int documentCount = 400; + Paths = new Collection { "/nullField", "/numberField" }, + Kind = Documents.PartitionKind.MultiHash, + Version = Documents.PartitionKeyDefinitionVersion.V2 + }; - string query = "SELECT VALUE r.numberField FROM r"; - IReadOnlyList expectedOutput = Enumerable.Range(0, documentCount).Select(i => i.ToString()).ToList(); + private static readonly Documents.PartitionKeyDefinition SimplePartitionKeyDefinition = new Documents.PartitionKeyDefinition + { + Paths = new Collection { "/UndefinedField" }, + Kind = Documents.PartitionKind.Hash + }; - await this.ValidateQueryBypassWithNonePartitionKey(documentCount, query, expectedOutput); + [TestMethod] + [TestCategory("Query")] + public async Task TestBypassQueryParsing() + { + IReadOnlyList testCases = new List + { + new( + PartitionKey.None, + "SELECT VALUE r.numberField FROM r", + Enumerable.Range(0, DocumentCount).Select(i => i.ToString()).ToList(), + TestInjections.PipelineType.Passthrough), + new( + PartitionKey.None, + @"SELECT VALUE { """" : r.numberField } FROM r", + Enumerable.Range(0, DocumentCount).Select(i => String.Format("{{\"\":{0}}}", i)).ToList(), + TestInjections.PipelineType.Passthrough), + }; + + await this.ValidateQueryBypass( + ConnectionModes.Direct | ConnectionModes.Gateway, + CollectionTypes.NonPartitioned | CollectionTypes.SinglePartition | CollectionTypes.MultiPartition, + SimplePartitionKeyDefinition, + testCases); } [TestMethod] [TestCategory("Query")] - public async Task TestBypassQueryParsingWithNonePartitionKeyEmptyPropertyName() + public async Task TestBypassQueryParsingWithHPK() { - int documentCount = 400; - - string query = @"SELECT VALUE { """" : r.numberField } FROM r"; - IReadOnlyList expectedOutput = Enumerable.Range(0, documentCount).Select(i => String.Format("{{\"\":{0}}}", i)).ToList(); + PartitionKey partialPartitionKey = new PartitionKeyBuilder().AddNullValue().Build(); - await this.ValidateQueryBypassWithNonePartitionKey(documentCount, query, expectedOutput); + IReadOnlyList testCases = new List + { + new( + partialPartitionKey, + "SELECT VALUE r.numberField FROM r", + Enumerable.Range(0, DocumentCount).Select(i => i.ToString()).ToList(), + TestInjections.PipelineType.Passthrough), // Passthrough because it is a client streaming query + new( + partialPartitionKey, + $"SELECT TOP {DocumentCount} VALUE r.numberField FROM r", + Enumerable.Range(0, DocumentCount).Select(i => i.ToString()).ToList(), + TestInjections.PipelineType.Specialized), + new( + partialPartitionKey, + @"SELECT VALUE { """" : r.numberField } FROM r", + Enumerable.Range(0, DocumentCount).Select(i => String.Format("{{\"\":{0}}}", i)).ToList(), + TestInjections.PipelineType.Passthrough), // Passthrough because it is a client streaming query + new( + partialPartitionKey, + "SELECT VALUE r.numberField FROM r ORDER BY r.numberField", + Enumerable.Range(0, DocumentCount).Select(i => i.ToString()).ToList(), + TestInjections.PipelineType.Specialized), + }; + + await this.ValidateQueryBypass( + ConnectionModes.Gateway, + CollectionTypes.MultiPartition, + HierarchicalPartitionKeyDefinition, + testCases); } - private async Task ValidateQueryBypassWithNonePartitionKey(int documentCount, string query, IReadOnlyList expectedOutput) + private Task ValidateQueryBypass(ConnectionModes connectionModes, CollectionTypes collectionTypes, Documents.PartitionKeyDefinition partitionKeyDefinition, IReadOnlyList testCases) { - QueryRequestOptions feedOptions = new QueryRequestOptions { PartitionKey = PartitionKey.None }; + IReadOnlyList documents = CreateDocuments(DocumentCount); - async Task ImplementationAsync(Container container, IReadOnlyList documents) + return this.CreateIngestQueryDeleteAsync( + connectionModes, + collectionTypes, + documents, + query: (container, _) => RunTestsAsync(container, testCases), + partitionKeyDefinition); + } + + private static async Task RunTestsAsync(Container container, IReadOnlyList testCases) + { + foreach (QueryTestCase testCase in testCases) { + QueryRequestOptions feedOptions = new QueryRequestOptions + { + PartitionKey = testCase.PartitionKey, + TestSettings = new TestInjections(simulate429s: false, simulateEmptyPages: false, responseStats: new()) + }; + ContainerInternal containerCore = container as ContainerInlineCore; MockCosmosQueryClient cosmosQueryClientCore = new MockCosmosQueryClient( @@ -53,20 +125,19 @@ async Task ImplementationAsync(Container container, IReadOnlyList containerCore.Id, cosmosQueryClientCore); - List items = await RunQueryAsync(containerWithBypassParsing, query, feedOptions); + List items = await RunQueryAsync(containerWithBypassParsing, testCase.Query, feedOptions); string[] actualOutput = items.Select(x => x.ToString()).ToArray(); - Assert.IsTrue(expectedOutput.SequenceEqual(actualOutput)); - } + if(!testCase.ExpectedOutput.SequenceEqual(actualOutput)) + { + System.Diagnostics.Trace.WriteLine($"Expected: [{string.Join(", ", testCase.ExpectedOutput)}]"); + System.Diagnostics.Trace.WriteLine($"Actual: [{string.Join(", ", actualOutput)}]"); - IReadOnlyList documents = CreateDocuments(documentCount); + Assert.Fail("Query results do not match expected results."); + } - await this.CreateIngestQueryDeleteAsync( - ConnectionModes.Direct | ConnectionModes.Gateway, - CollectionTypes.NonPartitioned | CollectionTypes.SinglePartition | CollectionTypes.MultiPartition, - documents, - ImplementationAsync, - "/undefinedPartitionKey"); + Assert.AreEqual(testCase.ExpectedPipelineType, feedOptions.TestSettings.Stats.PipelineType); + } } private static IReadOnlyList CreateDocuments(int documentCount) @@ -80,5 +151,24 @@ private static IReadOnlyList CreateDocuments(int documentCount) return documents; } + + private sealed class QueryTestCase + { + public PartitionKey PartitionKey { get; } + + public string Query { get; } + + public IReadOnlyList ExpectedOutput { get; } + + public TestInjections.PipelineType ExpectedPipelineType { get; } + + public QueryTestCase(PartitionKey partitionKey, string query, IReadOnlyList expectedOutput, TestInjections.PipelineType expectedPipelineType) + { + this.PartitionKey = partitionKey; + this.Query = query ?? throw new ArgumentNullException(nameof(query)); + this.ExpectedOutput = expectedOutput ?? throw new ArgumentNullException(nameof(expectedOutput)); + this.ExpectedPipelineType = expectedPipelineType; + } + } } } \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/QueryTestsBase.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/QueryTestsBase.cs index 9e55052dcb..c947041b85 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/QueryTestsBase.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/QueryTestsBase.cs @@ -100,16 +100,16 @@ private async Task> GetPartitionKeyRanges(Conta } private async Task CreateMultiPartitionContainer( - string partitionKey, + PartitionKeyDefinition partitionKey, Microsoft.Azure.Cosmos.IndexingPolicy indexingPolicy, - Cosmos.GeospatialType geospatialType, + Cosmos.GeospatialType geospatialType, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy) { ContainerResponse containerResponse = await this.CreatePartitionedContainer( throughput: 25000, partitionKey: partitionKey, indexingPolicy: indexingPolicy, - geospatialType, + geospatialType, vectorEmbeddingPolicy); IReadOnlyList ranges = await this.GetPartitionKeyRanges(containerResponse); @@ -121,16 +121,16 @@ private async Task CreateMultiPartitionContainer( } private async Task CreateSinglePartitionContainer( - string partitionKey, + PartitionKeyDefinition partitionKey, Microsoft.Azure.Cosmos.IndexingPolicy indexingPolicy, - Cosmos.GeospatialType geospatialType, + Cosmos.GeospatialType geospatialType, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy) { ContainerResponse containerResponse = await this.CreatePartitionedContainer( throughput: 4000, partitionKey: partitionKey, indexingPolicy: indexingPolicy, - geospatialType: geospatialType, + geospatialType: geospatialType, vectorEmbeddingPolicy: vectorEmbeddingPolicy); Assert.IsNotNull(containerResponse); @@ -160,9 +160,9 @@ await NonPartitionedContainerHelper.CreateNonPartitionedContainer( private async Task CreatePartitionedContainer( int throughput, - string partitionKey, + PartitionKeyDefinition partitionKey, Microsoft.Azure.Cosmos.IndexingPolicy indexingPolicy, - Cosmos.GeospatialType geospatialType, + Cosmos.GeospatialType geospatialType, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy) { // Assert that database exists (race deletes are possible when used concurrently) @@ -188,12 +188,8 @@ private async Task CreatePartitionedContainer( } } }, - PartitionKey = partitionKey == null ? null : new PartitionKeyDefinition - { - Paths = new Collection { partitionKey }, - Kind = PartitionKind.Hash - }, - GeospatialConfig = new Cosmos.GeospatialConfig(geospatialType), + PartitionKey = partitionKey, + GeospatialConfig = new Cosmos.GeospatialConfig(geospatialType), VectorEmbeddingPolicy = vectorEmbeddingPolicy }, // This throughput needs to be about half the max with multi master @@ -218,15 +214,15 @@ private async Task CreatePartitionedContainer( documents, partitionKey: null, indexingPolicy: indexingPolicy, - geospatialType: geospatialType, + geospatialType: geospatialType, vectorEmbeddingPolicy: null); } private Task<(Container, IReadOnlyList)> CreateSinglePartitionContainerAndIngestDocumentsAsync( IEnumerable documents, - string partitionKey, + PartitionKeyDefinition partitionKey, Cosmos.IndexingPolicy indexingPolicy, - Cosmos.GeospatialType geospatialType, + Cosmos.GeospatialType geospatialType, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy) { return this.CreateContainerAndIngestDocumentsAsync( @@ -234,15 +230,15 @@ private async Task CreatePartitionedContainer( documents, partitionKey, indexingPolicy, - geospatialType, + geospatialType, vectorEmbeddingPolicy); } private Task<(Container, IReadOnlyList)> CreateMultiPartitionContainerAndIngestDocumentsAsync( IEnumerable documents, - string partitionKey, + PartitionKeyDefinition partitionKey, Cosmos.IndexingPolicy indexingPolicy, - Cosmos.GeospatialType geospatialType, + Cosmos.GeospatialType geospatialType, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy) { return this.CreateContainerAndIngestDocumentsAsync( @@ -250,16 +246,16 @@ private async Task CreatePartitionedContainer( documents, partitionKey, indexingPolicy, - geospatialType, + geospatialType, vectorEmbeddingPolicy); } private async Task<(Container, IReadOnlyList)> CreateContainerAndIngestDocumentsAsync( CollectionTypes collectionType, IEnumerable documents, - string partitionKey, + PartitionKeyDefinition partitionKey, Cosmos.IndexingPolicy indexingPolicy, - Cosmos.GeospatialType geospatialType, + Cosmos.GeospatialType geospatialType, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy) { Container container = collectionType switch @@ -273,43 +269,53 @@ private async Task CreatePartitionedContainer( foreach (string document in documents) { JObject documentObject = JsonConvert.DeserializeObject(document); - // Add an id if (documentObject["id"] == null) { + // Add an id documentObject["id"] = Guid.NewGuid().ToString(); } + // Get partition key value. Cosmos.PartitionKey pkValue; if (partitionKey != null) { - string jObjectPartitionKey = partitionKey.Remove(0, 1); - JValue pkToken = (JValue)documentObject[jObjectPartitionKey]; - if (pkToken == null) - { - pkValue = Cosmos.PartitionKey.None; - } - else + PartitionKeyBuilder partitionKeyBuilder = new PartitionKeyBuilder(); + + foreach (string path in partitionKey.Paths) { - switch (pkToken.Type) + List propertyNames = path.Split('/', StringSplitOptions.RemoveEmptyEntries).ToList(); + string jsonPath = "$." + string.Join(".", propertyNames); + JToken pkToken = documentObject.SelectToken(jsonPath); + + if (pkToken == null) { - case JTokenType.Integer: - case JTokenType.Float: - pkValue = new Cosmos.PartitionKey(pkToken.Value()); - break; - case JTokenType.String: - pkValue = new Cosmos.PartitionKey(pkToken.Value()); - break; - case JTokenType.Boolean: - pkValue = new Cosmos.PartitionKey(pkToken.Value()); - break; - case JTokenType.Null: - pkValue = Cosmos.PartitionKey.Null; - break; - default: - throw new ArgumentException("Unknown partition key type"); + partitionKeyBuilder.AddNoneType(); + } + else + { + switch (pkToken.Type) + { + case JTokenType.Integer: + case JTokenType.Float: + partitionKeyBuilder.Add(pkToken.Value()); + break; + case JTokenType.String: + partitionKeyBuilder.Add(pkToken.Value()); + break; + case JTokenType.Boolean: + partitionKeyBuilder.Add(pkToken.Value()); + break; + case JTokenType.Null: + partitionKeyBuilder.AddNullValue(); + break; + default: + throw new ArgumentException("Unknown partition key type"); + } } } + + pkValue = partitionKeyBuilder.Build(); } else { @@ -377,16 +383,16 @@ internal delegate Task Query( IReadOnlyList documents, T testArgs); - internal delegate CosmosClient CosmosClientFactory(ConnectionMode connectionMode); - - internal static ConnectionModes ToTestConnectionMode(ConnectionMode connectionMode) - { - return connectionMode switch - { - ConnectionMode.Direct => ConnectionModes.Direct, - ConnectionMode.Gateway => ConnectionModes.Gateway, - _ => throw new ArgumentOutOfRangeException(nameof(connectionMode), connectionMode, null) - }; + internal delegate CosmosClient CosmosClientFactory(ConnectionMode connectionMode); + + internal static ConnectionModes ToTestConnectionMode(ConnectionMode connectionMode) + { + return connectionMode switch + { + ConnectionMode.Direct => ConnectionModes.Direct, + ConnectionMode.Gateway => ConnectionModes.Gateway, + _ => throw new ArgumentOutOfRangeException(nameof(connectionMode), connectionMode, null) + }; } internal Task CreateIngestQueryDeleteAsync( @@ -397,7 +403,7 @@ internal Task CreateIngestQueryDeleteAsync( string partitionKey = "/id", Cosmos.IndexingPolicy indexingPolicy = null, CosmosClientFactory cosmosClientFactory = null, - Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography, + Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy = null) { Task queryWrapper(Container container, IReadOnlyList inputDocuments, object throwaway) @@ -414,7 +420,36 @@ Task queryWrapper(Container container, IReadOnlyList inputDocument partitionKey, indexingPolicy, cosmosClientFactory, - geospatialType, + geospatialType, + vectorEmbeddingPolicy); + } + + internal Task CreateIngestQueryDeleteAsync( + ConnectionModes connectionModes, + CollectionTypes collectionTypes, + IEnumerable documents, + Query query, + PartitionKeyDefinition partitionKeyDefinition, + Cosmos.IndexingPolicy indexingPolicy = null, + CosmosClientFactory cosmosClientFactory = null, + Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography, + Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy = null) + { + Task queryWrapper(Container container, IReadOnlyList inputDocuments, object throwaway) + { + return query(container, inputDocuments); + } + + return this.CreateIngestQueryDeleteAsync( + connectionModes, + collectionTypes, + documents, + queryWrapper, + null, + partitionKeyDefinition, + indexingPolicy, + cosmosClientFactory, + geospatialType, vectorEmbeddingPolicy); } @@ -427,9 +462,14 @@ internal Task CreateIngestQueryDeleteAsync( string partitionKey = "/id", Cosmos.IndexingPolicy indexingPolicy = null, CosmosClientFactory cosmosClientFactory = null, - Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography, + Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy = null) { + PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition() + { + Paths = new Collection() { partitionKey } + }; + return this.CreateIngestQueryDeleteAsync( connectionModes, collectionTypes, @@ -437,9 +477,34 @@ internal Task CreateIngestQueryDeleteAsync( query, cosmosClientFactory ?? this.CreateDefaultCosmosClient, testArgs, - partitionKey, + partitionKeyDefinition, + indexingPolicy, + geospatialType, + vectorEmbeddingPolicy); + } + + internal Task CreateIngestQueryDeleteAsync( + ConnectionModes connectionModes, + CollectionTypes collectionTypes, + IEnumerable documents, + Query query, + T testArgs, + PartitionKeyDefinition partitionKeyDefinition, + Cosmos.IndexingPolicy indexingPolicy = null, + CosmosClientFactory cosmosClientFactory = null, + Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography, + Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy = null) + { + return this.CreateIngestQueryDeleteAsync( + connectionModes, + collectionTypes, + documents, + query, + cosmosClientFactory ?? this.CreateDefaultCosmosClient, + testArgs, + partitionKeyDefinition, indexingPolicy, - geospatialType, + geospatialType, vectorEmbeddingPolicy); } @@ -468,9 +533,9 @@ internal async Task CreateIngestQueryDeleteAsync( Query query, CosmosClientFactory cosmosClientFactory, T testArgs, - string partitionKey = "/id", + PartitionKeyDefinition partitionKey, Cosmos.IndexingPolicy indexingPolicy = null, - Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography, + Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography, Cosmos.VectorEmbeddingPolicy vectorEmbeddingPolicy = null) { try @@ -493,13 +558,13 @@ internal async Task CreateIngestQueryDeleteAsync( documents, partitionKey, indexingPolicy, - geospatialType, + geospatialType, vectorEmbeddingPolicy), CollectionTypes.MultiPartition => this.CreateMultiPartitionContainerAndIngestDocumentsAsync( documents, partitionKey, indexingPolicy, - geospatialType, + geospatialType, vectorEmbeddingPolicy), _ => throw new ArgumentException($"Unknown {nameof(CollectionTypes)} : {collectionType}"), }; From 982ce34f98bd93ac2d5f3ed6c369875e6997a01f Mon Sep 17 00:00:00 2001 From: Neil Deshpande Date: Thu, 18 Sep 2025 13:55:49 -0700 Subject: [PATCH 2/2] Incorporate code review feedback --- Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs b/Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs index cd6be5f67b..f9f5d4b640 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/RequestMessage.cs @@ -386,9 +386,12 @@ private bool AssertPartitioningPropertiesAndHeaders() bool partitionKeyRangeIdExists = !string.IsNullOrEmpty(this.Headers.PartitionKeyRangeId); if (partitionKeyRangeIdExists) { - OperationType op = this.OperationType; + OperationType operationType = this.OperationType; // Assert operation type is not write - if (op != OperationType.Query && op != OperationType.QueryPlan && op != OperationType.ReadFeed && op != OperationType.Batch) + if (operationType != OperationType.Query + && operationType != OperationType.QueryPlan + && operationType != OperationType.ReadFeed + && operationType != OperationType.Batch) { throw new ArgumentOutOfRangeException(RMResources.UnexpectedPartitionKeyRangeId); }