@@ -588,9 +588,9 @@ fn execute_selection_set<'a>(
588
588
// queries.
589
589
let collected_columns =
590
590
if * DISABLE_EXPERIMENTAL_FEATURE_SELECT_BY_SPECIFIC_ATTRIBUTE_NAMES {
591
- BTreeMap :: new ( )
591
+ SelectedAttributes ( BTreeMap :: new ( ) )
592
592
} else {
593
- CollectedAttributeNames :: consolidate_column_names ( schema, & field) ?
593
+ SelectedAttributes :: from_selection_set ( schema, field) ?
594
594
} ;
595
595
596
596
match execute_field (
@@ -640,7 +640,7 @@ struct CollectedResponseKey<'a> {
640
640
iface_cond : Option < & ' a s:: InterfaceType > ,
641
641
iface_fields : Vec < & ' a a:: Field > ,
642
642
obj_types : IndexMap < sast:: ObjectType < ' a > , Vec < & ' a a:: Field > > ,
643
- collected_column_names : CollectedAttributeNames < ' a > ,
643
+ collected_column_names : SelectedAttributes < ' a > ,
644
644
}
645
645
646
646
impl < ' a > IntoIterator for CollectedResponseKey < ' a > {
@@ -669,7 +669,7 @@ fn execute_field(
669
669
join : & Join < ' _ > ,
670
670
field : & a:: Field ,
671
671
field_definition : & s:: Field ,
672
- collected_column_names : AttributeNamesByObjectType < ' _ > ,
672
+ selected_attrs : SelectedAttributes < ' _ > ,
673
673
) -> Result < Vec < Node > , Vec < QueryExecutionError > > {
674
674
let argument_values = crate :: execution:: coerce_argument_values ( & ctx. query , object_type, field) ?;
675
675
let multiplicity = if sast:: is_list_or_non_null_list_field ( field_definition) {
@@ -690,7 +690,7 @@ fn execute_field(
690
690
ctx. max_first ,
691
691
ctx. max_skip ,
692
692
ctx. query . query_id . clone ( ) ,
693
- collected_column_names ,
693
+ selected_attrs ,
694
694
)
695
695
. map_err ( |e| vec ! [ e] )
696
696
}
@@ -710,7 +710,7 @@ fn fetch(
710
710
max_first : u32 ,
711
711
max_skip : u32 ,
712
712
query_id : String ,
713
- collected_column_names : AttributeNamesByObjectType < ' _ > ,
713
+ selected_attrs : SelectedAttributes < ' _ > ,
714
714
) -> Result < Vec < Node > , QueryExecutionError > {
715
715
let mut query = build_query (
716
716
join. child_type ,
@@ -719,7 +719,7 @@ fn fetch(
719
719
types_for_interface,
720
720
max_first,
721
721
max_skip,
722
- collected_column_names ,
722
+ selected_attrs . 0 ,
723
723
) ?;
724
724
query. query_id = Some ( query_id) ;
725
725
@@ -751,30 +751,33 @@ fn fetch(
751
751
. map ( |entities| entities. into_iter ( ) . map ( |entity| entity. into ( ) ) . collect ( ) )
752
752
}
753
753
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
-
758
754
#[ derive( Debug , Default , Clone ) ]
759
- struct CollectedAttributeNames < ' a > ( HashMap < ObjectOrInterface < ' a > , AttributeNames > ) ;
755
+ struct SelectedAttributes < ' a > ( BTreeMap < sast :: ObjectType < ' a > , AttributeNames > ) ;
760
756
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 ,
766
762
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 ( ) ;
769
765
for ( type_name, fields) in field. selection_set . fields ( ) {
770
766
let object_type = schema
771
767
. document ( )
772
768
. get_object_type_definition ( type_name)
773
769
. 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) ) ;
778
781
}
779
782
// We need to also select the `orderBy` field if there is one.
780
783
// Because of how the API Schema is set up, `orderBy` can only have
@@ -794,34 +797,6 @@ impl<'a> CollectedAttributeNames<'a> {
794
797
. into( ) ] ) ;
795
798
}
796
799
}
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) )
826
801
}
827
802
}
0 commit comments