Skip to content

Make cursor key extraction null-safe for nullable nested fields - #9953

Merged
glen-84 merged 2 commits into
mainfrom
gai/null-safe-nested-cursor-keys
Jun 19, 2026
Merged

glen-84 merged 2 commits into
mainfrom
gai/null-safe-nested-cursor-keys

Conversation

@glen-84

@glen-84 glen-84 commented Jun 19, 2026

Copy link
Copy Markdown
Member

Summary

  • Sorting a cursor-paginated connection on a nullable nested field (e.g. order: [{ meter: { name: ASC } }]) crashed with "Unexpected Execution Error" whenever an intermediate navigation was null: the cursor key selector was compiled and invoked verbatim, so it dereferenced the null and threw. The crash surfaced for Connection-returning resolvers (which eagerly create start/end cursors) even when no cursor field was selected.
  • CursorKey now compiles the selector into a null-safe delegate (NullSafeKeySelector) that mirrors the C# null-conditional operator: each nullable intermediate is bound to a local and evaluated once, reference / HasValue null checks short-circuit to a null key value (which the serializer already formats as the null marker), and intermediate casts/conversions are preserved so member access rebinds against the correct type.

Test plan

  • Added CursorFormatterTests covering null and non-null nested intermediates, deep chains, single evaluation (counting getter), overloaded ==, a nullable value-type intermediate, and a cast intermediate.
  • GreenDonut.Data.Tests: 364/364 pass.
  • PostgreSQL nullable cursor round-trip tests: 9/9 pass.

Copilot AI review requested due to automatic review settings June 19, 2026 10:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes cursor key extraction for cursor-paginated connections when sorting by nullable nested fields by compiling cursor key selectors into a null-safe delegate that short-circuits to a null key instead of throwing on null intermediates.

Changes:

  • Compile cursor key selector expressions into a null-safe delegate (NullSafeKeySelector) that mirrors C#’s null-conditional behavior and evaluates intermediates once.
  • Add unit tests covering null/non-null nested intermediates, deep chains, single evaluation, overloaded equality, nullable value-type intermediates, and cast intermediates.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/GreenDonut/src/GreenDonut.Data/Cursors/CursorKey.cs Switches key selector compilation to a null-safe compiler to prevent null dereference crashes during cursor formatting.
src/GreenDonut/test/GreenDonut.Data.Tests/Cursors/CursorFormatterTests.cs Adds focused tests validating null-safe nested cursor key formatting behavior across several edge cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/GreenDonut/src/GreenDonut.Data/Cursors/CursorKey.cs
@github-code-quality

github-code-quality Bot commented Jun 19, 2026 •

Copy link
Copy Markdown

Code Coverage Overview

Languages: C#

C# / code-coverage/dotnet

The overall coverage in the gai/null-safe-nested... branch remains at 49%, unchanged from the main branch.

Show a code coverage summary of the most impacted files.
File main 03ba3ad gai/null-safe-nested... 609c3a5 +/-
/home/runner/wo...ageProcessor.cs 100% 89% -11%
/home/runner/wo...heMiddleware.cs 92% 86% -6%
/home/runner/wo...boxProcessor.cs 72% 74% +2%
/home/runner/wo...DefaultTopic.cs 88% 90% +2%
/home/runner/wo...tocolHandler.cs 82% 84% +2%
/home/runner/wo...efaultPubSub.cs 89% 91% +2%
/home/runner/wo...geDispatcher.cs 73% 77% +4%
/home/runner/wo...r.Observable.cs 78% 85% +7%
/home/runner/wo...erMiddleware.cs 89% 97% +8%
/home/runner/wo...gerMessage.g.cs 11% 19% +8%

Updated June 19, 2026 11:20 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@glen-84
glen-84 merged commit 8221f11 into main Jun 19, 2026
277 of 279 checks passed
@glen-84
glen-84 deleted the gai/null-safe-nested-cursor-keys branch June 19, 2026 11:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants