@@ -5,15 +5,13 @@ use graph::{
55 prelude:: { s, CheapClone } ,
66 util:: timed_rw_lock:: TimedMutex ,
77} ;
8- use indexmap:: IndexMap ;
98use lazy_static:: lazy_static;
109use stable_hash:: crypto:: SetHasher ;
1110use stable_hash:: prelude:: * ;
1211use stable_hash:: utils:: stable_hash;
13- use std:: borrow:: ToOwned ;
14- use std:: collections:: { HashMap , HashSet } ;
15- use std:: iter;
12+ use std:: collections:: HashMap ;
1613use std:: time:: Instant ;
14+ use std:: { borrow:: ToOwned , collections:: HashSet } ;
1715
1816use graph:: data:: graphql:: * ;
1917use graph:: data:: query:: CacheStatus ;
@@ -136,7 +134,6 @@ impl Default for WeightedResult {
136134
137135struct HashableQuery < ' a > {
138136 query_schema_id : & ' a DeploymentHash ,
139- query_fragments : & ' a HashMap < String , a:: FragmentDefinition > ,
140137 selection_set : & ' a a:: SelectionSet ,
141138 block_ptr : & ' a BlockPtr ,
142139}
@@ -162,13 +159,6 @@ impl StableHash for HashableQuery<'_> {
162159 self . query_schema_id
163160 . stable_hash ( sequence_number. next_child ( ) , state) ;
164161
165- // Not stable! Uses to_string()
166- self . query_fragments
167- . iter ( )
168- . map ( |( k, v) | ( k, format ! ( "{:?}" , v) ) )
169- . collect :: < HashMap < _ , _ > > ( )
170- . stable_hash ( sequence_number. next_child ( ) , state) ;
171-
172162 // Not stable! Uses to_string
173163 format ! ( "{:?}" , self . selection_set) . stable_hash ( sequence_number. next_child ( ) , state) ;
174164
@@ -187,7 +177,6 @@ fn cache_key(
187177 // Otherwise, incorrect results may be returned.
188178 let query = HashableQuery {
189179 query_schema_id : ctx. query . schema . id ( ) ,
190- query_fragments : & ctx. query . fragments ,
191180 selection_set,
192181 block_ptr,
193182 } ;
@@ -275,7 +264,7 @@ where
275264 }
276265}
277266
278- pub fn execute_root_selection_set_uncached (
267+ pub ( crate ) fn execute_root_selection_set_uncached (
279268 ctx : & ExecutionContext < impl Resolver > ,
280269 selection_set : & a:: SelectionSet ,
281270 root_type : & s:: ObjectType ,
@@ -286,18 +275,16 @@ pub fn execute_root_selection_set_uncached(
286275 let mut intro_set = a:: SelectionSet :: empty_from ( selection_set) ;
287276 let mut meta_items = Vec :: new ( ) ;
288277
289- for ( _, fields) in collect_fields ( ctx, root_type, iter:: once ( selection_set) ) {
290- let name = fields[ 0 ] . name . clone ( ) ;
291- let selections = fields. into_iter ( ) . map ( |f| a:: Selection :: Field ( f. clone ( ) ) ) ;
278+ for field in selection_set. fields_for ( root_type) {
292279 // See if this is an introspection or data field. We don't worry about
293280 // non-existent fields; those will cause an error later when we execute
294281 // the data_set SelectionSet
295- if is_introspection_field ( & name) {
296- intro_set. extend ( selections )
297- } else if & name == META_FIELD_NAME {
298- meta_items. extend ( selections )
282+ if is_introspection_field ( & field . name ) {
283+ intro_set. push ( field )
284+ } else if & field . name == META_FIELD_NAME {
285+ meta_items. push ( field )
299286 } else {
300- data_set. extend ( selections )
287+ data_set. push ( field )
301288 }
302289 }
303290
@@ -306,8 +293,8 @@ pub fn execute_root_selection_set_uncached(
306293 Object :: default ( )
307294 } else {
308295 let initial_data = ctx. resolver . prefetch ( & ctx, & data_set) ?;
309- data_set. extend ( meta_items) ;
310- execute_selection_set_to_map ( & ctx, iter :: once ( & data_set) , root_type, initial_data) ?
296+ data_set. push_fields ( meta_items) ;
297+ execute_selection_set_to_map ( & ctx, & data_set, root_type, initial_data) ?
311298 } ;
312299
313300 // Resolve introspection fields, if there are any
@@ -316,7 +303,7 @@ pub fn execute_root_selection_set_uncached(
316303
317304 values. extend ( execute_selection_set_to_map (
318305 & ictx,
319- iter :: once ( & intro_set ) ,
306+ ctx . query . selection_set . as_ref ( ) ,
320307 & * INTROSPECTION_QUERY_TYPE ,
321308 None ,
322309 ) ?) ;
@@ -326,7 +313,7 @@ pub fn execute_root_selection_set_uncached(
326313}
327314
328315/// Executes the root selection set of a query.
329- pub async fn execute_root_selection_set < R : Resolver > (
316+ pub ( crate ) async fn execute_root_selection_set < R : Resolver > (
330317 ctx : Arc < ExecutionContext < R > > ,
331318 selection_set : Arc < a:: SelectionSet > ,
332319 root_type : Arc < s:: ObjectType > ,
@@ -472,21 +459,21 @@ pub async fn execute_root_selection_set<R: Resolver>(
472459/// Allows passing in a parent value during recursive processing of objects and their fields.
473460fn execute_selection_set < ' a > (
474461 ctx : & ' a ExecutionContext < impl Resolver > ,
475- selection_sets : impl Iterator < Item = & ' a a:: SelectionSet > ,
462+ selection_set : & ' a a:: SelectionSet ,
476463 object_type : & s:: ObjectType ,
477464 prefetched_value : Option < r:: Value > ,
478465) -> Result < r:: Value , Vec < QueryExecutionError > > {
479466 Ok ( r:: Value :: Object ( execute_selection_set_to_map (
480467 ctx,
481- selection_sets ,
468+ selection_set ,
482469 object_type,
483470 prefetched_value,
484471 ) ?) )
485472}
486473
487474fn execute_selection_set_to_map < ' a > (
488475 ctx : & ' a ExecutionContext < impl Resolver > ,
489- selection_sets : impl Iterator < Item = & ' a a:: SelectionSet > ,
476+ selection_set : & ' a a:: SelectionSet ,
490477 object_type : & s:: ObjectType ,
491478 prefetched_value : Option < r:: Value > ,
492479) -> Result < Object , Vec < QueryExecutionError > > {
@@ -498,14 +485,11 @@ fn execute_selection_set_to_map<'a>(
498485 let mut errors: Vec < QueryExecutionError > = Vec :: new ( ) ;
499486 let mut result_map = Object :: new ( ) ;
500487
501- // Group fields with the same response key, so we can execute them together
502- let grouped_field_set = collect_fields ( ctx, object_type, selection_sets) ;
503-
504488 // Gather fields that appear more than once with the same response key.
505489 let multiple_response_keys = {
506490 let mut multiple_response_keys = HashSet :: new ( ) ;
507491 let mut fields = HashSet :: new ( ) ;
508- for field in grouped_field_set . iter ( ) . map ( | ( _ , f ) | f . iter ( ) ) . flatten ( ) {
492+ for field in selection_set . fields_for ( object_type ) {
509493 if !fields. insert ( field. name . as_str ( ) ) {
510494 multiple_response_keys. insert ( field. name . as_str ( ) ) ;
511495 }
@@ -514,7 +498,7 @@ fn execute_selection_set_to_map<'a>(
514498 } ;
515499
516500 // Process all field groups in order
517- for ( response_key , fields ) in grouped_field_set {
501+ for field in selection_set . fields_for ( object_type ) {
518502 match ctx. deadline {
519503 Some ( deadline) if deadline < Instant :: now ( ) => {
520504 errors. push ( QueryExecutionError :: Timeout ) ;
@@ -523,8 +507,10 @@ fn execute_selection_set_to_map<'a>(
523507 _ => ( ) ,
524508 }
525509
510+ let response_key = field. response_key ( ) ;
511+
526512 // Unwrap: The query was validated to contain only valid fields.
527- let field = sast:: get_field ( object_type, & fields [ 0 ] . name ) . unwrap ( ) ;
513+ let field_type = sast:: get_field ( object_type, & field . name ) . unwrap ( ) ;
528514
529515 // Check if we have the value already.
530516 let field_value = prefetched_object
@@ -537,13 +523,13 @@ fn execute_selection_set_to_map<'a>(
537523
538524 // Scalars and scalar lists are associated to the field name.
539525 // If the field has more than one response key, we have to clone.
540- match multiple_response_keys. contains ( fields [ 0 ] . name . as_str ( ) ) {
541- false => o. remove ( & fields [ 0 ] . name ) ,
542- true => o. get ( & fields [ 0 ] . name ) . cloned ( ) ,
526+ match multiple_response_keys. contains ( field . name . as_str ( ) ) {
527+ false => o. remove ( & field . name ) ,
528+ true => o. get ( & field . name ) . cloned ( ) ,
543529 }
544530 } )
545531 . flatten ( ) ;
546- match execute_field ( & ctx, object_type, field_value, & fields [ 0 ] , field, fields ) {
532+ match execute_field ( & ctx, object_type, field_value, field, field_type ) {
547533 Ok ( v) => {
548534 result_map. insert ( response_key. to_owned ( ) , v) ;
549535 }
@@ -560,124 +546,13 @@ fn execute_selection_set_to_map<'a>(
560546 }
561547}
562548
563- /// Collects fields from selection sets. Returns a map from response key to fields. There will
564- /// typically be a single field for a response key. If there are multiple, the overall execution
565- /// logic will effectively merged them into the output for the response key.
566- pub fn collect_fields < ' a > (
567- ctx : & ' a ExecutionContext < impl Resolver > ,
568- object_type : & s:: ObjectType ,
569- selection_sets : impl Iterator < Item = & ' a a:: SelectionSet > ,
570- ) -> IndexMap < & ' a str , Vec < & ' a a:: Field > > {
571- let mut grouped_fields = IndexMap :: new ( ) ;
572- collect_fields_inner (
573- ctx,
574- object_type,
575- selection_sets,
576- & mut HashSet :: new ( ) ,
577- & mut grouped_fields,
578- ) ;
579- grouped_fields
580- }
581-
582- pub fn collect_fields_inner < ' a > (
583- ctx : & ' a ExecutionContext < impl Resolver > ,
584- object_type : & s:: ObjectType ,
585- selection_sets : impl Iterator < Item = & ' a a:: SelectionSet > ,
586- visited_fragments : & mut HashSet < & ' a str > ,
587- output : & mut IndexMap < & ' a str , Vec < & ' a a:: Field > > ,
588- ) {
589- for selection_set in selection_sets {
590- // Only consider selections that are not skipped and should be included
591- for selection in selection_set. included ( ) {
592- match selection {
593- a:: Selection :: Field ( ref field) => {
594- let response_key = field. response_key ( ) ;
595- output. entry ( response_key) . or_default ( ) . push ( field) ;
596- }
597-
598- a:: Selection :: FragmentSpread ( spread) => {
599- // Only consider the fragment if it hasn't already been included,
600- // as would be the case if the same fragment spread ...Foo appeared
601- // twice in the same selection set.
602- //
603- // Note: This will skip both duplicate fragments and will break cycles,
604- // so we support fragments even though the GraphQL spec prohibits them.
605- if visited_fragments. insert ( & spread. fragment_name ) {
606- let fragment = ctx. query . get_fragment ( & spread. fragment_name ) ;
607- if does_fragment_type_apply ( ctx, object_type, & fragment. type_condition ) {
608- // We have a fragment that applies to the current object type,
609- // collect fields recursively
610- collect_fields_inner (
611- ctx,
612- object_type,
613- iter:: once ( & fragment. selection_set ) ,
614- visited_fragments,
615- output,
616- ) ;
617- }
618- }
619- }
620-
621- a:: Selection :: InlineFragment ( fragment) => {
622- let applies = match & fragment. type_condition {
623- Some ( cond) => does_fragment_type_apply ( ctx, object_type, & cond) ,
624- None => true ,
625- } ;
626-
627- if applies {
628- collect_fields_inner (
629- ctx,
630- object_type,
631- iter:: once ( & fragment. selection_set ) ,
632- visited_fragments,
633- output,
634- )
635- }
636- }
637- } ;
638- }
639- }
640- }
641-
642- /// Determines whether a fragment is applicable to the given object type.
643- fn does_fragment_type_apply (
644- ctx : & ExecutionContext < impl Resolver > ,
645- object_type : & s:: ObjectType ,
646- fragment_type : & a:: TypeCondition ,
647- ) -> bool {
648- // This is safe to do, as TypeCondition only has a single `On` variant.
649- let a:: TypeCondition :: On ( ref name) = fragment_type;
650-
651- // Resolve the type the fragment applies to based on its name
652- let named_type = ctx. query . schema . document ( ) . get_named_type ( name) ;
653-
654- match named_type {
655- // The fragment applies to the object type if its type is the same object type
656- Some ( s:: TypeDefinition :: Object ( ot) ) => object_type == ot,
657-
658- // The fragment also applies to the object type if its type is an interface
659- // that the object type implements
660- Some ( s:: TypeDefinition :: Interface ( it) ) => {
661- object_type. implements_interfaces . contains ( & it. name )
662- }
663-
664- // The fragment also applies to an object type if its type is a union that
665- // the object type is one of the possible types for
666- Some ( s:: TypeDefinition :: Union ( ut) ) => ut. types . contains ( & object_type. name ) ,
667-
668- // In all other cases, the fragment does not apply
669- _ => false ,
670- }
671- }
672-
673549/// Executes a field.
674550fn execute_field (
675551 ctx : & ExecutionContext < impl Resolver > ,
676552 object_type : & s:: ObjectType ,
677553 field_value : Option < r:: Value > ,
678554 field : & a:: Field ,
679555 field_definition : & s:: Field ,
680- fields : Vec < & a:: Field > ,
681556) -> Result < r:: Value , Vec < QueryExecutionError > > {
682557 coerce_argument_values ( & ctx. query , object_type, field)
683558 . and_then ( |argument_values| {
@@ -691,7 +566,7 @@ fn execute_field(
691566 & argument_values,
692567 )
693568 } )
694- . and_then ( |value| complete_value ( ctx, field, & field_definition. field_type , & fields , value) )
569+ . and_then ( |value| complete_value ( ctx, field, & field_definition. field_type , value) )
695570}
696571
697572/// Resolves the value of a field.
@@ -878,13 +753,12 @@ fn complete_value(
878753 ctx : & ExecutionContext < impl Resolver > ,
879754 field : & a:: Field ,
880755 field_type : & s:: Type ,
881- fields : & Vec < & a:: Field > ,
882756 resolved_value : r:: Value ,
883757) -> Result < r:: Value , Vec < QueryExecutionError > > {
884758 match field_type {
885759 // Fail if the field type is non-null but the value is null
886760 s:: Type :: NonNullType ( inner_type) => {
887- return match complete_value ( ctx, field, inner_type, fields , resolved_value) ? {
761+ return match complete_value ( ctx, field, inner_type, resolved_value) ? {
888762 r:: Value :: Null => Err ( vec ! [ QueryExecutionError :: NonNullError (
889763 field. position,
890764 field. name. to_string( ) ,
@@ -908,7 +782,7 @@ fn complete_value(
908782 for value_place in & mut values {
909783 // Put in a placeholder, complete the value, put the completed value back.
910784 let value = std:: mem:: replace ( value_place, r:: Value :: Null ) ;
911- match complete_value ( ctx, field, inner_type, fields , value) {
785+ match complete_value ( ctx, field, inner_type, value) {
912786 Ok ( value) => {
913787 * value_place = value;
914788 }
@@ -965,7 +839,7 @@ fn complete_value(
965839 // Complete object types recursively
966840 s:: TypeDefinition :: Object ( object_type) => execute_selection_set (
967841 ctx,
968- fields . iter ( ) . map ( |f| & f . selection_set ) ,
842+ & field . selection_set ,
969843 object_type,
970844 Some ( resolved_value) ,
971845 ) ,
@@ -976,7 +850,7 @@ fn complete_value(
976850
977851 execute_selection_set (
978852 ctx,
979- fields . iter ( ) . map ( |f| & f . selection_set ) ,
853+ & field . selection_set ,
980854 object_type,
981855 Some ( resolved_value) ,
982856 )
@@ -988,7 +862,7 @@ fn complete_value(
988862
989863 execute_selection_set (
990864 ctx,
991- fields . iter ( ) . map ( |f| & f . selection_set ) ,
865+ & field . selection_set ,
992866 object_type,
993867 Some ( resolved_value) ,
994868 )
0 commit comments