Skip to content

feat: add type mismatch relaxation config for field selection merging#1395

Closed
jensneuse wants to merge 3 commits intomasterfrom
jensneuse/type-mismatch-config
Closed

feat: add type mismatch relaxation config for field selection merging#1395
jensneuse wants to merge 3 commits intomasterfrom
jensneuse/type-mismatch-config

Conversation

@jensneuse
Copy link
Copy Markdown
Member

@jensneuse jensneuse commented Feb 19, 2026

Summary

  • Adds RelaxSubgraphOperationFieldSelectionMergingTypeMismatch config flag that allows completely different field types (e.g., Int vs String) on fields within non-overlapping concrete object types inside inline fragments
  • This is a deliberate, safe relaxation of GraphQL spec section 5.3.2 (SameResponseShape) — when enclosing types are distinct concrete objects, only one branch contributes to the response at runtime
  • The new flag is a superset of the existing RelaxSubgraphOperationFieldSelectionMergingNullability flag: when set, it allows any type difference (including nullability), not just nullability mismatches

Test plan

  • 9 new validation rule test cases covering flag combinations, interface overlap rejection, and superset behavior
  • 1 new planning test verifying discriminated resolve.Field entries with OnTypeNames
  • 3 new end-to-end execution tests verifying rejection without flag, Int response, and String response
  • All existing tests pass (go test ./v2/... and go test ./execution/...)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for relaxing type mismatch validation during field selection merging in subgraph operations, providing more flexible handling of type incompatibilities in specific scenarios.
    • Introduced configurable validation options to enable type mismatch relaxation at the engine and planner levels.
  • Tests

    • Added comprehensive test coverage for field merging with different types on union types, validating behavior with and without relaxation enabled.

jensneuse and others added 3 commits February 19, 2026 07:36
Add a new configuration flag `RelaxSubgraphOperationFieldSelectionMergingTypeMismatch`
that allows completely differing field types (e.g. IssueState vs PullRequestReviewState,
or Int vs String) on fields in non-overlapping concrete object types within inline
fragments. This extends the existing nullability relaxation pattern and is gated
behind an opt-in flag across all 5 layers: validation rule, validator options,
plan configuration, datasource interface, and factory pool.

Includes unit tests (8 cases), planning tests, and execution integration tests (3 cases).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change the relaxation flag wiring in CreatePlannerConfiguration from
sequential if/if to if/else if, ensuring the broader type mismatch pool
is preferred when both flags are set. Add documentation explaining the
two-level relaxation hierarchy at the core validation logic, options
struct, and factory method.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change FieldSelectionMerging signature from variadic to pointer param
- Extract duplicated relaxation logic into canRelaxTypeMismatch helper
- Rename test for naming consistency ("allows" instead of "relaxes")
- Add test for both relaxation flags set simultaneously

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 19, 2026

📝 Walkthrough

Walkthrough

The PR extends the field selection merging validation framework by introducing a type-mismatch relaxation option that parallels the existing nullability relaxation. The feature is integrated across validation rules, planner configuration, execution engine initialization, and data source factory configuration.

Changes

Cohort / File(s) Summary
Validation Core
v2/pkg/astvalidation/operation_rule_field_selection_merging.go, v2/pkg/astvalidation/operation_validation.go
Adds FieldSelectionMergingOptions struct with RelaxTypeMismatchCheck flag; updates FieldSelectionMerging API from variadic bool parameter to pointer-based options; implements canRelaxTypeMismatch method for centralized relaxation logic; extends DefaultOperationValidator to propagate both nullability and type-mismatch relaxation settings.
Configuration & Planner
v2/pkg/engine/plan/configuration.go, v2/pkg/engine/plan/datasource_configuration.go
Adds RelaxSubgraphOperationFieldSelectionMergingTypeMismatch field to Configuration; introduces SubgraphFieldSelectionMergingTypeMismatchRelaxer interface; updates planner logic to delegate to type-mismatch relaxation when configured, with fallback to nullability relaxation.
Engine & Datasource
execution/engine/execution_engine.go, v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go
Adds conditional validation option registration in ExecutionEngine constructor when type-mismatch relaxation is enabled; introduces typeMismatchRelaxedPrintKitPool and EnableSubgraphFieldSelectionMergingTypeMismatchRelaxation factory method for GraphQL data source.
Tests
execution/engine/execution_engine_test.go, v2/pkg/astvalidation/operation_validation_test.go, v2/pkg/astvalidation/reference/testsgo/harness_test.go, v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_test.go
Updates all FieldSelectionMerging invocations to use explicit options pointers; adds new test helper relaxFieldSelectionMergingTypeMismatch(); introduces test scenarios validating field merging behavior with type mismatches on non-overlapping union types, both with and without relaxation.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Planner as Planner/Config
    participant DataSource as GraphQL DataSource
    participant Engine as Execution Engine
    participant Validator as AST Validator

    Client->>Planner: Create plan with config
    alt RelaxSubgraphOperationFieldSelectionMergingTypeMismatch enabled
        Planner->>DataSource: EnableSubgraphFieldSelectionMergingTypeMismatchRelaxation()
        DataSource->>DataSource: Use typeMismatchRelaxedPrintKitPool
        DataSource->>DataSource: Apply WithRelaxFieldSelectionMergingTypeMismatch()
    end
    
    Planner->>Engine: Initialize with relaxation flags
    Engine->>Validator: Append validation options
    
    alt Type mismatch in field selection
        Validator->>Validator: canRelaxTypeMismatch() check
        alt Relaxation enabled
            Validator->>Validator: Allow merge (type mismatch relaxed)
        else Relaxation disabled
            Validator->>Validator: Reject merge (type mismatch error)
        end
    end
    
    Validator-->>Engine: Validation result
    Engine-->>Client: Execution result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and clearly describes the main feature being added: a new type mismatch relaxation configuration for field selection merging validation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jensneuse/type-mismatch-config

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
v2/pkg/astvalidation/operation_validation_test.go (2)

5802-5838: Unused BotKind enum can be removed or used.

BotKind isn’t referenced in entityDefinition; either wire it into Bot for test coverage or remove it to keep the schema focused.

🤖 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 5802 - 5838,
The BotKind enum is declared but unused in the test schema; either remove the
unused enum BotKind or add a field on the Bot type that references it (e.g., a
"kind: BotKind" field) so BotKind is exercised; update the union Entity/ Bot
type accordingly (look for symbols BotKind, type Bot, and union Entity) and
adjust any tests expecting the previous shape.

1118-1215: Add an overlap guard test for scalar type mismatches.

You already assert that RelaxTypeMismatchCheck doesn’t apply when an interface overlap is possible (nullability case). Consider adding a scalar-type mismatch case (e.g., Int vs String) on overlapping interface/union types to ensure the relaxation never leaks beyond non‑overlapping concrete objects.

🤖 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 1118 - 1215,
Add a new test that mirrors the nullability overlap guard but for scalar type
mismatches: call runWithDefinition with the overlapping interface/union
definition (e.g., use boxDefinition or another interface-based definition that
makes potentiallySameObject=true), a query that selects the same scalar field
(e.g., score) on two overlapping inline fragments returning different scalar
types (Int vs String), pass
FieldSelectionMerging(&FieldSelectionMergingOptions{RelaxTypeMismatchCheck:
true}) and assert Invalid with a validation error like "fields 'score' conflict
because they return conflicting types 'Int' and 'String'". Place this alongside
the existing tests and follow their pattern using runWithDefinition,
FieldSelectionMerging, FieldSelectionMergingOptions, and withValidationErrors.
🤖 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 5802-5838: The BotKind enum is declared but unused in the test
schema; either remove the unused enum BotKind or add a field on the Bot type
that references it (e.g., a "kind: BotKind" field) so BotKind is exercised;
update the union Entity/ Bot type accordingly (look for symbols BotKind, type
Bot, and union Entity) and adjust any tests expecting the previous shape.
- Around line 1118-1215: Add a new test that mirrors the nullability overlap
guard but for scalar type mismatches: call runWithDefinition with the
overlapping interface/union definition (e.g., use boxDefinition or another
interface-based definition that makes potentiallySameObject=true), a query that
selects the same scalar field (e.g., score) on two overlapping inline fragments
returning different scalar types (Int vs String), pass
FieldSelectionMerging(&FieldSelectionMergingOptions{RelaxTypeMismatchCheck:
true}) and assert Invalid with a validation error like "fields 'score' conflict
because they return conflicting types 'Int' and 'String'". Place this alongside
the existing tests and follow their pattern using runWithDefinition,
FieldSelectionMerging, FieldSelectionMergingOptions, and withValidationErrors.

@jensneuse jensneuse closed this Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant