diff --git a/internal/exec/exec.go b/internal/exec/exec.go index 0f9f5f98132..49d164e7ed8 100644 --- a/internal/exec/exec.go +++ b/internal/exec/exec.go @@ -77,13 +77,6 @@ func (r *Request) execSelection(ctx context.Context, sel selected.Selection, res } } - case *selected.MetaField: - subresults := make(map[string]interface{}) - for _, subsel := range sel.Sels { - r.execSelection(ctx, subsel, sel.Resolver, subresults) - } - results[sel.Alias] = subresults - case *selected.TypeAssertion: out := resolver.Method(sel.MethodIndex).Call(nil) if !out[1].Bool() { @@ -119,6 +112,11 @@ func (r *Request) execFieldSelection(ctx context.Context, field *selected.Schema } }() + if field.FixedResult.IsValid() { + result = field.FixedResult + return nil + } + if err := traceCtx.Err(); err != nil { return errors.Errorf("%s", err) // don't execute any more resolvers if context got cancelled } diff --git a/internal/exec/resolvable/meta.go b/internal/exec/resolvable/meta.go index 491b2345cfb..cf4e7dd1951 100644 --- a/internal/exec/resolvable/meta.go +++ b/internal/exec/resolvable/meta.go @@ -1,6 +1,7 @@ package resolvable import ( + "fmt" "reflect" "github.com/neelance/graphql-go/internal/schema" @@ -30,3 +31,19 @@ func init() { panic(err) } } + +var MetaFieldSchema = Field{ + Field: schema.Field{ + Name: "__schema", + Type: schema.Meta.Types["__Schema"], + }, + TraceLabel: fmt.Sprintf("GraphQL field: __schema"), +} + +var MetaFieldType = Field{ + Field: schema.Field{ + Name: "__type", + Type: schema.Meta.Types["__Type"], + }, + TraceLabel: fmt.Sprintf("GraphQL field: __type"), +} diff --git a/internal/exec/selected/selected.go b/internal/exec/selected/selected.go index a41ee1532b0..69bb94705ce 100644 --- a/internal/exec/selected/selected.go +++ b/internal/exec/selected/selected.go @@ -52,10 +52,11 @@ type Selection interface { type SchemaField struct { resolvable.Field - Alias string - Args map[string]interface{} - PackedArgs reflect.Value - Sels []Selection + Alias string + Args map[string]interface{} + PackedArgs reflect.Value + Sels []Selection + FixedResult reflect.Value } type TypeAssertion struct { @@ -68,16 +69,9 @@ type TypenameField struct { Alias string } -type MetaField struct { - Alias string - Sels []Selection - Resolver reflect.Value -} - func (*SchemaField) isSelection() {} func (*TypeAssertion) isSelection() {} func (*TypenameField) isSelection() {} -func (*MetaField) isSelection() {} func applySelectionSet(r *Request, e *resolvable.Object, selSet *query.SelectionSet) (sels []Selection) { if selSet == nil { @@ -99,10 +93,11 @@ func applySelectionSet(r *Request, e *resolvable.Object, selSet *query.Selection }) case "__schema": - sels = append(sels, &MetaField{ - Alias: field.Alias.Name, - Sels: applySelectionSet(r, resolvable.MetaSchema, field.SelSet), - Resolver: reflect.ValueOf(introspection.WrapSchema(r.Schema)), + sels = append(sels, &SchemaField{ + Field: resolvable.MetaFieldSchema, + Alias: field.Alias.Name, + Sels: applySelectionSet(r, resolvable.MetaSchema, field.SelSet), + FixedResult: reflect.ValueOf(introspection.WrapSchema(r.Schema)), }) case "__type": @@ -118,10 +113,11 @@ func applySelectionSet(r *Request, e *resolvable.Object, selSet *query.Selection return nil } - sels = append(sels, &MetaField{ - Alias: field.Alias.Name, - Sels: applySelectionSet(r, resolvable.MetaType, field.SelSet), - Resolver: reflect.ValueOf(introspection.WrapType(t)), + sels = append(sels, &SchemaField{ + Field: resolvable.MetaFieldType, + Alias: field.Alias.Name, + Sels: applySelectionSet(r, resolvable.MetaType, field.SelSet), + FixedResult: reflect.ValueOf(introspection.WrapType(t)), }) default: