fix: check interface implementation in potentiallySameObject for nullability relaxation - #1454
Conversation
…ability relaxation When relax_subgraph_operation_field_selection_merging_nullability is enabled, field selection merging should allow nullability differences between types that cannot overlap at runtime. The potentiallySameObject function previously treated any interface+object pair as potentially overlapping, which prevented nullability relaxation even when the object type does not implement the interface. Split the single interface case into three: - both interfaces → conservatively assume overlap - interface + object → overlap only if the object implements the interface - two objects → overlap only if same type name
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe change updates field-selection-merging overlap logic. Interface/object pairs overlap only when the object implements the interface. New tests cover allowed and rejected nullability differences. ChangesField selection merging validation
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
potentiallySameObject for nullability relaxation
There was a problem hiding this comment.
🧹 Nitpick comments (1)
v2/pkg/astvalidation/operation_validation_test.go (1)
1137-1144: This test doesn’t prove the implementing-object overlap branch.
Printable.titleandBook.titleare bothString!, so this stays valid even ifpotentiallySameObjectwrongly treatsPrintable+Bookas non-overlapping. To lock down the new branch, make the interface/object pair differ in nullability and assert thatFieldSelectionMerging(true)still rejects them.🧪 Example adjustment
- t.Run("allows matching types on interface vs implementing object type with relaxation", func(t *testing.T) { + t.Run("rejects differing nullability on interface vs implementing object type with relaxation", func(t *testing.T) { runWithDefinition(t, interfaceNonImplementorDefinition, ` { item { - ... on Printable { title } - ... on Book { title } + ... on Printable { summary } + ... on Book { summary } } - }`, FieldSelectionMerging(true), Valid) + }`, FieldSelectionMerging(true), Invalid, + withValidationErrors(`fields 'summary' conflict because they return conflicting types 'String' and 'String!'`)) })And in
interfaceNonImplementorDefinition, add a field like:interface Printable { title: String! name: String! + summary: String } type Book implements Printable { title: String! name: String! + summary: String! } type Magazine implements Printable { title: String! name: String! + summary: String! }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@v2/pkg/astvalidation/operation_validation_test.go` around lines 1137 - 1144, The test "allows matching types on interface vs implementing object type with relaxation" currently uses Printable.title and Book.title both as String!, so it doesn't exercise the implementing-object overlap branch; change the schema in interfaceNonImplementorDefinition so the interface and the implementing object have the same field name with different nullability (e.g., Printable.title as String and Book.title as String! or vice versa) and update the assertion to expect rejection when FieldSelectionMerging(true) is applied, ensuring runWithDefinition(t, interfaceNonImplementorDefinition, ...) fails validation for that mismatch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@v2/pkg/astvalidation/operation_validation_test.go`:
- Around line 1137-1144: The test "allows matching types on interface vs
implementing object type with relaxation" currently uses Printable.title and
Book.title both as String!, so it doesn't exercise the implementing-object
overlap branch; change the schema in interfaceNonImplementorDefinition so the
interface and the implementing object have the same field name with different
nullability (e.g., Printable.title as String and Book.title as String! or vice
versa) and update the assertion to expect rejection when
FieldSelectionMerging(true) is applied, ensuring runWithDefinition(t,
interfaceNonImplementorDefinition, ...) fails validation for that mismatch.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: edecbe3f-1522-4aec-975b-2a06dceab6ca
📒 Files selected for processing (2)
v2/pkg/astvalidation/operation_rule_field_selection_merging.gov2/pkg/astvalidation/operation_validation_test.go
I'll resolve this |
|
Hi @davidomid. Is this PR ready for review again? |
ysmolski
left a comment
There was a problem hiding this comment.
LGTM, but need another vote from @devsergiy too
|
@davidomid @ysmolski have there been any updates? I'm running into the same issue. |
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
🤖 I have created a release *beep* *boop* --- ## [2.16.0](v2.15.1...v2.16.0) (2026-08-13) ### Features * implement multi fetch to the same subgraph ([#1594](#1594)) ([22584e2](22584e2)) * schedule fetch trees optimally ([#1612](#1612)) ([bd03deb](bd03deb)) ### Bug Fixes * check interface implementation in `potentiallySameObject` for nullability relaxation ([#1454](#1454)) ([5bacb9e](5bacb9e)) * improve handling of nullable lists for required fields ([#1631](#1631)) ([0af4dd3](0af4dd3)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: wundergraph-bot[bot] <285992168+wundergraph-bot[bot]@users.noreply.github.com>
Fixes #1455
Summary
When
RelaxSubgraphOperationFieldSelectionMergingNullabilityis enabled, field selection merging should allow nullability differences between types that cannot overlap at runtime. ThepotentiallySameObjectfunction previously treated any interface+object pair as potentially overlapping, which prevented nullability relaxation even when the object type does not implement the interface.Example
Using the existing
boxDefinitiontest schema, consider these types:NonNullStringBox1— an interface withscalar: String!StringBox— an object type that implementsSomeBoxbut does not implementNonNullStringBox1, withscalar: StringThe following query:
{ someBox { ... on NonNullStringBox1 { scalar } ... on StringBox { scalar } } }produces this validation error even with
RelaxSubgraphOperationFieldSelectionMergingNullabilityenabled:Since
StringBoxdoes not implementNonNullStringBox1, no runtime object can ever satisfy both type conditions simultaneously, so the nullability difference is safe to relax. After this fix, the query validates successfully when the relaxation flag is enabled.Fix
Updated
potentiallySameObjectto split the single interface case into three:true)NodeImplementsInterfaceNode)Testing
Two new test cases have been added alongside the existing
"disallows differing return type nullability when interface could overlap"test, reusing the sameboxDefinitionschema:"allows differing return type nullability on interface vs non implementing type with relaxation" — same query as the existing test (
NonNullStringBox1vsStringBox) but withFieldSelectionMerging(true)→Valid. Directly demonstrates the fix:StringBoxdoes not implementNonNullStringBox1, so relaxation applies."rejects differing return type nullability on interface vs implementing type even with relaxation" —
SomeBox(interface,scalar: String) vsNonNullStringBox1Impl(implementsSomeBox,scalar: String!),FieldSelectionMerging(true)→Invalid. Confirms that overlap detection still blocks relaxation when types actually overlap.Additionally, some manual tests have been done by:
wundergraph/cosmo.wundergraph/cosmobranch into a federation router service.Checklist
Open Source AI Manifesto
This project follows the principles of the Open Source AI Manifesto. Please ensure your contribution aligns with its principles.
Summary by CodeRabbit
Bug Fixes
Tests