@@ -588,9 +588,9 @@ fn execute_selection_set<'a>(
588588 // queries.
589589 let collected_columns =
590590 if * DISABLE_EXPERIMENTAL_FEATURE_SELECT_BY_SPECIFIC_ATTRIBUTE_NAMES {
591- BTreeMap :: new ( )
591+ SelectedAttributes ( BTreeMap :: new ( ) )
592592 } else {
593- CollectedAttributeNames :: consolidate_column_names ( schema, & field) ?
593+ SelectedAttributes :: from_selection_set ( schema, field) ?
594594 } ;
595595
596596 match execute_field (
@@ -640,7 +640,7 @@ struct CollectedResponseKey<'a> {
640640 iface_cond : Option < & ' a s:: InterfaceType > ,
641641 iface_fields : Vec < & ' a a:: Field > ,
642642 obj_types : IndexMap < sast:: ObjectType < ' a > , Vec < & ' a a:: Field > > ,
643- collected_column_names : CollectedAttributeNames < ' a > ,
643+ collected_column_names : SelectedAttributes < ' a > ,
644644}
645645
646646impl < ' a > IntoIterator for CollectedResponseKey < ' a > {
@@ -669,7 +669,7 @@ fn execute_field(
669669 join : & Join < ' _ > ,
670670 field : & a:: Field ,
671671 field_definition : & s:: Field ,
672- collected_column_names : AttributeNamesByObjectType < ' _ > ,
672+ selected_attrs : SelectedAttributes < ' _ > ,
673673) -> Result < Vec < Node > , Vec < QueryExecutionError > > {
674674 let argument_values = crate :: execution:: coerce_argument_values ( & ctx. query , object_type, field) ?;
675675 let multiplicity = if sast:: is_list_or_non_null_list_field ( field_definition) {
@@ -690,7 +690,7 @@ fn execute_field(
690690 ctx. max_first ,
691691 ctx. max_skip ,
692692 ctx. query . query_id . clone ( ) ,
693- collected_column_names ,
693+ selected_attrs ,
694694 )
695695 . map_err ( |e| vec ! [ e] )
696696}
@@ -710,7 +710,7 @@ fn fetch(
710710 max_first : u32 ,
711711 max_skip : u32 ,
712712 query_id : String ,
713- collected_column_names : AttributeNamesByObjectType < ' _ > ,
713+ selected_attrs : SelectedAttributes < ' _ > ,
714714) -> Result < Vec < Node > , QueryExecutionError > {
715715 let mut query = build_query (
716716 join. child_type ,
@@ -719,7 +719,7 @@ fn fetch(
719719 types_for_interface,
720720 max_first,
721721 max_skip,
722- collected_column_names ,
722+ selected_attrs . 0 ,
723723 ) ?;
724724 query. query_id = Some ( query_id) ;
725725
@@ -751,30 +751,33 @@ fn fetch(
751751 . map ( |entities| entities. into_iter ( ) . map ( |entity| entity. into ( ) ) . collect ( ) )
752752}
753753
754- /// Represents a finished column collection operation, mapping each object type to the final set of
755- /// selected SQL columns.
756- type AttributeNamesByObjectType < ' a > = BTreeMap < sast:: ObjectType < ' a > , AttributeNames > ;
757-
758754#[ derive( Debug , Default , Clone ) ]
759- struct CollectedAttributeNames < ' a > ( HashMap < ObjectOrInterface < ' a > , AttributeNames > ) ;
755+ struct SelectedAttributes < ' a > ( BTreeMap < sast :: ObjectType < ' a > , AttributeNames > ) ;
760756
761- impl < ' a > CollectedAttributeNames < ' a > {
762- /// Creates a new, combined `CollectedAttributeNames` using drained values from `CollectedAttributeNames`
763- /// scattered across different `CollectedResponseKey`s.
764- fn consolidate_column_names < ' schema > (
765- schema : & ' schema ApiSchema ,
757+ impl < ' a > SelectedAttributes < ' a > {
758+ /// Extract the attributes we should select from `selection_set`. In
759+ /// particular, disregard derived fields since they are not stored
760+ fn from_selection_set (
761+ schema : & ' a ApiSchema ,
766762 field : & a:: Field ,
767- ) -> Result < AttributeNamesByObjectType < ' schema > , Vec < QueryExecutionError > > {
768- let mut map: AttributeNamesByObjectType = BTreeMap :: new ( ) ;
763+ ) -> Result < SelectedAttributes < ' a > , Vec < QueryExecutionError > > {
764+ let mut map = BTreeMap :: new ( ) ;
769765 for ( type_name, fields) in field. selection_set . fields ( ) {
770766 let object_type = schema
771767 . document ( )
772768 . get_object_type_definition ( type_name)
773769 . expect ( "selection sets only contain valid object types" ) ;
774- let column_names =
775- AttributeNames :: Select ( fields. map ( |field| field. name . clone ( ) ) . collect ( ) ) ;
776- let column_names = filter_derived_fields ( column_names, object_type) ;
777- map. insert ( object_type. into ( ) , column_names) ;
770+ let column_names = fields
771+ . filter ( |field| {
772+ // Keep fields that are not derived and for which we
773+ // can find the field type
774+ sast:: get_field ( object_type, & field. name )
775+ . map ( |field_type| !field_type. is_derived ( ) )
776+ . unwrap_or ( false )
777+ } )
778+ . map ( |field| field. name . clone ( ) )
779+ . collect ( ) ;
780+ map. insert ( object_type. into ( ) , AttributeNames :: Select ( column_names) ) ;
778781 }
779782 // We need to also select the `orderBy` field if there is one.
780783 // Because of how the API Schema is set up, `orderBy` can only have
@@ -794,34 +797,6 @@ impl<'a> CollectedAttributeNames<'a> {
794797 . into( ) ] ) ;
795798 }
796799 }
797- Ok ( map)
798- }
799- }
800-
801- /// Removes all derived fields from a `AttributeNames` collection based on a referential `ObjectType`.
802- fn filter_derived_fields (
803- column_names_type : AttributeNames ,
804- object : & s:: ObjectType ,
805- ) -> AttributeNames {
806- match column_names_type {
807- AttributeNames :: All => column_names_type,
808- AttributeNames :: Select ( sql_column_names) => {
809- let mut filtered = AttributeNames :: All ;
810- sql_column_names
811- . into_iter ( )
812- . filter_map ( |column_name| {
813- if let Some ( schema_field) = sast:: get_field ( object, & column_name) {
814- if !schema_field. is_derived ( ) {
815- Some ( column_name) // field exists and is not derived
816- } else {
817- None // field exists and is derived
818- }
819- } else {
820- None // field does not exist
821- }
822- } )
823- . for_each ( |col| filtered. add_str ( & col) ) ;
824- filtered
825- }
800+ Ok ( SelectedAttributes ( map) )
826801 }
827802}
0 commit comments