Skip to content

Commit e3a8d38

Browse files
authored
Fix nullable nested list variable coercion (#439)
1 parent 7edd6f7 commit e3a8d38

3 files changed

Lines changed: 40 additions & 5 deletions

File tree

validator/testdata/vars.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type Query {
99
structArg(i: InputType!): Boolean!
1010
defaultStructArg(i: InputType! = {name: "foo"}): Boolean!
1111
arrayArg(i: [InputType!]): Boolean!
12+
nestedArrayArg(i: [[InputType!]]): Boolean!
1213
intArrayArg(i: [Int]): Boolean!
1314
stringArrayArg(i: [String]): Boolean!
1415
boolArrayArg(i: [Boolean]): Boolean!

validator/vars.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ func (v *varValidator) validateVarType(
117117
v.path = currentPath
118118
}
119119
defer resetPath()
120+
121+
if !val.IsValid() {
122+
if typ.NonNull {
123+
return val, gqlerror.ErrorPathf(v.path, "cannot be null")
124+
}
125+
return val, nil
126+
}
127+
120128
if typ.Elem != nil {
121129
if val.Kind() != reflect.Slice {
122130
// GraphQL spec says that non-null values should be coerced to an array when possible.
@@ -147,11 +155,6 @@ func (v *varValidator) validateVarType(
147155
panic(fmt.Errorf("missing def for %s", typ.NamedType))
148156
}
149157

150-
if !typ.NonNull && !val.IsValid() {
151-
// If the type is not null and we got a invalid value namely null/nil, then it's valid
152-
return val, nil
153-
}
154-
155158
switch def.Kind {
156159
case ast.Enum:
157160
kind := val.Type().Kind()

validator/vars_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,37 @@ func TestValidateVars(t *testing.T) {
346346
}}, vars["var"])
347347
})
348348

349+
t.Run("null nested list value", func(t *testing.T) {
350+
//nolint:staticcheck
351+
q := gqlparser.MustLoadQuery(
352+
schema,
353+
`query foo($var: [[InputType!]]) { nestedArrayArg(i: $var) }`,
354+
)
355+
vars, gerr := validator.VariableValues(
356+
schema,
357+
q.Operations.ForName(""),
358+
map[string]any{
359+
"var": []any{
360+
[]any{
361+
map[string]any{
362+
"name": "foo",
363+
},
364+
},
365+
nil,
366+
},
367+
},
368+
)
369+
require.NoError(t, gerr)
370+
require.EqualValues(t, []any{
371+
[]any{
372+
map[string]any{
373+
"name": "foo",
374+
},
375+
},
376+
nil,
377+
}, vars["var"])
378+
})
379+
349380
t.Run("null element value", func(t *testing.T) {
350381
//nolint:staticcheck
351382
q := gqlparser.MustLoadQuery(

0 commit comments

Comments
 (0)