@@ -1594,9 +1594,9 @@ Input Objects are allowed to reference other Input Objects as field types. A
15941594circular reference occurs when an Input Object references itself either directly
15951595or through referenced Input Objects .
15961596
1597- Circular references are generally allowed , however they may not be defined as an
1598- unbroken chain of Non - Null singular fields . Such Input Objects are invalid
1599- because there is no way to provide a legal value for them .
1597+ Circular references are generally allowed , however they may not form cycles such
1598+ that no finite value can be provided . Such Input Objects are invalid because
1599+ there is no way to provide a legal value for them .
16001600
16011601This example of a circularly -referenced input type is valid as the field `self `
16021602may be omitted or the value {null }.
@@ -1642,32 +1642,19 @@ input Second {
16421642}
16431643```
16441644
1645- _OneOf Input Objects_ introduce another case where a field cannot be provided a
1646- finite value . Because exactly one field must be set and must be non - null ,
1647- nullable fields do not provide an escape from recursion as they do in regular
1648- Input Objects . This OneOf Input Object is invalid because its only field
1649- references itself , and a non - null value must always be provided :
1645+ Because _OneOf Input Objects_ require exactly one field to be set and non - null ,
1646+ nullable fields do not allow a finite value to be provided as they do in other
1647+ Input Objects . This example is invalid because providing a value for ` First `
1648+ requires a non - null ` Second `, and constructing a ` Second ` requires a non - null
1649+ ` First ` :
16501650
16511651```graphql counter -example
1652- input Example @oneOf {
1653- self : Example
1652+ input First @oneOf {
1653+ second : Second
16541654}
1655- ```
1656-
1657- However , a OneOf Input Object that references itself is valid when at least one
1658- field provides a path to a type that is not a OneOf Input Object :
16591655
1660- ```graphql example
1661- input PetInput @oneOf {
1662- cat : CatInput
1663- dog : DogInput
1664- self : PetInput
1665- }
1666- input CatInput {
1667- name : String !
1668- }
1669- input DogInput {
1670- name : String !
1656+ input Second {
1657+ first : First !
16711658}
16721659```
16731660
@@ -1755,12 +1742,8 @@ input ExampleInputObject {
17551742 5. If the Input Object is a _OneOf Input Object_ then :
17561743 1. The type of the input field must be nullable .
17571744 2. The input field must not have a default value .
1758- 3. If an Input Object references itself either directly or through referenced
1759- Input Objects , at least one of the fields in the chain of references must be
1760- either a nullable or a List type .
1745+ 3. {InputObjectCanBeProvidedAFiniteValue (inputObject)} must be {true }.
176117464. {InputObjectDefaultValueHasCycle (inputObject)} must be {false }.
1762- 5. If the Input Object is a _OneOf Input Object_ ,
1763- {OneOfInputObjectCanBeProvidedAFiniteValue (inputObject)} must be {true }.
17641747
17651748InputObjectDefaultValueHasCycle (inputObject, defaultValue, visitedFields):
17661749
@@ -1799,25 +1782,39 @@ InputFieldDefaultValueHasCycle(field, defaultValue, visitedFields):
17991782 - Return {InputObjectDefaultValueHasCycle (namedFieldType, fieldDefaultValue,
18001783 nextVisitedFields)}.
18011784
1802- OneOfInputObjectCanBeProvidedAFiniteValue (oneOfInputObject , visited):
1785+ InputObjectCanBeProvidedAFiniteValue (inputObject , visited):
18031786
18041787- If {visited } is not provided , initialize it to the empty set .
1805- - If {oneOfInputObject } is within {visited }:
1788+ - If {inputObject } is in {visited }:
18061789 - Return {false }.
1807- - Let {nextVisited } be a new set containing {oneOfInputObject } and everything
1790+ - Let {nextVisited } be a new set containing {inputObject } and everything
18081791 from {visited }.
1809- - For each field {field } of {oneOfInputObject }:
1810- - Let {fieldType } be the type of {field }.
1811- - If {fieldType } is a List type :
1812- - Return {true }.
1813- - Let {namedFieldType } be the underlying named type of {fieldType }.
1814- - If {namedFieldType } is not an Input Object type :
1815- - Return {true }.
1816- - If {namedFieldType } is not a _OneOf Input Object_ :
1817- - Return {true }.
1818- - If {OneOfInputObjectCanBeProvidedAFiniteValue (namedFieldType, nextVisited)}:
1819- - Return {true }.
1820- - Return {false }.
1792+ - If {inputObject } is a _OneOf Input Object_ :
1793+ - For each field {field } of {inputObject }:
1794+ - Let {fieldType } be the type of {field }.
1795+ - If {FieldTypeCanBeProvidedAFiniteValue (fieldType, nextVisited)}:
1796+ - Return {true }.
1797+ - Return {false }.
1798+ - Otherwise :
1799+ - For each field {field } of {inputObject }:
1800+ - Let {fieldType } be the type of {field }.
1801+ - If {fieldType } is Non -Null :
1802+ - Let {innerType } be the type wrapped by {fieldType }.
1803+ - If not {FieldTypeCanBeProvidedAFiniteValue (innerType, nextVisited)}:
1804+ - Return {false }.
1805+ - Return {true }.
1806+
1807+ FieldTypeCanBeProvidedAFiniteValue (fieldType, visited):
1808+
1809+ - If {fieldType } is a List type :
1810+ - Return {true }.
1811+ - If {fieldType } is a Non -Null type :
1812+ - Let {innerType } be the type wrapped by {fieldType }.
1813+ - Return {FieldTypeCanBeProvidedAFiniteValue (innerType, visited)}.
1814+ - Assert : {fieldType } is a named type .
1815+ - If {fieldType } is not an Input Object type :
1816+ - Return {true }.
1817+ - Return {InputObjectCanBeProvidedAFiniteValue (fieldType, visited)}.
18211818
18221819### OneOf Input Objects
18231820
0 commit comments