diff --git a/cmd/hasura-ndc-go/command/internal/connector_handler.go b/cmd/hasura-ndc-go/command/internal/connector_handler.go index 1d8b3e7..5d1e50f 100644 --- a/cmd/hasura-ndc-go/command/internal/connector_handler.go +++ b/cmd/hasura-ndc-go/command/internal/connector_handler.go @@ -29,9 +29,7 @@ func (chb connectorHandlerBuilder) Render() { bs.imports["github.com/hasura/ndc-sdk-go/connector"] = "" bs.imports["github.com/hasura/ndc-sdk-go/schema"] = "" bs.imports["go.opentelemetry.io/otel/trace"] = "" - if len(chb.Functions) > 0 || len(chb.Procedures) > 0 { - bs.imports[packageSDKUtils] = "" - } + bs.imports[packageSDKUtils] = "" if chb.RawSchema.StateType != nil && bs.packagePath != chb.RawSchema.StateType.PackagePath { bs.imports[chb.RawSchema.StateType.PackagePath] = "" @@ -99,7 +97,7 @@ func (dch DataConnectorHandler) Query(ctx context.Context, state *`) return nil, schema.UnprocessableContentError(err.Error(), nil) } - result, err := dch.execQuery(ctx, state, request, queryFields, rawArgs) + result, err := dch.execQuery(context.WithValue(ctx, utils.CommandSelectionFieldKey, queryFields), state, request, queryFields, rawArgs) if err != nil { return nil, err } @@ -208,6 +206,7 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *`) _, _ = sb.WriteString(`, operation *schema.MutationOperation) (schema.MutationOperationResults, error) { span := trace.SpanFromContext(ctx) logger := connector.GetLogger(ctx) + ctx = context.WithValue(ctx, utils.CommandSelectionFieldKey, operation.Fields) connector_addSpanEvent(span, logger, "validate_request", map[string]any{ "operations_name": operation.Name, }) diff --git a/cmd/hasura-ndc-go/command/internal/testdata/basic/expected/functions.go.tmpl b/cmd/hasura-ndc-go/command/internal/testdata/basic/expected/functions.go.tmpl index 478df2b..101f459 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/basic/expected/functions.go.tmpl +++ b/cmd/hasura-ndc-go/command/internal/testdata/basic/expected/functions.go.tmpl @@ -1203,7 +1203,7 @@ func (dch DataConnectorHandler) Query(ctx context.Context, state *types.State, r return nil, schema.UnprocessableContentError(err.Error(), nil) } - result, err := dch.execQuery(ctx, state, request, queryFields, rawArgs) + result, err := dch.execQuery(context.WithValue(ctx, utils.CommandSelectionFieldKey, queryFields), state, request, queryFields, rawArgs) if err != nil { return nil, err } @@ -1371,6 +1371,7 @@ func (dch DataConnectorHandler) MutationExists(name string) bool { func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State, operation *schema.MutationOperation) (schema.MutationOperationResults, error) { span := trace.SpanFromContext(ctx) logger := connector.GetLogger(ctx) + ctx = context.WithValue(ctx, utils.CommandSelectionFieldKey, operation.Fields) connector_addSpanEvent(span, logger, "validate_request", map[string]any{ "operations_name": operation.Name, }) diff --git a/cmd/hasura-ndc-go/command/internal/testdata/basic/source/go.mod b/cmd/hasura-ndc-go/command/internal/testdata/basic/source/go.mod index 25e5b0d..cfc56d9 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/basic/source/go.mod +++ b/cmd/hasura-ndc-go/command/internal/testdata/basic/source/go.mod @@ -5,6 +5,9 @@ go 1.21 require ( github.com/google/uuid v1.6.0 github.com/hasura/ndc-sdk-go v1.4.1 + go.opentelemetry.io/otel v1.29.0 + go.opentelemetry.io/otel/trace v1.29.0 + golang.org/x/sync v0.10.0 ) require ( @@ -24,7 +27,6 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect go.opentelemetry.io/contrib/bridges/otelslog v0.4.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.29.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.5.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 // indirect @@ -38,7 +40,6 @@ require ( go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.opentelemetry.io/otel/sdk/log v0.5.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect - go.opentelemetry.io/otel/trace v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect diff --git a/cmd/hasura-ndc-go/command/internal/testdata/basic/source/go.sum b/cmd/hasura-ndc-go/command/internal/testdata/basic/source/go.sum index 9a566a9..496aef4 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/basic/source/go.sum +++ b/cmd/hasura-ndc-go/command/internal/testdata/basic/source/go.sum @@ -85,6 +85,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/cmd/hasura-ndc-go/command/internal/testdata/empty/source/go.mod b/cmd/hasura-ndc-go/command/internal/testdata/empty/source/go.mod index 374dc6f..916d289 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/empty/source/go.mod +++ b/cmd/hasura-ndc-go/command/internal/testdata/empty/source/go.mod @@ -2,7 +2,11 @@ module github.com/hasura/ndc-codegen-empty-test go 1.21 -require github.com/hasura/ndc-sdk-go v1.4.1 +require ( + github.com/hasura/ndc-sdk-go v1.4.1 + go.opentelemetry.io/otel v1.29.0 + golang.org/x/sync v0.10.0 +) require ( github.com/alecthomas/kong v1.6.0 // indirect @@ -22,7 +26,6 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect go.opentelemetry.io/contrib/bridges/otelslog v0.4.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.29.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.5.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 // indirect diff --git a/cmd/hasura-ndc-go/command/internal/testdata/empty/source/go.sum b/cmd/hasura-ndc-go/command/internal/testdata/empty/source/go.sum index 9a566a9..496aef4 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/empty/source/go.sum +++ b/cmd/hasura-ndc-go/command/internal/testdata/empty/source/go.sum @@ -85,6 +85,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/cmd/hasura-ndc-go/command/internal/testdata/single_op/source/go.mod b/cmd/hasura-ndc-go/command/internal/testdata/single_op/source/go.mod index e1d2840..c2ea6c9 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/single_op/source/go.mod +++ b/cmd/hasura-ndc-go/command/internal/testdata/single_op/source/go.mod @@ -2,7 +2,12 @@ module github.com/hasura/ndc-codegen-function-only-test go 1.21 -require github.com/hasura/ndc-sdk-go v1.6.2 +require ( + github.com/hasura/ndc-sdk-go v1.6.2 + go.opentelemetry.io/otel v1.29.0 + go.opentelemetry.io/otel/trace v1.29.0 + golang.org/x/sync v0.10.0 +) require ( github.com/alecthomas/kong v1.6.0 // indirect @@ -22,7 +27,6 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect go.opentelemetry.io/contrib/bridges/otelslog v0.4.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.29.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.5.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 // indirect @@ -36,7 +40,6 @@ require ( go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.opentelemetry.io/otel/sdk/log v0.5.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect - go.opentelemetry.io/otel/trace v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect diff --git a/cmd/hasura-ndc-go/command/internal/testdata/single_op/source/go.sum b/cmd/hasura-ndc-go/command/internal/testdata/single_op/source/go.sum index 9a566a9..496aef4 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/single_op/source/go.sum +++ b/cmd/hasura-ndc-go/command/internal/testdata/single_op/source/go.sum @@ -85,6 +85,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/cmd/hasura-ndc-go/command/internal/testdata/snake_case/expected/functions.go.tmpl b/cmd/hasura-ndc-go/command/internal/testdata/snake_case/expected/functions.go.tmpl index d250503..6eca6ea 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/snake_case/expected/functions.go.tmpl +++ b/cmd/hasura-ndc-go/command/internal/testdata/snake_case/expected/functions.go.tmpl @@ -897,7 +897,7 @@ func (dch DataConnectorHandler) Query(ctx context.Context, state *types.State, r return nil, schema.UnprocessableContentError(err.Error(), nil) } - result, err := dch.execQuery(ctx, state, request, queryFields, rawArgs) + result, err := dch.execQuery(context.WithValue(ctx, utils.CommandSelectionFieldKey, queryFields), state, request, queryFields, rawArgs) if err != nil { return nil, err } @@ -1032,6 +1032,7 @@ func (dch DataConnectorHandler) MutationExists(name string) bool { func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State, operation *schema.MutationOperation) (schema.MutationOperationResults, error) { span := trace.SpanFromContext(ctx) logger := connector.GetLogger(ctx) + ctx = context.WithValue(ctx, utils.CommandSelectionFieldKey, operation.Fields) connector_addSpanEvent(span, logger, "validate_request", map[string]any{ "operations_name": operation.Name, }) diff --git a/cmd/hasura-ndc-go/command/internal/testdata/snake_case/source/go.mod b/cmd/hasura-ndc-go/command/internal/testdata/snake_case/source/go.mod index 59ea83d..427f6c9 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/snake_case/source/go.mod +++ b/cmd/hasura-ndc-go/command/internal/testdata/snake_case/source/go.mod @@ -5,6 +5,9 @@ go 1.21 require ( github.com/google/uuid v1.6.0 github.com/hasura/ndc-sdk-go v1.6.3 + go.opentelemetry.io/otel v1.29.0 + go.opentelemetry.io/otel/trace v1.29.0 + golang.org/x/sync v0.10.0 ) require ( @@ -24,7 +27,6 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect go.opentelemetry.io/contrib/bridges/otelslog v0.4.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.29.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.5.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.5.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 // indirect @@ -38,7 +40,6 @@ require ( go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.opentelemetry.io/otel/sdk/log v0.5.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect - go.opentelemetry.io/otel/trace v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect diff --git a/cmd/hasura-ndc-go/command/internal/testdata/snake_case/source/go.sum b/cmd/hasura-ndc-go/command/internal/testdata/snake_case/source/go.sum index 9a566a9..496aef4 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/snake_case/source/go.sum +++ b/cmd/hasura-ndc-go/command/internal/testdata/snake_case/source/go.sum @@ -85,6 +85,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/cmd/hasura-ndc-go/command/internal/testdata/subdir/expected/functions.go.tmpl b/cmd/hasura-ndc-go/command/internal/testdata/subdir/expected/functions.go.tmpl index 0c0b0c0..e3c21ba 100644 --- a/cmd/hasura-ndc-go/command/internal/testdata/subdir/expected/functions.go.tmpl +++ b/cmd/hasura-ndc-go/command/internal/testdata/subdir/expected/functions.go.tmpl @@ -49,7 +49,7 @@ func (dch DataConnectorHandler) Query(ctx context.Context, state *types.State, r return nil, schema.UnprocessableContentError(err.Error(), nil) } - result, err := dch.execQuery(ctx, state, request, queryFields, rawArgs) + result, err := dch.execQuery(context.WithValue(ctx, utils.CommandSelectionFieldKey, queryFields), state, request, queryFields, rawArgs) if err != nil { return nil, err } diff --git a/example/codegen/functions/prefix.go b/example/codegen/functions/prefix.go index 866eec5..a971d82 100644 --- a/example/codegen/functions/prefix.go +++ b/example/codegen/functions/prefix.go @@ -3,6 +3,7 @@ package functions import ( "context" "encoding/json" + "errors" "fmt" "time" @@ -63,6 +64,11 @@ type CreateAuthorResult struct { // ProcedureCreateAuthor creates an author func ProcedureCreateAuthor(ctx context.Context, state *types.State, arguments *CreateAuthorArguments) (*CreateAuthorResult, error) { + selection := utils.CommandSelectionFieldFromContext(ctx) + if len(selection) == 0 { + return nil, errors.New("expected not-null selection field, got null") + } + return &CreateAuthorResult{ ID: 1, Name: arguments.Name, @@ -92,6 +98,11 @@ func FunctionGetInts(ctx context.Context, state *types.State) ([]*int, error) { } func FunctionGetTypes(ctx context.Context, state *types.State, arguments *arguments.GetTypesArguments) (*arguments.GetTypesArguments, error) { + selection := utils.CommandSelectionFieldFromContext(ctx) + if len(selection) == 0 { + return nil, errors.New("expected not-null selection field, got null") + } + return arguments, nil } diff --git a/example/codegen/functions/types.generated.go b/example/codegen/functions/types.generated.go index cb7804f..19f4e36 100644 --- a/example/codegen/functions/types.generated.go +++ b/example/codegen/functions/types.generated.go @@ -148,7 +148,7 @@ func (dch DataConnectorHandler) Query(ctx context.Context, state *types.State, r return nil, schema.UnprocessableContentError(err.Error(), nil) } - result, err := dch.execQuery(ctx, state, request, queryFields, rawArgs) + result, err := dch.execQuery(context.WithValue(ctx, utils.CommandSelectionFieldKey, queryFields), state, request, queryFields, rawArgs) if err != nil { return nil, err } @@ -429,6 +429,7 @@ func (dch DataConnectorHandler) MutationExists(name string) bool { func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State, operation *schema.MutationOperation) (schema.MutationOperationResults, error) { span := trace.SpanFromContext(ctx) logger := connector.GetLogger(ctx) + ctx = context.WithValue(ctx, utils.CommandSelectionFieldKey, operation.Fields) connector_addSpanEvent(span, logger, "validate_request", map[string]any{ "operations_name": operation.Name, }) diff --git a/example/codegen/go.mod b/example/codegen/go.mod index 01b0b59..51d973a 100644 --- a/example/codegen/go.mod +++ b/example/codegen/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 - github.com/hasura/ndc-sdk-go v1.6.0 + github.com/hasura/ndc-sdk-go v1.6.4 go.opentelemetry.io/otel v1.29.0 go.opentelemetry.io/otel/trace v1.29.0 golang.org/x/sync v0.10.0 diff --git a/example/codegen/types/types.generated.go b/example/codegen/types/types.generated.go index 9ca029e..109b405 100644 --- a/example/codegen/types/types.generated.go +++ b/example/codegen/types/types.generated.go @@ -64,7 +64,7 @@ var enumValues_AuthorStatus = []AuthorStatus{AuthorStatusActive, AuthorStatusIna func ParseAuthorStatus(input string) (AuthorStatus, error) { result := AuthorStatus(input) if !slices.Contains(enumValues_AuthorStatus, result) { - return AuthorStatus(""), errors.New("failed to parse AuthorStatus, expect one of AuthorStatusActive, AuthorStatusInactive") + return AuthorStatus(""), errors.New("failed to parse AuthorStatus, expect one of [active, inactive]") } return result, nil diff --git a/utils/connector.go b/utils/connector.go index 0855808..dbf8544 100644 --- a/utils/connector.go +++ b/utils/connector.go @@ -1,6 +1,7 @@ package utils import ( + "context" "errors" "fmt" "reflect" @@ -10,6 +11,9 @@ import ( const ( errFunctionValueFieldRequired = "__value field is required in query function type" + + // CommandSelectionFieldKey the context key for the nested selection field in command. + CommandSelectionFieldKey string = "ndc-command-selection-field" ) var ErrHandlerNotfound = errors.New("connector handler not found") @@ -322,3 +326,15 @@ func MergeSchemas(schemas ...*schema.SchemaResponse) (*schema.SchemaResponse, [] } return &result, errs } + +// CommandSelectionFieldFromContext gets the command's nested selection field from context. +func CommandSelectionFieldFromContext(ctx context.Context) schema.NestedField { + value := ctx.Value(CommandSelectionFieldKey) + if value != nil { + if selection, ok := value.(schema.NestedField); ok { + return selection + } + } + + return nil +}