Skip to content

Commit a200126

Browse files
committed
ReadMany: Fixes BadRequest when using Ids with single quotes (#3732)
* Use parameters * Emulator tests
1 parent 8a537ce commit a200126

File tree

2 files changed

+19
-20
lines changed

2 files changed

+19
-20
lines changed

Microsoft.Azure.Cosmos/src/ReadManyQueryHelper.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -249,18 +249,22 @@ private QueryDefinition CreateReadManyQueryDefinitionForId(List<(string, Partiti
249249
{
250250
int totalItemCount = Math.Min(items.Count, startIndex + this.maxItemsPerQuery);
251251
StringBuilder queryStringBuilder = new StringBuilder();
252+
SqlParameterCollection sqlParameters = new SqlParameterCollection();
252253
queryStringBuilder.Append("SELECT * FROM c WHERE c.id IN ( ");
253254
for (int i = startIndex; i < totalItemCount; i++)
254255
{
255-
queryStringBuilder.Append($"'{items[i].Item1}'");
256+
string idParamName = "@param_id" + i;
257+
sqlParameters.Add(new SqlParameter(idParamName, items[i].Item1));
258+
queryStringBuilder.Append(idParamName);
256259
if (i < totalItemCount - 1)
257260
{
258261
queryStringBuilder.Append(",");
259262
}
260263
}
261264
queryStringBuilder.Append(" )");
262265

263-
return new QueryDefinition(queryStringBuilder.ToString());
266+
return QueryDefinition.CreateFromQuerySpec(new SqlQuerySpec(queryStringBuilder.ToString(),
267+
sqlParameters));
264268
}
265269

266270
private QueryDefinition CreateReadManyQueryDefinitionForOther(List<(string, PartitionKey)> items,

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosReadManyItemsTests.cs

+13-18
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,27 @@
55
namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
66
{
77
using System;
8-
using System.Collections.Concurrent;
98
using System.Collections.Generic;
10-
using System.Collections.ObjectModel;
119
using System.Net;
12-
using System.Net.Http;
13-
using System.Text;
1410
using System.Threading;
1511
using System.Threading.Tasks;
1612
using Microsoft.Azure.Cosmos.Fluent;
17-
using Microsoft.Azure.Cosmos.Query.Core;
1813
using Microsoft.Azure.Cosmos.Tracing;
1914
using Microsoft.VisualStudio.TestTools.UnitTesting;
2015

2116
[TestClass]
2217
public class CosmosReadManyItemsTests : BaseCosmosClientHelper
2318
{
2419
private Container Container = null;
25-
private ContainerProperties containerSettings = null;
2620

2721
[TestInitialize]
2822
public async Task TestInitialize()
2923
{
3024
await base.TestInit();
3125
string PartitionKey = "/pk";
32-
this.containerSettings = new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: PartitionKey);
26+
ContainerProperties containerSettings = new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: PartitionKey);
3327
ContainerResponse response = await this.database.CreateContainerAsync(
34-
this.containerSettings,
28+
containerSettings,
3529
throughput: 20000,
3630
cancellationToken: this.cancellationToken);
3731
Assert.IsNotNull(response);
@@ -122,23 +116,24 @@ public async Task ReadManyDoesNotFetchQueryPlan()
122116
[TestMethod]
123117
public async Task ReadManyWithIdasPk()
124118
{
125-
string PartitionKey = "/id";
126-
ContainerProperties containerSettings = new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: PartitionKey);
127-
Container container = await this.database.CreateContainerAsync(containerSettings);
119+
Container container = await this.database.CreateContainerAsync(Guid.NewGuid().ToString(), "/id");
128120

129121
List<(string, PartitionKey)> itemList = new List<(string, PartitionKey)>();
130-
for (int i = 0; i < 5; i++)
131-
{
132-
itemList.Add((i.ToString(), new PartitionKey(i.ToString())));
133-
}
134122

135123
// Create items with different pk values
136124
for (int i = 0; i < 5; i++)
137125
{
138126
ToDoActivity item = ToDoActivity.CreateRandomToDoActivity();
139-
item.id = i.ToString();
140127
ItemResponse<ToDoActivity> itemResponse = await container.CreateItemAsync(item);
141128
Assert.AreEqual(HttpStatusCode.Created, itemResponse.StatusCode);
129+
130+
itemList.Add((item.id, new PartitionKey(item.id)));
131+
132+
ToDoActivity itemWithSingleQuotes = ToDoActivity.CreateRandomToDoActivity(id: item.id + "'singlequote");
133+
ItemResponse<ToDoActivity> itemResponseWithSingleQuotes = await container.CreateItemAsync(itemWithSingleQuotes);
134+
Assert.AreEqual(HttpStatusCode.Created, itemResponseWithSingleQuotes.StatusCode);
135+
136+
itemList.Add((itemWithSingleQuotes.id, new PartitionKey(itemWithSingleQuotes.id)));
142137
}
143138

144139
using (ResponseMessage responseMessage = await container.ReadManyItemsStreamAsync(itemList))
@@ -149,12 +144,12 @@ public async Task ReadManyWithIdasPk()
149144

150145
ToDoActivity[] items = this.cosmosClient.ClientContext.SerializerCore.FromFeedStream<ToDoActivity>(
151146
CosmosFeedResponseSerializer.GetStreamWithoutServiceEnvelope(responseMessage.Content));
152-
Assert.AreEqual(items.Length, 5);
147+
Assert.AreEqual(items.Length, 10);
153148
}
154149

155150
FeedResponse<ToDoActivity> feedResponse = await container.ReadManyItemsAsync<ToDoActivity>(itemList);
156151
Assert.IsNotNull(feedResponse);
157-
Assert.AreEqual(feedResponse.Count, 5);
152+
Assert.AreEqual(feedResponse.Count, 10);
158153
Assert.IsTrue(feedResponse.Headers.RequestCharge > 0);
159154
Assert.IsNotNull(feedResponse.Diagnostics);
160155
}

0 commit comments

Comments
 (0)