diff --git a/v2/pkg/engine/plan/abstract_selection_rewriter_helpers.go b/v2/pkg/engine/plan/abstract_selection_rewriter_helpers.go index 2288269743..cf0b40db99 100644 --- a/v2/pkg/engine/plan/abstract_selection_rewriter_helpers.go +++ b/v2/pkg/engine/plan/abstract_selection_rewriter_helpers.go @@ -466,7 +466,23 @@ func (r *fieldSelectionRewriter) fieldTypeNameFromUpstreamSchema(fieldRef int, e node, hasNode := r.upstreamDefinition.NodeByName(enclosingTypeName) if !hasNode { - return "", false + var interfaceObjectName string + + for _, objCfg := range r.dsConfiguration.FederationConfiguration().InterfaceObjects { + if slices.Contains(objCfg.ConcreteTypeNames, string(enclosingTypeName)) { + interfaceObjectName = objCfg.InterfaceTypeName + break + } + } + + if interfaceObjectName == "" { + return "", false + } + + node, hasNode = r.upstreamDefinition.NodeByNameStr(interfaceObjectName) + if !hasNode { + return "", false + } } fieldTypeNode, ok := r.upstreamDefinition.FieldTypeNode(fieldName, node) diff --git a/v2/pkg/engine/plan/abstract_selection_rewriter_test.go b/v2/pkg/engine/plan/abstract_selection_rewriter_test.go index 26b7bb74c2..cc920d13ac 100644 --- a/v2/pkg/engine/plan/abstract_selection_rewriter_test.go +++ b/v2/pkg/engine/plan/abstract_selection_rewriter_test.go @@ -3667,6 +3667,66 @@ func TestInterfaceSelectionRewriter_RewriteOperation(t *testing.T) { }`, shouldRewrite: false, }, + { + name: "field is an interface object with concrete type fragments", + definition: ` + type User implements Account { + id: ID! + name: String! + surname: String! + } + + type Admin implements Account { + id: ID! + name: String! + login: String! + } + + interface Account { + id: ID! + title: String! + } + + type Query { + user: Account! + }`, + upstreamDefinition: ` + type Account @key(fields: "id") @interfaceObject { + id: ID! + title: String! + }`, + dsConfiguration: dsb(). + RootNode("Account", "id", "title"). + WithMetadata(func(m *FederationMetaData) { + m.InterfaceObjects = []EntityInterfaceConfiguration{ + { + InterfaceTypeName: "Account", + ConcreteTypeNames: []string{"Admin", "User"}, + }, + } + }). + DS(), + fieldName: "name", + operation: ` + query { + __typename + user { + ... on User { + name + } + } + }`, + expectedOperation: ` + query { + __typename + user { + ... on User { + name + } + } + }`, + shouldRewrite: false, + }, } for _, testCase := range testCases {