@@ -286,8 +286,9 @@ CreateSourceEventStream(subscription, schema, variableValues, initialValue):
286286 selectionSet, variableValues)}.
287287- If {collectedFieldsMap} does not have exactly one entry, raise a _ request
288288 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
291292 is unaffected if an alias is used.
292293- Let {field} be the first entry in {fields}.
293294- 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
446447maintained through execution, ensuring that fields appear in the executed
447448response in a stable and predictable order.
448449
449- CollectFields(objectType, selectionSet, variableValues, visitedFragments):
450+ CollectFields(objectType, selectionSet, variableValues, visitedFragments,
451+ fragmentVariables):
450452
451453- If {visitedFragments} is not provided, initialize it to the empty set.
452454- Initialize {collectedFieldsMap} to an empty ordered map of ordered sets.
@@ -464,10 +466,12 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
464466 - If {selection} is a {Field}:
465467 - Let {responseName} be the _ response name_ of {selection} (the alias if
466468 defined, otherwise the field name).
467- - Let {fieldsForResponseName} be the _ field set _ value in
469+ - Let {fieldsForResponseName} be the _ field map _ value in
468470 {collectedFieldsMap} for the key {responseName}; otherwise create the
469471 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}.
471475 - If {selection} is a {FragmentSpread}:
472476 - Let {fragmentSpreadName} be the name of {selection}.
473477 - If {fragmentSpreadName} is in {visitedFragments}, continue with the next
@@ -480,10 +484,19 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
480484 - Let {fragmentType} be the type condition on {fragment}.
481485 - If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
482486 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}.
483496 - Let {fragmentSelectionSet} be the top-level selection set of {fragment}.
484497 - Let {fragmentCollectedFieldMap} be the result of calling
485498 {CollectFields(objectType, fragmentSelectionSet, variableValues,
486- visitedFragments)}.
499+ visitedFragments, newFragmentVariables )}.
487500 - For each {responseName} and {fragmentFields} in
488501 {fragmentCollectedFieldMap}:
489502 - Let {fieldsForResponseName} be the _ field set_ value in
@@ -498,7 +511,7 @@ CollectFields(objectType, selectionSet, variableValues, visitedFragments):
498511 - Let {fragmentSelectionSet} be the top-level selection set of {selection}.
499512 - Let {fragmentCollectedFieldMap} be the result of calling
500513 {CollectFields(objectType, fragmentSelectionSet, variableValues,
501- visitedFragments)}.
514+ visitedFragments, fragmentVariables )}.
502515 - For each {responseName} and {fragmentFields} in
503516 {fragmentCollectedFieldMap}:
504517 - Let {fieldsForResponseName} be the _ field set_ value in
@@ -562,11 +575,11 @@ CollectSubfields(objectType, fields, variableValues):
562575 - If {fieldSelectionSet} is null or empty, continue to the next field.
563576 - Let {fieldCollectedFieldMap} be the result of {CollectFields(objectType,
564577 fieldSelectionSet, variableValues)}.
565- - For each {responseName} and {subfields } in {fieldCollectedFieldMap}:
578+ - For each {responseName} and {subfieldInfos } in {fieldCollectedFieldMap}:
566579 - Let {fieldsForResponseName} be the _ field set_ value in
567580 {collectedFieldsMap} for the key {responseName}; otherwise create the
568581 entry with an empty ordered set.
569- - Add each fields from {subfields} to {fieldsForResponseName}.
582+ - Add each fieldInfo from {subfields} to {fieldsForResponseName}.
570583- Return {collectedFieldsMap}.
571584
572585Note: All the {fields} passed to {CollectSubfields()} share the same _ response
@@ -585,11 +598,12 @@ ExecuteCollectedFields(collectedFieldsMap, objectType, objectValue,
585598variableValues):
586599
587600- 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}.
589604 - Let {fieldName} be the name of the first entry in {fields}. Note: This value
590605 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}.
593607 - Let {fieldType} be the return type defined for the field {fieldName} of
594608 {objectType}.
595609 - If {fieldType} is defined:
@@ -720,134 +734,6 @@ A correct executor must generate the following result for that _selection set_:
720734}
721735```
722736
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-
851737## Executing Fields
852738
853739Each 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,
856742and finally completes that value either by recursively executing another
857743selection set or coercing a scalar value.
858744
859- ### TODO: this needs updating
860-
861- ExecuteField(objectType, objectValue, fieldType, fields, variableValues,
862- fragmentVariableValues):
745+ ExecuteField(objectType, objectValue, fieldType, fieldDetailsList, variableValues,
746+ fragmentVariables):
863747
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}.
865750- 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)}.
872755
873756### Coercing Arguments
874757
@@ -977,14 +860,12 @@ the expected return type. If the return type is another Object type, then the
977860field execution process continues recursively by collecting and executing
978861subfields.
979862
980- ### TODO: needs updating with fieldDetails
981-
982- CompleteValue(fieldType, fields, result, variableValues):
863+ CompleteValue(fieldType, fieldDetailsList, result, variableValues):
983864
984865- If the {fieldType} is a Non-Null type:
985866 - Let {innerType} be the inner type of {fieldType}.
986867 - Let {completedResult} be the result of calling {CompleteValue(innerType,
987- fields , result, variableValues)}.
868+ fieldDetailsList , result, variableValues)}.
988869 - If {completedResult} is {null}, raise an _ execution error_ .
989870 - Return {completedResult}.
990871- If {result} is {null} (or another internal value similar to {null} such as
@@ -993,7 +874,7 @@ CompleteValue(fieldType, fields, result, variableValues):
993874 - If {result} is not a collection of values, raise an _ execution error_ .
994875 - Let {innerType} be the inner type of {fieldType}.
995876 - 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
997878 {resultItem} is each item in {result}.
998879- If {fieldType} is a Scalar or Enum type:
999880 - Return the result of {CoerceResult(fieldType, result)}.
@@ -1003,7 +884,7 @@ CompleteValue(fieldType, fields, result, variableValues):
1003884 - Otherwise if {fieldType} is an Interface or Union type.
1004885 - Let {objectType} be {ResolveAbstractType(fieldType, result)}.
1005886 - Let {collectedFieldsMap} be the result of calling
1006- {CollectSubfields(objectType, fields , variableValues)}.
887+ {CollectSubfields(objectType, fieldDetailsList , variableValues)}.
1007888 - Return the result of evaluating {ExecuteCollectedFields(collectedFieldsMap,
1008889 objectType, result, variableValues)} _ normally_ (allowing for
1009890 parallelization).
0 commit comments