Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query: Fixes "System.ArgumentException: Stream was not readable." when using WithParameterStream #3155

Merged
merged 7 commits into from
Apr 29, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
// if the SqlParameter has stream value we dont pass it through the custom serializer.
if (sqlParameter.Value is SerializedParameterValue serializedEncryptedData)
{
using (StreamReader streamReader = new StreamReader(serializedEncryptedData.valueStream))
{
string parameterValue = streamReader.ReadToEnd();
writer.WriteRawValue(parameterValue);
}
writer.WriteRawValue(serializedEncryptedData.rawSerializedJsonValue);
}
else
{
Expand Down
10 changes: 8 additions & 2 deletions Microsoft.Azure.Cosmos/src/Query/v3Query/QueryDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,16 @@ public QueryDefinition WithParameter(string name, object value)
/// <returns>An instance of <see cref="QueryDefinition"/>.</returns>
public QueryDefinition WithParameterStream(string name, Stream valueStream)
{
string rawSerializedJsonValue = null;
using (StreamReader streamReader = new StreamReader(valueStream))
{
rawSerializedJsonValue = streamReader.ReadToEnd();
}

// pack it into an internal type for identification.
SerializedParameterValue serializedParameterValue = new SerializedParameterValue
{
valueStream = valueStream
rawSerializedJsonValue = rawSerializedJsonValue
};

return this.WithParameter(name, serializedParameterValue);
Expand Down Expand Up @@ -200,6 +206,6 @@ IEnumerator IEnumerable.GetEnumerator()

internal struct SerializedParameterValue
{
internal Stream valueStream;
internal string rawSerializedJsonValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,36 @@ public async Task QueryStreamValueTest()
Assert.AreEqual(pageCount, fromStreamCount);
}

// get result across pages,multiple requests by setting MaxItemCount to 1.
foreach (QueryDefinition queryDefinition in queryDefinitions)
{
toStreamCount = 0;
fromStreamCount = 0;

List<dynamic> allItems = new List<dynamic>();
int pageCount = 0;
using (FeedIterator<dynamic> feedIterator = containerSerializer.GetItemQueryIterator<dynamic>(
queryDefinition: queryDefinition,
requestOptions: new QueryRequestOptions { MaxItemCount = 1 }))
{
while (feedIterator.HasMoreResults)
{
// Only need once to verify correct serialization of the query definition
FeedResponse<dynamic> response = await feedIterator.ReadNextAsync(this.cancellationToken);
Assert.AreEqual(response.Count, response.Count());
allItems.AddRange(response);
pageCount++;
}
}

Assert.AreEqual(2, allItems.Count, $"missing query results. Only found: {allItems.Count} items for query:{queryDefinition.ToSqlQuerySpec().QueryText}");

// There should be no call to custom serializer since the parameter values are already serialized.
Assert.AreEqual(0, toStreamCount, $"missing to stream call. Expected: 0 , Actual: {toStreamCount} for query:{queryDefinition.ToSqlQuerySpec().QueryText}");
Assert.AreEqual(pageCount, fromStreamCount);
}


// Standard Cosmos Serializer Used

CosmosClient clientStandardSerializer = TestCommon.CreateCosmosClient(useCustomSeralizer: false);
Expand Down