Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ public ImmutableArray<SatisfiabilityError> Validate(
MutableObjectTypeDefinition contextType,
SatisfiabilityPathItem? parentPathItem,
string excludeSchemaName,
bool allowIntermediatesFromExcludedSchema = false,
SatisfiabilityPath? cycleDetectionPath = null)
{
var context = new RequirementsValidatorContext(
contextType,
parentPathItem,
excludeSchemaName,
allowIntermediatesFromExcludedSchema,
cycleDetectionPath);

var errors = new List<SatisfiabilityError>();
Expand Down Expand Up @@ -138,7 +140,19 @@ private ImmutableArray<SatisfiabilityError> Visit(
return [];
}

var schemaNames = field.GetSchemaNames().Remove(context.ExcludeSchemaName);
// Leaf fields in the requirement must be sourced from outside the
// excluded schema. Intermediate fields (with a sub-selection) may also
// be sourced from the excluded schema when validating a field-level
// @require: those intermediates are navigation steps the gateway can
// resolve locally in the requiring schema as part of executing the
// requiring field. For lookup-key validation the excluded schema has
// not been entered yet, so intermediates must also come from outside
// it (default behavior).
var schemaNames = field.GetSchemaNames();
if (fieldNode.SelectionSet is null || !context.AllowIntermediatesFromExcludedSchema)
{
schemaNames = schemaNames.Remove(context.ExcludeSchemaName);
}
var fieldType = field.Type.AsTypeDefinition();

foreach (var schemaName in schemaNames)
Expand Down Expand Up @@ -202,7 +216,8 @@ private ImmutableArray<SatisfiabilityError> Visit(
type,
context.Path.Peek(),
excludeSchemaName: schemaName,
context.CycleDetectionPath);
allowIntermediatesFromExcludedSchema: true,
cycleDetectionPath: context.CycleDetectionPath);

if (requirementErrors.Length != 0)
{
Expand Down Expand Up @@ -299,7 +314,7 @@ private ImmutableArray<SatisfiabilityError> ValidateSourceSchemaTransition(
contextType,
parentPathItem,
excludeSchemaName: transitionToSchemaName,
context.CycleDetectionPath),
cycleDetectionPath: context.CycleDetectionPath),
RequirementsValidator_NoLookupsFoundForType,
RequirementsValidator_UnableToSatisfyRequirementForLookup);
}
Expand All @@ -311,6 +326,7 @@ public RequirementsValidatorContext(
MutableObjectTypeDefinition contextType,
SatisfiabilityPathItem? parentPathItem,
string excludeSchemaName,
bool allowIntermediatesFromExcludedSchema = false,
SatisfiabilityPath? cycleDetectionPath = null)
{
TypeContext.Push(contextType);
Expand All @@ -321,6 +337,7 @@ public RequirementsValidatorContext(
}

ExcludeSchemaName = excludeSchemaName;
AllowIntermediatesFromExcludedSchema = allowIntermediatesFromExcludedSchema;
CycleDetectionPath = cycleDetectionPath ?? [];
}

Expand All @@ -330,6 +347,8 @@ public RequirementsValidatorContext(

public string ExcludeSchemaName { get; }

public bool AllowIntermediatesFromExcludedSchema { get; }

public SatisfiabilityPath CycleDetectionPath { get; }

public HashSet<FieldAccessCacheKey> FieldAccessCache { get; } = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ private void VisitOutputField(
requirements,
type,
path?.Item,
excludeSchemaName: schemaName);
excludeSchemaName: schemaName,
allowIntermediatesFromExcludedSchema: true);

if (requirementErrors.Length != 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1790,11 +1790,7 @@ type Movie @key(fields: "id") {
Assert.True(result.IsSuccess);
}

[Fact(Skip = "Circular @require whose intermediate field is owned by the "
+ "requiring schema is not yet satisfiable. The validator evaluates the "
+ "requirement from the entity's origin path and does not hop into the "
+ "requiring schema to gather its locally-owned field first. Enable once "
+ "multi-hop requirement gathering is supported.")]
[Fact]
// https://github.com/graphql-hive/federation-gateway-audit/tree/main/src/test-suites/requires-circular
public void RequiresCircular()
{
Expand Down
Loading