1
+ use graph:: data:: graphql:: DocumentExt as _;
1
2
use graph:: data:: value:: Object ;
2
3
use graphql_parser:: Pos ;
3
4
use graphql_tools:: validation:: rules:: * ;
@@ -18,7 +19,7 @@ use graph::prelude::{info, o, q, r, s, BlockNumber, CheapClone, Logger, TryFromV
18
19
19
20
use crate :: execution:: ast as a;
20
21
use crate :: query:: { ast as qast, ext:: BlockConstraint } ;
21
- use crate :: schema:: ast as sast;
22
+ use crate :: schema:: ast:: { self as sast} ;
22
23
use crate :: values:: coercion;
23
24
use crate :: { execution:: get_field, schema:: api:: ErrorPolicy } ;
24
25
@@ -861,21 +862,53 @@ impl Transform {
861
862
selection_set,
862
863
} = field;
863
864
865
+ // Short-circuit '__typename' since it is not a real field
866
+ if name == "__typename" {
867
+ return Ok ( Some ( a:: Field {
868
+ position,
869
+ alias,
870
+ name,
871
+ arguments : vec ! [ ] ,
872
+ directives : vec ! [ ] ,
873
+ selection_set : a:: SelectionSet :: new ( vec ! [ ] ) ,
874
+ } ) ) ;
875
+ }
876
+
877
+ let field_type = parent_type. field ( & name) . ok_or_else ( || {
878
+ vec ! [ QueryExecutionError :: UnknownField (
879
+ position,
880
+ parent_type. name( ) . to_string( ) ,
881
+ name. clone( ) ,
882
+ ) ]
883
+ } ) ?;
884
+
864
885
let ( directives, skip) = self . interpolate_directives ( directives) ?;
865
886
if skip {
866
887
return Ok ( None ) ;
867
888
}
868
889
869
890
let mut arguments = self . interpolate_arguments ( arguments, & position) ?;
870
891
self . coerce_argument_values ( & mut arguments, parent_type, & name) ?;
892
+
893
+ let is_leaf_type = self . schema . document ( ) . is_leaf_type ( & field_type. field_type ) ;
871
894
let selection_set = if selection_set. items . is_empty ( ) {
895
+ if !is_leaf_type {
896
+ // see: graphql-bug-compat
897
+ // Field requires selection, ignore this field
898
+ return Ok ( None ) ;
899
+ }
872
900
a:: SelectionSet :: new ( vec ! [ ] )
873
901
} else {
874
- let field_type = parent_type. field ( & name) . expect ( "field names are valid" ) ;
875
- let ty = field_type. field_type . get_base_type ( ) ;
876
- let type_set = a:: ObjectTypeSet :: from_name ( & self . schema , ty) ?;
877
- let ty = self . schema . object_or_interface ( ty) . unwrap ( ) ;
878
- self . expand_selection_set ( selection_set, & type_set, ty) ?
902
+ if is_leaf_type {
903
+ // see: graphql-bug-compat
904
+ // Field does not allow selections, ignore selections
905
+ a:: SelectionSet :: new ( vec ! [ ] )
906
+ } else {
907
+ let ty = field_type. field_type . get_base_type ( ) ;
908
+ let type_set = a:: ObjectTypeSet :: from_name ( & self . schema , ty) ?;
909
+ let ty = self . schema . object_or_interface ( ty) . unwrap ( ) ;
910
+ self . expand_selection_set ( selection_set, & type_set, ty) ?
911
+ }
879
912
} ;
880
913
881
914
Ok ( Some ( a:: Field {
0 commit comments