1+ use graph:: data:: graphql:: DocumentExt as _;
12use graph:: data:: value:: Object ;
23use graphql_parser:: Pos ;
34use graphql_tools:: validation:: rules:: * ;
@@ -18,7 +19,7 @@ use graph::prelude::{info, o, q, r, s, BlockNumber, CheapClone, Logger, TryFromV
1819
1920use crate :: execution:: ast as a;
2021use crate :: query:: { ast as qast, ext:: BlockConstraint } ;
21- use crate :: schema:: ast as sast;
22+ use crate :: schema:: ast:: { self as sast} ;
2223use crate :: values:: coercion;
2324use crate :: { execution:: get_field, schema:: api:: ErrorPolicy } ;
2425
@@ -861,21 +862,53 @@ impl Transform {
861862 selection_set,
862863 } = field;
863864
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+
864885 let ( directives, skip) = self . interpolate_directives ( directives) ?;
865886 if skip {
866887 return Ok ( None ) ;
867888 }
868889
869890 let mut arguments = self . interpolate_arguments ( arguments, & position) ?;
870891 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 ) ;
871894 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+ }
872900 a:: SelectionSet :: new ( vec ! [ ] )
873901 } 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+ }
879912 } ;
880913
881914 Ok ( Some ( a:: Field {
0 commit comments