@@ -579,22 +579,52 @@ ExecuteField(objectType, objectValue, fieldType, fields, variableValues):
579
579
## Accounting For Client Controlled Nullability Designators
580
580
581
581
A field can have its nullability status set either in its service's schema, or
582
- it can be overriden by a designator (! or ?) for the duration of an execution.
582
+ a nullability designator (! or ?) can override it for the duration of an execution.
583
583
In order to determine a field's true nullability, both are taken into account
584
584
and a final type is produced.
585
585
586
586
ModifiedOutputType(outputType, requiredStatus):
587
587
588
- - If {requiredStatus} is 'required' and {outputType} is not a Non-Nullable type:
589
- - Return Non-Null with an inner type of {outputType}.
590
- - Otherwise if {requiredStatus} is 'optional':
591
- - If {outputType} is not a Non-Nullable type:
592
- - Return {outputType}.
593
- - Otherwise if {outputType} is a Non-Nullable type:
594
- - Let {innerOutputType} be the inner type of {outputType}.
595
- - Return {innerOutputType}.
596
- - Otherwise:
597
- - Return {outputType}.
588
+ - Create a {stack} initially containing {type}.
589
+ - As long as the top of {stack} is a list:
590
+ - Let {currentType} be the top item of {stack}.
591
+ - Push the {elementType} of {currentType} to the {stack}.
592
+ - If {requiredStatus} exists:
593
+ - Start visiting {node}s in {requiredStatus} and building up a {resultingType}:
594
+ - For each {node} that is a RequiredDesignator:
595
+ - If {resultingType} exists:
596
+ - Let {nullableResult} be the nullable type of {resultingType}.
597
+ - Set {resultingType} to the Non-Nullable type of {nullableResult}.
598
+ - Continue onto the next node.
599
+ - Pop the top of {stack} and let {nextType} be the result.
600
+ - Let {nullableType} be the nullable type of {nextType}.
601
+ - Set {resultingType} to the Non-Nullable type of {nullableType}.
602
+ - Continue onto the next node.
603
+ - For each {node} that is a OptionalDesignator:
604
+ - If {resultingType} exists:
605
+ - Set {resultingType} to the nullableType type of {resultingType}.
606
+ - Continue onto the next node.
607
+ - Pop the top of {stack} and let {nextType} be the result.
608
+ - Set {resultingType} to the nullable type of {resultingType}
609
+ - Continue onto the next node.
610
+ - For each {node} that is a ListNullabilityDesignator:
611
+ - Pop the top of {stack} and let {listType} be the result
612
+ - If the nullable type of {listType} is not a list
613
+ - Pop the top of {stack} and set {listType} to the result
614
+ - If {listType} does not exist:
615
+ - Throw an error because {requiredStatus} had more list dimensions than {outputType} and is invalid.
616
+ - If {resultingType} exist:
617
+ - If {listType} is Non-Nullable:
618
+ - Set {resultingType} to a Non-Nullable list where the element is {resultingType}.
619
+ - Otherwise:
620
+ - Set {resultingType} to a list where the element is {resultingType}.
621
+ - Continue onto the next node.
622
+ - Set {resultingType} to {listType}
623
+ - If {stack} is not empty:
624
+ - Throw an error because {requiredStatus} had fewer list dimensions than {outputType} and is invalid.
625
+ - Return {resultingType}.
626
+ - Otherwise:
627
+ - Return {outputType}.
598
628
599
629
### Coercing Field Arguments
600
630
0 commit comments