@@ -133,24 +133,24 @@ respectively.
133
133
### Query
134
134
135
135
If the operation is a query, the result of the operation is the result of
136
- executing the operation’s top level _ selection set_ with the query root
137
- operation type.
136
+ executing the operation’s _ root selection set_ with the query root operation
137
+ type.
138
138
139
139
An initial value may be provided when executing a query operation.
140
140
141
141
ExecuteQuery(query, schema, variableValues, initialValue):
142
142
143
143
- Let {queryType} be the root Query type in {schema}.
144
144
- Assert: {queryType} is an Object type.
145
- - Let {selectionSet } be the top level selection set in {query}.
145
+ - Let {rootSelectionSet } be the _ root selection set _ in {query}.
146
146
- Return {ExecuteRootSelectionSet(variableValues, initialValue, queryType,
147
- selectionSet )}.
147
+ rootSelectionSet, "normal" )}.
148
148
149
149
### Mutation
150
150
151
151
If the operation is a mutation, the result of the operation is the result of
152
- executing the operation’s top level _ selection set_ on the mutation root object
153
- type. This selection set should be executed serially.
152
+ executing the operation’s _ root selection set_ on the mutation root object type.
153
+ This selection set should be executed serially.
154
154
155
155
It is expected that the top level fields in a mutation operation perform
156
156
side-effects on the underlying data system. Serial execution of the provided
@@ -160,9 +160,9 @@ ExecuteMutation(mutation, schema, variableValues, initialValue):
160
160
161
161
- Let {mutationType} be the root Mutation type in {schema}.
162
162
- Assert: {mutationType} is an Object type.
163
- - Let {selectionSet } be the top level selection set in {mutation}.
163
+ - Let {rootSelectionSet } be the _ root selection set _ in {mutation}.
164
164
- Return {ExecuteRootSelectionSet(variableValues, initialValue, mutationType,
165
- selectionSet, true )}.
165
+ rootSelectionSet, "serial" )}.
166
166
167
167
### Subscription
168
168
@@ -328,9 +328,9 @@ ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue):
328
328
329
329
- Let {subscriptionType} be the root Subscription type in {schema}.
330
330
- Assert: {subscriptionType} is an Object type.
331
- - Let {selectionSet } be the top level selection set in {subscription}.
331
+ - Let {rootSelectionSet } be the _ root selection set _ in {subscription}.
332
332
- Return {ExecuteRootSelectionSet(variableValues, initialValue,
333
- subscriptionType, selectionSet )}.
333
+ subscriptionType, rootSelectionSet, "normal" )}.
334
334
335
335
Note: The {ExecuteSubscriptionEvent()} algorithm is intentionally similar to
336
336
{ExecuteQuery()} since this is how each event result is produced.
@@ -346,43 +346,56 @@ Unsubscribe(responseStream):
346
346
347
347
- Cancel {responseStream}.
348
348
349
- ## Executing the Root Selection Set
349
+ ## Executing Selection Sets
350
350
351
- To execute the root selection set, the object value being evaluated and the
352
- object type need to be known, as well as whether it must be executed serially,
353
- or may be executed in parallel.
351
+ The process of executing a GraphQL operation is to recursively execute every
352
+ selected field in the operation. To do this, first all initially selected fields
353
+ from the operation's top most _ root selection set_ are collected, then each
354
+ executed, then of those all subfields are collected, then each executed. This
355
+ process continues until there are no more subfields to collect and execute.
356
+
357
+ ### Executing the Root Selection Set
358
+
359
+ :: A _ root selection set_ is the top level _ selection set_ provided by a GraphQL
360
+ operation. A root selection set always selects from a root type.
361
+
362
+ To execute the root selection set, the initial value being evaluated and the
363
+ root type must be known, as well as whether it must be executed serially, or may
364
+ be executed in parallel (see
365
+ [ Normal and Serial Execution] ( #sec-Normal-and-Serial-Execution ) .
354
366
355
367
Executing the root selection set works similarly for queries (parallel),
356
368
mutations (serial), and subscriptions (where it is executed for each event in
357
369
the underlying Source Stream).
358
370
359
- First, the selection set is turned into a _ grouped field set_ ; then, we execute
360
- this grouped field set and return the resulting {data} and {errors}.
371
+ First, the _ selection set _ is collected into a _ grouped field set_ which is then
372
+ executed, returning the resulting {data} and {errors}.
361
373
362
374
ExecuteRootSelectionSet(variableValues, initialValue, objectType, selectionSet,
363
- serial ):
375
+ executionMode ):
364
376
365
- - If {serial} is not provided, initialize it to {false}.
366
377
- Let {groupedFieldSet} be the result of {CollectFields(objectType,
367
378
selectionSet, variableValues)}.
368
379
- Let {data} be the result of running {ExecuteGroupedFieldSet(groupedFieldSet,
369
- objectType, initialValue, variableValues)} _ serially_ if {serial } is {true},
370
- _ normally _ (allowing parallelization) otherwise .
380
+ objectType, initialValue, variableValues)} _ serially_ if {executionMode } is
381
+ {"serial"}, otherwise _ normally _ ) .
371
382
- Let {errors} be the list of all _ execution error_ raised while executing the
372
383
selection set.
373
384
- Return an unordered map containing {data} and {errors}.
374
385
375
386
### Field Collection
376
387
377
- :: A _ grouped field set_ is a map where each entry is a list of field selections
378
- that share a _ response name_ (the alias if defined, otherwise the field name).
379
-
380
388
Before execution, the _ selection set_ is converted to a _ grouped field set_ by
381
- calling {CollectFields()}. This ensures all fields with the same response name
382
- (including those in referenced fragments) are executed at the same time.
389
+ calling {CollectFields()}. This ensures all fields with the same response name,
390
+ including those in referenced fragments, are executed at the same time.
391
+
392
+ :: A _ grouped field set_ is a map where each entry is a _ response name_ and a
393
+ list of selected fields that share that _ response name_ (the field alias if
394
+ defined, otherwise the field's name).
383
395
384
- As an example, collecting the fields of this selection set would collect two
385
- instances of the field ` a ` and one of field ` b ` :
396
+ As an example, collecting the fields of this selection set would result in a
397
+ grouped field set with two entries, ` "a" ` and ` "b" ` , with two instances of the
398
+ field ` a ` and one of field ` b ` :
386
399
387
400
``` graphql example
388
401
{
@@ -479,14 +492,64 @@ DoesFragmentTypeApply(objectType, fragmentType):
479
492
Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
480
493
directives may be applied in either order since they apply commutatively.
481
494
482
- ## Executing a Grouped Field Set
495
+ ** Merging Selection Sets**
496
+
497
+ When more than one field of the same name is executed in parallel, during value
498
+ completion each related _ selection set_ is collected together to produce a
499
+ single _ grouped field set_ in order to continue execution of the sub-selection
500
+ sets.
501
+
502
+ An example operation illustrating parallel fields with the same name with
503
+ sub-selections.
504
+
505
+ Continuing the example above,
506
+
507
+ ``` graphql example
508
+ {
509
+ a {
510
+ subfield1
511
+ }
512
+ ... ExampleFragment
513
+ }
514
+
515
+ fragment ExampleFragment on Query {
516
+ a {
517
+ subfield2
518
+ }
519
+ b
520
+ }
521
+ ```
483
522
484
- To execute a grouped field set , the object value being evaluated and the object
485
- type need to be known, as well as whether it must be executed serially, or may
486
- be executed in parallel .
523
+ After resolving the value for field ` "a" ` , the following multiple selection sets
524
+ are merged together so ` "subfield1" ` and ` "subfield2" ` are resolved in the same
525
+ phase with the same value .
487
526
488
- Each represented field in the grouped field set produces an entry into a result
489
- map.
527
+ CollectSubfields(objectType, fields, variableValues):
528
+
529
+ - Let {groupedFieldSet} be an empty map.
530
+ - For each {field} in {fields}:
531
+ - Let {fieldSelectionSet} be the selection set of {field}.
532
+ - If {fieldSelectionSet} is null or empty, continue to the next field.
533
+ - Let {fieldGroupedFieldSet} be the result of {CollectFields(objectType,
534
+ fieldSelectionSet, variableValues)}.
535
+ - For each {fieldGroupedFieldSet} as {responseName} and {subfields}:
536
+ - Let {groupForResponseName} be the list in {groupedFieldSet} for
537
+ {responseName}; if no such list exists, create it as an empty list.
538
+ - Append all fields in {subfields} to {groupForResponseName}.
539
+ - Return {groupedFieldSet}.
540
+
541
+ Note: All the {fields} passed to {CollectSubfields()} share the same _ response
542
+ name_ .
543
+
544
+ ### Executing a Grouped Field Set
545
+
546
+ To execute a _ grouped field set_ , the object value being evaluated and the
547
+ object type need to be known, as well as whether it must be executed serially,
548
+ or may be executed in parallel (see
549
+ [ Normal and Serial Execution] ( #sec-Normal-and-Serial-Execution ) .
550
+
551
+ Each entry in the grouped field set represents a _ response name_ which produces
552
+ an entry into a result map.
490
553
491
554
ExecuteGroupedFieldSet(groupedFieldSet, objectType, objectValue,
492
555
variableValues):
@@ -504,7 +567,8 @@ variableValues):
504
567
- Return {resultMap}.
505
568
506
569
Note: {resultMap} is ordered by which fields appear first in the operation. This
507
- is explained in greater detail in the Field Collection section below.
570
+ is explained in greater detail in the [ Field Collection] ( #sec-Field-Collection )
571
+ section.
508
572
509
573
** Errors and Non-Null Types**
510
574
@@ -800,47 +864,6 @@ ResolveAbstractType(abstractType, objectValue):
800
864
for determining the Object type of {abstractType} given the value
801
865
{objectValue}.
802
866
803
- ** Merging Selection Sets**
804
-
805
- When more than one field of the same name is executed in parallel, during value
806
- completion each related _ selection set_ is collected together to produce a
807
- single grouped field set in order to continue execution of the sub-selection
808
- sets.
809
-
810
- An example operation illustrating parallel fields with the same name with
811
- sub-selections.
812
-
813
- ``` graphql example
814
- {
815
- me {
816
- firstName
817
- }
818
- me {
819
- lastName
820
- }
821
- }
822
- ```
823
-
824
- After resolving the value for ` me ` , the selection sets are merged together so
825
- ` firstName ` and ` lastName ` can be resolved for one value.
826
-
827
- CollectSubfields(objectType, fields, variableValues):
828
-
829
- - Let {groupedFieldSet} be an empty map.
830
- - For each {field} in {fields}:
831
- - Let {fieldSelectionSet} be the selection set of {field}.
832
- - If {fieldSelectionSet} is null or empty, continue to the next field.
833
- - Let {fieldGroupedFieldSet} be the result of {CollectFields(objectType,
834
- fieldSelectionSet, variableValues)}.
835
- - For each {fieldGroupedFieldSet} as {responseName} and {subfields}:
836
- - Let {groupForResponseName} be the list in {groupedFieldSet} for
837
- {responseName}; if no such list exists, create it as an empty list.
838
- - Append all fields in {subfields} to {groupForResponseName}.
839
- - Return {groupedFieldSet}.
840
-
841
- Note: All the {fields} passed to {CollectSubfields()} share the same _ response
842
- name_ .
843
-
844
867
### Handling Execution Errors
845
868
846
869
<a name =" sec-Handling-Field-Errors " >
0 commit comments