Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions src/Core/Resolvers/SqlQueryEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,14 @@ public object ResolveList(JsonElement array, ObjectField fieldSchema, ref IMetad

private static JsonDocument? ParseResultIntoJsonDocument(JsonElement? result)
{
// An empty result set surfaces as a default (JsonValueKind.Undefined) JsonElement with no
// backing document; serializing it throws InvalidOperationException. Return null to match the
// non-cached path, which renders an empty payload (e.g. {"value":[]}).
if (result is { ValueKind: JsonValueKind.Undefined })
{
return null;
}

byte[] jsonBytes = JsonSerializer.SerializeToUtf8Bytes(result);
return JsonDocument.Parse(jsonBytes);
}
Expand Down
19 changes: 19 additions & 0 deletions src/Service.Tests/UnitTests/SqlQueryEngineHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ public void ParseResultIntoJsonDocument_HandlesValuesAndNull(string? json, bool
Assert.AreEqual(hasObject ? JsonValueKind.Object : JsonValueKind.Null, result.RootElement.ValueKind);
}

/// <summary>
/// Regression test for https://github.com/Azure/data-api-builder/issues/3704
/// An empty cached read surfaces as a default (JsonValueKind.Undefined) JsonElement that has no
/// backing document. Serializing it previously threw InvalidOperationException (HTTP 500).
/// ParseResultIntoJsonDocument must instead return null, matching the non-cached empty-result path.
/// </summary>
[TestMethod]
public void ParseResultIntoJsonDocument_UndefinedElement_ReturnsNull()
{
JsonElement? undefined = default(JsonElement);
MethodInfo method = typeof(SqlQueryEngine).GetMethod(
"ParseResultIntoJsonDocument",
BindingFlags.Static | BindingFlags.NonPublic)!;

JsonDocument? result = (JsonDocument?)method.Invoke(null, new object?[] { undefined });

Assert.IsNull(result);
}

/// <summary>
/// Verifies stored-procedure execution returns the first result object and maps empty or absent result arrays to null.
/// </summary>
Expand Down
Loading