@@ -564,30 +564,49 @@ Each field requested in the grouped field set that is defined on the selected
564
564
objectType will result in an entry in the response map. Field execution first
565
565
coerces any provided argument values, then resolves a value for the field, and
566
566
finally completes that value either by recursively executing another selection
567
- set or coercing a scalar value.
567
+ set or coercing a scalar value. ` ccnPropagationPairs ` is an unordered map where
568
+ the keys are paths of required fields, and values are paths of the nearest
569
+ optional parent to those required fields. ` currentPropagationPath ` starts as an
570
+ empty path to indicate that ` null ` propagation should continue until it hits
571
+ ` data ` if there is no optional field.
568
572
569
- ExecuteField(objectType, objectValue, fieldType, fields, variableValues):
573
+ ExecuteField(objectType, objectValue, fieldType, fields, variableValues,
574
+ currentPropagationPath, ccnPropagationPairs):
570
575
571
576
- Let {field} be the first entry in {fields}.
572
577
- Let {fieldName} be the field name of {field}.
573
578
- Let {requiredStatus} be the required status of {field}.
579
+ - Let {newPropagationPath} be {path} if {requiredStatus} is optional, otherwise
580
+ let {newPropagationPath} be {currentPropagationPath}
581
+ - If {requiredStatus} is optional:
582
+ - Let {newPropagationPath} be {path}
583
+ - If {requiredStatus} is required:
584
+ - Set {path} to {newPropagationPath} in {ccnPropagationPairs}
574
585
- Let {argumentValues} be the result of {CoerceArgumentValues(objectType, field,
575
586
variableValues)}
576
587
- Let {resolvedValue} be {ResolveFieldValue(objectType, objectValue, fieldName,
577
588
argumentValues)}.
578
- - Let {modifiedFieldType} be {ModifiedOutputType (fieldType, requiredStatus)}.
589
+ - Let {modifiedFieldType} be {ApplyRequiredStatus (fieldType, requiredStatus)}.
579
590
- Return the result of {CompleteValue(modifiedFieldType, fields, resolvedValue,
580
- variableValues)}.
591
+ variableValues, newPropagationPath, ccnPropagationPairs )}.
581
592
582
593
## Accounting For Client Controlled Nullability Designators
583
594
584
595
A field can have its nullability status set either in its service's schema, or a
585
- nullability designator (! or ? ) can override it for the duration of an
596
+ nullability designator (` ! ` or ` ? ` ) can override it for the duration of an
586
597
execution. In order to determine a field's true nullability, both are taken into
587
- account and a final type is produced.
588
-
589
- ModifiedOutputType(outputType, requiredStatus):
590
-
598
+ account and a final type is produced. A field marked with a ` ! ` is called a
599
+ "required field" and a field marked with a ` ? ` is called an optional field.
600
+
601
+ ApplyRequiredStatus(type, requiredStatus):
602
+
603
+ - If there is no {requiredStatus}:
604
+ - return {type}
605
+ - If {requiredStatus} is not a list:
606
+ - If {requiredStatus} is required:
607
+ - return a ` Non-Null ` version of {type}
608
+ - If {requiredStatus} is optional:
609
+ - return a nullable version of {type}
591
610
- Create a {stack} initially containing {type}.
592
611
- As long as the top of {stack} is a list:
593
612
- Let {currentType} be the top item of {stack}.
@@ -616,8 +635,8 @@ ModifiedOutputType(outputType, requiredStatus):
616
635
- If the nullable type of {listType} is not a list
617
636
- Pop the top of {stack} and set {listType} to the result
618
637
- If {listType} does not exist:
619
- - Throw an error because {requiredStatus} had more list dimensions than
620
- {outputType} and is invalid.
638
+ - Raise a field error because {requiredStatus} had more list dimensions
639
+ than {outputType} and is invalid.
621
640
- If {resultingType} exist:
622
641
- If {listType} is Non-Nullable:
623
642
- Set {resultingType} to a Non-Nullable list where the element is
@@ -627,11 +646,9 @@ ModifiedOutputType(outputType, requiredStatus):
627
646
- Continue onto the next node.
628
647
- Set {resultingType} to {listType}
629
648
- If {stack} is not empty:
630
- - Throw an error because {requiredStatus} had fewer list dimensions than
649
+ - Raise a field error because {requiredStatus} had fewer list dimensions than
631
650
{outputType} and is invalid.
632
651
- Return {resultingType}.
633
- - Otherwise:
634
- - Return {outputType}.
635
652
636
653
### Coercing Field Arguments
637
654
@@ -835,8 +852,9 @@ response.
835
852
836
853
If the result of resolving a field is {null} (either because the function to
837
854
resolve the field returned {null} or because a field error was raised), and the
838
- {ModifiedOutputType} of that field is of a ` Non-Null ` type, then a field error
839
- is raised. The error must be added to the {"errors"} list in the response.
855
+ type of the field after {ApplyRequiredStatus} has been applied to it is of a
856
+ ` Non-Null ` type, then a field error is raised. The error must be added to the
857
+ {"errors"} list in the response.
840
858
841
859
If the field returns {null} because of a field error which has already been
842
860
added to the {"errors"} list in the response, the {"errors"} list must not be
@@ -845,8 +863,11 @@ field.
845
863
846
864
Since ` Non-Null ` type fields cannot be {null}, field errors are propagated to be
847
865
handled by the parent field. If the parent field may be {null} then it resolves
848
- to {null}, otherwise if its {ModifiedOutputType} is a ` Non-Null ` type, the field
849
- error is further propagated to its parent field.
866
+ to {null}, otherwise if it is a ` Non-Null ` type, the field error is further
867
+ propagated to its parent field.
868
+
869
+ If a required field resolves to {null}, propagation instead happens until an
870
+ optional field is found.
850
871
851
872
If a ` List ` type wraps a ` Non-Null ` type, and one of the elements of that list
852
873
resolves to {null}, then the entire list must resolve to {null}. If the ` List `
0 commit comments