@@ -286,8 +286,9 @@ CreateSourceEventStream(subscription, schema, variableValues, initialValue):
286
286
selectionSet, variableValues)}.
287
287
- If {collectedFieldsMap} does not have exactly one entry, raise a _ request
288
288
error_ .
289
- - Let {fields} be the value of the first entry in {collectedFieldsMap}.
290
- - Let {fieldName} be the name of the first entry in {fields}. Note: This value
289
+ - Let {fieldInfo} be the value of the first entry in {collectedFieldsMap}.
290
+ - Let {field} be the value of the {field} property in {fieldInfo}.
291
+ - Let {fieldName} be the name of the first entry in {fields}' {field} property. Note: This value
291
292
is unaffected if an alias is used.
292
293
- Let {field} be the first entry in {fields}.
293
294
- Let {argumentValues} be the result of {CoerceArgumentValues(subscriptionType,
@@ -446,7 +447,8 @@ The depth-first-search order of the _field set_ produced by {CollectFields()} is
446
447
maintained through execution, ensuring that fields appear in the executed
447
448
response in a stable and predictable order.
448
449
449
- CollectFields(objectType, selectionSet, variableValues, visitedFragments):
450
+ CollectFields(objectType, selectionSet, variableValues, visitedFragments,
451
+ fragmentVariables):
450
452
451
453
- If {visitedFragments} is not provided, initialize it to the empty set.
452
454
- Initialize {collectedFieldsMap} to an empty ordered map of ordered sets.
@@ -464,10 +466,12 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
464
466
- If {selection} is a {Field}:
465
467
- Let {responseName} be the _ response name_ of {selection} (the alias if
466
468
defined, otherwise the field name).
467
- - Let {fieldsForResponseName} be the _ field set _ value in
469
+ - Let {fieldsForResponseName} be the _ field map _ value in
468
470
{collectedFieldsMap} for the key {responseName}; otherwise create the
469
471
entry with an empty ordered set.
470
- - Add {selection} to the {fieldsForResponseName}.
472
+ - Let {fieldDetails} be a new unordered map containing {fragmentVariables}.
473
+ - Set the entry for {field} on {fieldDetails} to {selection}.
474
+ - Add {fieldDetails} to the {fieldsForResponseName}.
471
475
- If {selection} is a {FragmentSpread}:
472
476
- Let {fragmentSpreadName} be the name of {selection}.
473
477
- If {fragmentSpreadName} is in {visitedFragments}, continue with the next
@@ -480,10 +484,19 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
480
484
- Let {fragmentType} be the type condition on {fragment}.
481
485
- If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
482
486
with the next {selection} in {selectionSet}.
487
+ - Let {variableDefinitions} be the variable definitions for {fragment}.
488
+ - Initialize {signatures} to an empty list.
489
+ - For each {variableDefinition} of {variableDefinitions}:
490
+ - Append the result of {GetVariableSignature(variableDefinition)} to
491
+ {signatures}.
492
+ - Let {values} be the result of {CoerceArgumentValues(fragment,
493
+ argumentDefinitions, variableValues, fragmentVariables)}.
494
+ - Let {newFragmentVariables} be an unordered map containing {signatures} and
495
+ {values}.
483
496
- Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
484
497
- Let {fragmentCollectedFieldMap} be the result of calling
485
498
{CollectFields(objectType, fragmentSelectionSet, variableValues,
486
- visitedFragments)}.
499
+ visitedFragments, newFragmentVariables )}.
487
500
- For each {responseName} and {fragmentFields} in
488
501
{fragmentCollectedFieldMap}:
489
502
- Let {fieldsForResponseName} be the _ field set_ value in
@@ -498,7 +511,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
498
511
- Let {fragmentSelectionSet} be the top-level selection set of {selection}.
499
512
- Let {fragmentCollectedFieldMap} be the result of calling
500
513
{CollectFields(objectType, fragmentSelectionSet, variableValues,
501
- visitedFragments)}.
514
+ visitedFragments, fragmentVariables )}.
502
515
- For each {responseName} and {fragmentFields} in
503
516
{fragmentCollectedFieldMap}:
504
517
- Let {fieldsForResponseName} be the _ field set_ value in
@@ -562,11 +575,11 @@ CollectSubfields(objectType, fields, variableValues):
562
575
- If {fieldSelectionSet} is null or empty, continue to the next field.
563
576
- Let {fieldCollectedFieldMap} be the result of {CollectFields(objectType,
564
577
fieldSelectionSet, variableValues)}.
565
- - For each {responseName} and {subfields } in {fieldCollectedFieldMap}:
578
+ - For each {responseName} and {subfieldInfos } in {fieldCollectedFieldMap}:
566
579
- Let {fieldsForResponseName} be the _ field set_ value in
567
580
{collectedFieldsMap} for the key {responseName}; otherwise create the
568
581
entry with an empty ordered set.
569
- - Add each fields from {subfields} to {fieldsForResponseName}.
582
+ - Add each fieldInfo from {subfields} to {fieldsForResponseName}.
570
583
- Return {collectedFieldsMap}.
571
584
572
585
Note: All the {fields} passed to {CollectSubfields()} share the same _ response
@@ -585,11 +598,12 @@ ExecuteCollectedFields(collectedFieldsMap, objectType, objectValue,
585
598
variableValues):
586
599
587
600
- Initialize {resultMap} to an empty ordered map.
588
- - For each {responseName} and {fields} in {collectedFieldsMap}:
601
+ - For each {responseName} and {fieldInfos} in {collectedFieldsMap}:
602
+ - Let {fieldInfo} be the first entry in {fieldInfos}.
603
+ - Let {field} be the field property of {fieldInfo}.
589
604
- Let {fieldName} be the name of the first entry in {fields}. Note: This value
590
605
is unaffected if an alias is used.
591
- - Let {fragmentVariableValues} be the fragment-variables value of the first
592
- entry in {fields}.
606
+ - Let {fragmentVariableValues} be the fragmentVariables property of {fieldInfo}.
593
607
- Let {fieldType} be the return type defined for the field {fieldName} of
594
608
{objectType}.
595
609
- If {fieldType} is defined:
@@ -720,134 +734,6 @@ A correct executor must generate the following result for that _selection set_:
720
734
}
721
735
```
722
736
723
- ### Field Collection
724
-
725
- Before execution, the _ selection set_ is converted to a grouped field set by
726
- calling {CollectFields()}. Each entry in the grouped field set is a list of
727
- fields that share a response key (the alias if defined, otherwise the field
728
- name). This ensures all fields with the same response key (including those in
729
- referenced fragments) are executed at the same time.
730
-
731
- As an example, collecting the fields of this selection set would collect two
732
- instances of the field ` a ` and one of field ` b ` :
733
-
734
- ``` graphql example
735
- {
736
- a {
737
- subfield1
738
- }
739
- ... ExampleFragment
740
- }
741
-
742
- fragment ExampleFragment on Query {
743
- a {
744
- subfield2
745
- }
746
- b
747
- }
748
- ```
749
-
750
- The depth-first-search order of the field groups produced by {CollectFields()}
751
- is maintained through execution, ensuring that fields appear in the executed
752
- response in a stable and predictable order.
753
-
754
- CollectFields(objectType, selectionSet, variableValues, visitedFragments,
755
- fragmentVariables):
756
-
757
- - If {visitedFragments} is not provided, initialize it to the empty set.
758
- - Initialize {groupedFields} to an empty ordered map of lists.
759
- - For each {selection} in {selectionSet}:
760
- - If {selection} provides the directive ` @skip ` , let {skipDirective} be that
761
- directive.
762
- - Let {directiveValues} be the result of {GetDirectiveValues(skipDirective,
763
- variableValues, fragmentVariables)}.
764
- - If the entry for the {if} argument within {directiveValues} is {true},
765
- continue with the next {selection} in {selectionSet}.
766
- - If {selection} provides the directive ` @include ` , let {includeDirective} be
767
- that directive.
768
- - Let {directiveValues} be the result of
769
- {GetDirectiveValues(includeDirective, variableValues, fragmentVariables)}.
770
- - If the entry for the {if} argument within {directiveValues} is not {true},
771
- - If {selection} is a {Field}:
772
- - Let {responseKey} be the response key of {selection} (the alias if
773
- defined, otherwise the field name).
774
- - Let {groupForResponseKey} be the list in {groupedFields} for
775
- {responseKey}; if no such list exists, create it as an empty list.
776
- - Let {fieldDetails} be a new unordered map containing {fragmentVariables}.
777
- - Set the entry for {field} on {fieldDetails} to {selection}.
778
- - Append {fieldDetails} to the {groupForResponseKey}.
779
- - If {selection} is a {FragmentSpread}:
780
- - Let {fragmentSpreadName} be the name of {selection}.
781
- - If {fragmentSpreadName} is in {visitedFragments}, continue with the next
782
- {selection} in {selectionSet}.
783
- - Add {fragmentSpreadName} to {visitedFragments}.
784
- - Let {fragment} be the Fragment in the current Document whose name is
785
- {fragmentSpreadName}.
786
- - If no such {fragment} exists, continue with the next {selection} in
787
- {selectionSet}.
788
- - Let {fragmentType} be the type condition on {fragment}.
789
- - If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
790
- with the next {selection} in {selectionSet}.
791
- - Let {variableDefinitions} be the variable definitions for {fragment}.
792
- - Initialize {signatures} to an empty list.
793
- - For each {variableDefinition} of {variableDefinitions}:
794
- - Append the result of {GetVariableSignature(variableDefinition)} to
795
- {signatures}.
796
- - Let {values} be the result of {CoerceArgumentValues(fragment,
797
- argumentDefinitions, variableValues, fragmentVariables)}.
798
- - Let {newFragmentVariables} be an unordered map containing {signatures} and
799
- {values}.
800
- - Let {fragmentGroupedFieldSet} be the result of calling
801
- {CollectFields(objectType, fragmentSelectionSet, variableValues,
802
- visitedFragments, newFragmentVariables)}.
803
- - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
804
- - Let {responseKey} be the response key shared by all fields in
805
- {fragmentGroup}.
806
- - Let {groupForResponseKey} be the list in {groupedFields} for
807
- {responseKey}; if no such list exists, create it as an empty list.
808
- - Append all items in {fragmentGroup} to {groupForResponseKey}.
809
- - If {selection} is an {InlineFragment}:
810
- - Let {fragmentType} be the type condition on {selection}.
811
- - If {fragmentType} is not {null} and {DoesFragmentTypeApply(objectType,
812
- fragmentType)} is {false}, continue with the next {selection} in
813
- {selectionSet}.
814
- - Let {fragmentSelectionSet} be the top-level selection set of {selection}.
815
- - Let {fragmentGroupedFieldSet} be the result of calling
816
- {CollectFields(objectType, fragmentSelectionSet, variableValues,
817
- visitedFragments, fragmentVariables)}.
818
- - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
819
- - Let {responseKey} be the response key shared by all fields in
820
- {fragmentGroup}.
821
- - Let {groupForResponseKey} be the list in {groupedFields} for
822
- {responseKey}; if no such list exists, create it as an empty list.
823
- - Append all items in {fragmentGroup} to {groupForResponseKey}.
824
- - Return {groupedFields}.
825
-
826
- DoesFragmentTypeApply(objectType, fragmentType):
827
-
828
- - If {fragmentType} is an Object Type:
829
- - If {objectType} and {fragmentType} are the same type, return {true},
830
- otherwise return {false}.
831
- - If {fragmentType} is an Interface Type:
832
- - If {objectType} is an implementation of {fragmentType}, return {true}
833
- otherwise return {false}.
834
- - If {fragmentType} is a Union:
835
- - If {objectType} is a possible type of {fragmentType}, return {true}
836
- otherwise return {false}.
837
-
838
- Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
839
- directives may be applied in either order since they apply commutatively.
840
-
841
- GetDirectiveValues(directive, variableValues, fragmentVariables):
842
-
843
- - Let {directiveName} be the name of {directive}.
844
- - Let {directiveDefinition} be the definition for {directiveName} within the
845
- schema.
846
- - Assert {directiveDefinition} is defined.
847
- - Let {argumentDefinitions} be the arguments defined by {directiveDefinition}.
848
- - Return the result of {CoerceArgumentValues(directiveDefinition,
849
- argumentDefinitions, variableValues, fragmentVariables)}.
850
-
851
737
## Executing Fields
852
738
853
739
Each entry in a result map is the result of executing a field on an object type
@@ -856,19 +742,16 @@ first coerces any provided argument values, then resolves a value for the field,
856
742
and finally completes that value either by recursively executing another
857
743
selection set or coercing a scalar value.
858
744
859
- ### TODO: this needs updating
860
-
861
- ExecuteField(objectType, objectValue, fieldType, fields, variableValues,
862
- fragmentVariableValues):
745
+ ExecuteField(objectType, objectValue, fieldType, fieldDetailsList, variableValues,
746
+ fragmentVariables):
863
747
864
- - Let {field} be the first entry in {fields}.
748
+ - Let {fieldDetails} be the first entry in {fieldDetailsList}.
749
+ - Let {field} and {fragmentVariables} be the corresponding entries on {fieldDetails}.
865
750
- Let {fieldName} be the field name of {field}.
866
- - Let {argumentValues} be the result of {CoerceFieldArgumentValues(objectType,
867
- field, variableValues, fragmentVariableValues)}
868
- - Let {resolvedValue} be {ResolveFieldValue(objectType, objectValue, fieldName,
869
- argumentValues)}.
870
- - Return the result of {CompleteValue(fieldType, fields, resolvedValue,
871
- variableValues)}.
751
+ - Let {argumentDefinitions} be the arguments defined by {objectType} for the field named {fieldName}.
752
+ - Let {argumentValues} be the result of {CoerceArgumentValues(field, argumentDefinitions, variableValues, fragmentVariables)}.
753
+ - Let {resolvedValue} be {ResolveFieldValue(objectType, objectValue, fieldName, argumentValues)}.
754
+ Return the result of {CompleteValue(fieldType, fieldDetailsList, resolvedValue, variableValues)}.
872
755
873
756
### Coercing Arguments
874
757
@@ -977,14 +860,12 @@ the expected return type. If the return type is another Object type, then the
977
860
field execution process continues recursively by collecting and executing
978
861
subfields.
979
862
980
- ### TODO: needs updating with fieldDetails
981
-
982
- CompleteValue(fieldType, fields, result, variableValues):
863
+ CompleteValue(fieldType, fieldDetailsList, result, variableValues):
983
864
984
865
- If the {fieldType} is a Non-Null type:
985
866
- Let {innerType} be the inner type of {fieldType}.
986
867
- Let {completedResult} be the result of calling {CompleteValue(innerType,
987
- fields , result, variableValues)}.
868
+ fieldDetailsList , result, variableValues)}.
988
869
- If {completedResult} is {null}, raise an _ execution error_ .
989
870
- Return {completedResult}.
990
871
- If {result} is {null} (or another internal value similar to {null} such as
@@ -993,7 +874,7 @@ CompleteValue(fieldType, fields, result, variableValues):
993
874
- If {result} is not a collection of values, raise an _ execution error_ .
994
875
- Let {innerType} be the inner type of {fieldType}.
995
876
- Return a list where each list item is the result of calling
996
- {CompleteValue(innerType, fields , resultItem, variableValues)}, where
877
+ {CompleteValue(innerType, fieldDetailsList , resultItem, variableValues)}, where
997
878
{resultItem} is each item in {result}.
998
879
- If {fieldType} is a Scalar or Enum type:
999
880
- Return the result of {CoerceResult(fieldType, result)}.
@@ -1003,7 +884,7 @@ CompleteValue(fieldType, fields, result, variableValues):
1003
884
- Otherwise if {fieldType} is an Interface or Union type.
1004
885
- Let {objectType} be {ResolveAbstractType(fieldType, result)}.
1005
886
- Let {collectedFieldsMap} be the result of calling
1006
- {CollectSubfields(objectType, fields , variableValues)}.
887
+ {CollectSubfields(objectType, fieldDetailsList , variableValues)}.
1007
888
- Return the result of evaluating {ExecuteCollectedFields(collectedFieldsMap,
1008
889
objectType, result, variableValues)} _ normally_ (allowing for
1009
890
parallelization).
0 commit comments