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

[Internal] Query: Adds support for continuation using SqlQuerySpec #3774

Merged
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
60f7f09
initial change to support sending continuation as resume value in que…
Mar 16, 2023
7aba983
serialize resume value in continuation token.
Mar 18, 2023
732cb05
fix unit test that was failing. other minor refactors
Mar 21, 2023
55dbb82
additional refactoring
Mar 22, 2023
39e83c1
Merge branch 'master' into users/balaperu/query_spec_continuation
Jun 22, 2023
1976690
Merge branch 'master' into users/balaperu/query_spec_continuation
Jul 14, 2023
5eb8726
few minor changes
Jul 14, 2023
13797cb
additional tests
Jul 19, 2023
079196c
Merge branch 'master' into users/balaperu/query_spec_continuation
Jul 19, 2023
09b0704
code refactoring
Aug 2, 2023
d228875
Create separate top level object to represent SqlQueryResumeValue. Di…
Aug 8, 2023
07eb3ac
handle different continuation token for target partition
Aug 9, 2023
b041d42
update test for continuation from array and object values. other mino…
Aug 11, 2023
86dd496
save resume value as CosmosElement instead of defining a separate der…
Aug 24, 2023
05c1a89
support on CosmosNumber64. Other number types are not supported for r…
Aug 25, 2023
c63665f
update cosmosundefinedquerytests to include arrays and object in orde…
Aug 26, 2023
315314d
revert change to have separate SqlQueryResumeValue objects as it is b…
Aug 28, 2023
5144b4e
group resume value into 3 types: Undefined, Primitive and Complex
Aug 29, 2023
b5b9159
minor fix
Sep 5, 2023
b1b3c78
Merge branch 'master' into users/balaperu/query_spec_continuation
Sep 5, 2023
d57b084
Merge branch 'master' into users/balaperu/query_spec_continuation
Jan 26, 2024
6b6655c
Merge branch 'master' into users/balaperu/query_spec_continuation
adityasa Feb 13, 2024
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
98 changes: 78 additions & 20 deletions Microsoft.Azure.Cosmos/src/CosmosSqlQuerySpecJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ internal CosmosSqlQuerySpecJsonConverter(CosmosSerializer userSerializer)

public override bool CanConvert(Type objectType)
{
return typeof(SqlParameter) == objectType;
return typeof(SqlParameter) == objectType
|| typeof(SqlQueryResumeFilter.ResumeValue).IsAssignableFrom(objectType);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
Expand All @@ -34,32 +35,89 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
SqlParameter sqlParameter = (SqlParameter)value;

writer.WriteStartObject();
writer.WritePropertyName("name");
serializer.Serialize(writer, sqlParameter.Name);
writer.WritePropertyName("value");

// if the SqlParameter has stream value we dont pass it through the custom serializer.
if (sqlParameter.Value is SerializedParameterValue serializedEncryptedData)
{
writer.WriteRawValue(serializedEncryptedData.rawSerializedJsonValue);
}
else
if (value is SqlParameter sqlParameter)
{
// Use the user serializer for the parameter values so custom conversions are correctly handled
using (Stream str = this.UserSerializer.ToStream(sqlParameter.Value))
writer.WriteStartObject();
writer.WritePropertyName("name");
serializer.Serialize(writer, sqlParameter.Name);
writer.WritePropertyName("value");

// 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(str))
writer.WriteRawValue(serializedEncryptedData.rawSerializedJsonValue);
}
else
{
// Use the user serializer for the parameter values so custom conversions are correctly handled
using (Stream str = this.UserSerializer.ToStream(sqlParameter.Value))
{
string parameterValue = streamReader.ReadToEnd();
writer.WriteRawValue(parameterValue);
using (StreamReader streamReader = new StreamReader(str))
{
string parameterValue = streamReader.ReadToEnd();
writer.WriteRawValue(parameterValue);
}
}
}

writer.WriteEndObject();
}
else if (value is SqlQueryResumeFilter.ResumeValue resumeValue)
{
this.WriteResumeValue(writer, resumeValue, serializer);
}
}

writer.WriteEndObject();
private void WriteResumeValue(JsonWriter writer, SqlQueryResumeFilter.ResumeValue value, JsonSerializer serializer)
adityasa marked this conversation as resolved.
Show resolved Hide resolved
{
switch (value)
{
case SqlQueryResumeFilter.UndefinedResumeValue:
writer.WriteStartArray();
writer.WriteEndArray();
break;

case SqlQueryResumeFilter.NullResumeValue:
writer.WriteNull();
break;

case SqlQueryResumeFilter.BooleanResumeValue booleanValue:
serializer.Serialize(writer, booleanValue.Value);
break;

case SqlQueryResumeFilter.NumberResumeValue numberValue:
serializer.Serialize(writer, numberValue.Value);
break;

case SqlQueryResumeFilter.StringResumeValue stringValue:
serializer.Serialize(writer, stringValue.Value.ToString());
break;

case SqlQueryResumeFilter.ArrayResumeValue arrayValue:
writer.WriteStartObject();
writer.WritePropertyName(SqlQueryResumeFilter.ResumeValue.PropertyNames.Type);
writer.WriteValue(SqlQueryResumeFilter.ResumeValue.PropertyNames.ArrayType);
writer.WritePropertyName(SqlQueryResumeFilter.ResumeValue.PropertyNames.Low);
writer.WriteValue(arrayValue.HashValue.GetLow());
writer.WritePropertyName(SqlQueryResumeFilter.ResumeValue.PropertyNames.High);
writer.WriteValue(arrayValue.HashValue.GetHigh());
writer.WriteEndObject();
break;

case SqlQueryResumeFilter.ObjectResumeValue objectValue:
writer.WriteStartObject();
writer.WritePropertyName(SqlQueryResumeFilter.ResumeValue.PropertyNames.Type);
writer.WriteValue(SqlQueryResumeFilter.ResumeValue.PropertyNames.ObjectType);
writer.WritePropertyName(SqlQueryResumeFilter.ResumeValue.PropertyNames.Low);
writer.WriteValue(objectValue.HashValue.GetLow());
writer.WritePropertyName(SqlQueryResumeFilter.ResumeValue.PropertyNames.High);
writer.WriteValue(objectValue.HashValue.GetHigh());
writer.WriteEndObject();
break;

default:
throw new ArgumentException($"Invalid {nameof(SqlQueryResumeFilter.ResumeValue)} type.");
}
}

/// <summary>
Expand Down
Loading
Loading