diff --git a/graphql/context_operation_test.go b/graphql/context_operation_test.go index 02a8ae7259b..4ce374601f7 100644 --- a/graphql/context_operation_test.go +++ b/graphql/context_operation_test.go @@ -106,4 +106,31 @@ func TestCollectAllFields(t *testing.T) { require.NotEqual(t, collected[0], collected[1]) require.Equal(t, collected[0].Name, collected[1].Name) }) + + t.Run("collect fragments with same field name and different alias", func(t *testing.T) { + ctx := testContext(ast.SelectionSet{ + &ast.InlineFragment{ + TypeCondition: "ExampleTypeA", + SelectionSet: ast.SelectionSet{ + &ast.Field{ + Name: "fieldA", + Alias: "fieldA", + ObjectDefinition: &ast.Definition{Name: "ExampleTypeA"}, + }, + &ast.Field{ + Name: "fieldA", + Alias: "fieldA Alias", + ObjectDefinition: &ast.Definition{Name: "ExampleTypeA"}, + }, + }, + ObjectDefinition: &ast.Definition{Name: "ExampleType", Kind: ast.Interface}, + }, + }) + resCtx := GetFieldContext(ctx) + collected := CollectFields(GetOperationContext(ctx), resCtx.Field.Selections, nil) + require.Len(t, collected, 2) + require.NotEqual(t, collected[0], collected[1]) + require.Equal(t, collected[0].Name, collected[1].Name) + require.NotEqual(t, collected[0].Alias, collected[1].Alias) + }) } diff --git a/graphql/executable_schema.go b/graphql/executable_schema.go index dc53b6881ef..012baafff48 100644 --- a/graphql/executable_schema.go +++ b/graphql/executable_schema.go @@ -32,7 +32,7 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies if !shouldIncludeNode(sel.Directives, reqCtx.Variables) { continue } - f := getOrCreateAndAppendField(&groupedFields, sel.Alias, sel.ObjectDefinition, func() CollectedField { + f := getOrCreateAndAppendField(&groupedFields, sel.Name, sel.Alias, sel.ObjectDefinition, func() CollectedField { return CollectedField{Field: sel} }) @@ -45,7 +45,7 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies continue } for _, childField := range collectFields(reqCtx, sel.SelectionSet, satisfies, visited) { - f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.ObjectDefinition, func() CollectedField { return childField }) + f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) f.Selections = append(f.Selections, childField.Selections...) } @@ -70,7 +70,7 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies } for _, childField := range collectFields(reqCtx, fragment.SelectionSet, satisfies, visited) { - f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.ObjectDefinition, func() CollectedField { return childField }) + f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) f.Selections = append(f.Selections, childField.Selections...) } default: @@ -96,9 +96,9 @@ func instanceOf(val string, satisfies []string) bool { return false } -func getOrCreateAndAppendField(c *[]CollectedField, name string, objectDefinition *ast.Definition, creator func() CollectedField) *CollectedField { +func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, objectDefinition *ast.Definition, creator func() CollectedField) *CollectedField { for i, cf := range *c { - if cf.Alias == name && (cf.ObjectDefinition == objectDefinition || (cf.ObjectDefinition != nil && objectDefinition != nil && cf.ObjectDefinition.Name == objectDefinition.Name)) { + if cf.Name == name && cf.Alias == alias && (cf.ObjectDefinition == objectDefinition || (cf.ObjectDefinition != nil && objectDefinition != nil && cf.ObjectDefinition.Name == objectDefinition.Name)) { return &(*c)[i] } }