diff --git a/src/HotChocolate/Fusion/src/Core/Planning/RequestFormatters/RequestDocumentFormatter.cs b/src/HotChocolate/Fusion/src/Core/Planning/RequestFormatters/RequestDocumentFormatter.cs index a7fcd8d1f66..dedc66bd463 100644 --- a/src/HotChocolate/Fusion/src/Core/Planning/RequestFormatters/RequestDocumentFormatter.cs +++ b/src/HotChocolate/Fusion/src/Core/Planning/RequestFormatters/RequestDocumentFormatter.cs @@ -608,16 +608,11 @@ protected void TryForwardVariable( var originalVarDef = context.Operation.Definition.VariableDefinitions .First(t => t.Variable.Equals(variableValue, SyntaxComparison.Syntax)); - if (resolver is null || !resolver.ArgumentTypes.TryGetValue(argumentName, out var type)) - { - type = originalVarDef.Type; - } - context.ForwardedVariables.Add( new VariableDefinitionNode( null, variableValue, - type, + originalVarDef.Type, originalVarDef.DefaultValue, Array.Empty())); } diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph.md b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph.md index 082e8659f0a..29d0345c8bd 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph.md +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph.md @@ -10,6 +10,7 @@ schema { type Query { errorField: String + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int userById(id: ID!): User users: [User!]! usersById(ids: [ID!]!): [User!]! @@ -66,6 +67,7 @@ schema @fusion(version: 1) @transport(subgraph: "Accounts", group: "Fusion", loc type Query { errorField: String @resolver(subgraph: "Accounts", select: "{ errorField }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int @variable(subgraph: "Accounts", name: "first", argument: "first") @variable(subgraph: "Accounts", name: "second", argument: "second") @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) @@ -117,7 +119,7 @@ scalar Date ```json { "Name": "Accounts", - "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n errorField: String\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\ntype User implements Node {\n errorField: String\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: Date!\n}\n\ntype AddUserPayload {\n user: User\n}", + "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n errorField: String\n testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype User implements Node {\n errorField: String\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: Date!\n}\n\ntype AddUserPayload {\n user: User\n}", "Extensions": [ "extend type Query {\n userById(id: ID!\n @is(field: \"id\")): User!\n usersById(ids: [ID!]!\n @is(field: \"id\")): [User!]!\n}" ], diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Append_Subgraph.md b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Append_Subgraph.md index 49581d92c59..3bbe74c1b0c 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Append_Subgraph.md +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Append_Subgraph.md @@ -15,6 +15,7 @@ type Query { reviewById(id: ID!): Review reviewOrAuthor: ReviewOrAuthor! reviews: [Review!]! + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int userById(id: ID!): User users: [User!]! usersById(ids: [ID!]!): [User!]! @@ -111,6 +112,7 @@ type Query { reviewById(id: ID!): Review @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) reviewOrAuthor: ReviewOrAuthor! @resolver(subgraph: "Reviews2", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews2", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int @variable(subgraph: "Accounts", name: "first", argument: "first") @variable(subgraph: "Accounts", name: "second", argument: "second") @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) @@ -197,7 +199,7 @@ scalar Date ```json { "Name": "Accounts", - "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n errorField: String\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\ntype User implements Node {\n errorField: String\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: Date!\n}\n\ntype AddUserPayload {\n user: User\n}", + "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n errorField: String\n testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype User implements Node {\n errorField: String\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: Date!\n}\n\ntype AddUserPayload {\n user: User\n}", "Extensions": [ "extend type Query {\n userById(id: ID!\n @is(field: \"id\")): User!\n usersById(ids: [ID!]!\n @is(field: \"id\")): [User!]!\n}" ], diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Remove_Subgraph.md b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Remove_Subgraph.md index bfcd53741b9..e731f4388da 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Remove_Subgraph.md +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Remove_Subgraph.md @@ -10,6 +10,7 @@ schema { type Query { errorField: String + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int userById(id: ID!): User users: [User!]! usersById(ids: [ID!]!): [User!]! @@ -66,6 +67,7 @@ schema @fusion(version: 1) @transport(subgraph: "Accounts", group: "Fusion", loc type Query { errorField: String @resolver(subgraph: "Accounts", select: "{ errorField }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int @variable(subgraph: "Accounts", name: "first", argument: "first") @variable(subgraph: "Accounts", name: "second", argument: "second") @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) @@ -117,7 +119,7 @@ scalar Date ```json { "Name": "Accounts", - "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n errorField: String\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\ntype User implements Node {\n errorField: String\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: Date!\n}\n\ntype AddUserPayload {\n user: User\n}", + "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n errorField: String\n testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype User implements Node {\n errorField: String\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: Date!\n}\n\ntype AddUserPayload {\n user: User\n}", "Extensions": [ "extend type Query {\n userById(id: ID!\n @is(field: \"id\")): User!\n usersById(ids: [ID!]!\n @is(field: \"id\")): [User!]!\n}" ], diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Extract_Extensions.snap b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Extract_Extensions.snap index 0f98e06d2a6..be8aaf9577e 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Extract_Extensions.snap +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Extract_Extensions.snap @@ -24,6 +24,7 @@ type Query { userById(id: ID!): User usersById(ids: [ID!]!): [User!]! errorField: String + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int viewer: Viewer! } @@ -34,11 +35,6 @@ type Mutation { "The `Date` scalar represents an ISO-8601 compliant date type." scalar Date -type Viewer { - user: User - data: SomeData! -} - type User implements Node { errorField: String id: ID! @@ -47,6 +43,11 @@ type User implements Node { username: String! } +type Viewer { + user: User + data: SomeData! +} + type SomeData { accountValue: String! } diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Subgraph_Package.snap b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Subgraph_Package.snap index 302843dd60d..a7574ad2c6c 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Subgraph_Package.snap +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Subgraph_Package.snap @@ -24,6 +24,7 @@ type Query { userById(id: ID!): User usersById(ids: [ID!]!): [User!]! errorField: String + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int viewer: Viewer! } @@ -34,11 +35,6 @@ type Mutation { "The `Date` scalar represents an ISO-8601 compliant date type." scalar Date -type Viewer { - user: User - data: SomeData! -} - type User implements Node { errorField: String id: ID! @@ -47,6 +43,11 @@ type User implements Node { username: String! } +type Viewer { + user: User + data: SomeData! +} + type SomeData { accountValue: String! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews.graphql index f59c07dfa55..a16a8421088 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews.graphql @@ -22,6 +22,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews2_Products_With_Nodes.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews2_Products_With_Nodes.graphql index 66afb7d7763..29c48e88950 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews2_Products_With_Nodes.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews2_Products_With_Nodes.graphql @@ -43,6 +43,10 @@ type Query { @resolver(subgraph: "Reviews2", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews2", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) topProducts(first: Int!): [Product!]! @variable(subgraph: "Products", name: "first", argument: "first") @resolver(subgraph: "Products", select: "{ topProducts(first: $first) }", arguments: [ { name: "first", type: "Int!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Infer_Patterns.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Infer_Patterns.graphql index a948142ed8d..d389e793f6e 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Infer_Patterns.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Infer_Patterns.graphql @@ -22,6 +22,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products.graphql index 98977ffc0de..cc83928d536 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products.graphql @@ -32,6 +32,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) topProducts(first: Int!): [Product!]! @variable(subgraph: "Products", name: "first", argument: "first") @resolver(subgraph: "Products", select: "{ topProducts(first: $first) }", arguments: [ { name: "first", type: "Int!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_AutoCompose_With_Node.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_AutoCompose_With_Node.graphql index 22f58462f95..5cd926234cd 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_AutoCompose_With_Node.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_AutoCompose_With_Node.graphql @@ -35,6 +35,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) topProducts(first: Int!): [Product!]! @variable(subgraph: "Products", name: "first", argument: "first") @resolver(subgraph: "Products", select: "{ topProducts(first: $first) }", arguments: [ { name: "first", type: "Int!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_With_Nodes.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_With_Nodes.graphql index afbaeec068d..9a5d4bc3019 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_With_Nodes.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_With_Nodes.graphql @@ -43,6 +43,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) topProducts(first: Int!): [Product!]! @variable(subgraph: "Products", name: "first", argument: "first") @resolver(subgraph: "Products", select: "{ topProducts(first: $first) }", arguments: [ { name: "first", type: "Int!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_With_Cost.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_With_Cost.graphql index 06f25f2f81a..ed923047c0f 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_With_Cost.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_With_Cost.graphql @@ -22,6 +22,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Compose_With_SourceSchema_Lib.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Compose_With_SourceSchema_Lib.graphql index ff8b096a22a..e386198b80e 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Compose_With_SourceSchema_Lib.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Compose_With_SourceSchema_Lib.graphql @@ -37,6 +37,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) topProducts(first: Int!): [Product!]! @variable(subgraph: "Products", name: "first", argument: "first") @resolver(subgraph: "Products", select: "{ topProducts(first: $first) }", arguments: [ { name: "first", type: "Int!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/RequireTests.Require_Scalar_Arguments_No_Overloads.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/RequireTests.Require_Scalar_Arguments_No_Overloads.graphql index effb33abc06..8b955a7c148 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/RequireTests.Require_Scalar_Arguments_No_Overloads.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/RequireTests.Require_Scalar_Arguments_No_Overloads.graphql @@ -39,6 +39,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) topProducts(first: Int!): [Product!]! @variable(subgraph: "Products", name: "first", argument: "first") @resolver(subgraph: "Products", select: "{ topProducts(first: $first) }", arguments: [ { name: "first", type: "Int!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Do_Not_Expose_Tags_On_Public_Schema.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Do_Not_Expose_Tags_On_Public_Schema.graphql index 31f9b8271ee..dd44a565d7f 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Do_Not_Expose_Tags_On_Public_Schema.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Do_Not_Expose_Tags_On_Public_Schema.graphql @@ -25,6 +25,10 @@ type Query { someTypeById(id: ID!): SomeType! @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ someTypeById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Subgraphs_With_Review_Tag.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Subgraphs_With_Review_Tag.graphql index 1a2b4cb566e..41ce33e5088 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Subgraphs_With_Review_Tag.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Subgraphs_With_Review_Tag.graphql @@ -14,6 +14,10 @@ type Query { someTypeById(id: ID!): SomeType! @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ someTypeById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag.graphql index 3f00fd52adf..5278c7a6b09 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag.graphql @@ -23,6 +23,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag_Which_Is_Private.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag_Which_Is_Private.graphql index 60347bf2478..b13a1229298 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag_Which_Is_Private.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag_Which_Is_Private.graphql @@ -22,6 +22,10 @@ type Query { @resolver(subgraph: "Reviews", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Expose_Tags_On_Public_Schema.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Expose_Tags_On_Public_Schema.graphql index 4b825136d54..71b70c5081d 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Expose_Tags_On_Public_Schema.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Expose_Tags_On_Public_Schema.graphql @@ -25,6 +25,10 @@ type Query { someTypeById(id: ID!): SomeType! @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ someTypeById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Core.Tests/DemoIntegrationTests.cs b/src/HotChocolate/Fusion/test/Core.Tests/DemoIntegrationTests.cs index aca41b49535..bba26390ebf 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/DemoIntegrationTests.cs +++ b/src/HotChocolate/Fusion/test/Core.Tests/DemoIntegrationTests.cs @@ -2572,6 +2572,49 @@ type Query { MatchMarkdownSnapshot(request, result); } + [Fact] + public async Task Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables() + { + // arrange + using var demoProject = await DemoProject.CreateAsync(); + + // act + var fusionGraph = await new FusionGraphComposer(logFactory: _logFactory).ComposeAsync( + new[] + { + demoProject.Accounts.ToConfiguration(AccountsExtensionSdl) + }); + + var executor = await new ServiceCollection() + .AddSingleton(demoProject.HttpClientFactory) + .AddSingleton(demoProject.WebSocketConnectionFactory) + .AddFusionGatewayServer() + .ConfigureFromDocument(SchemaFormatter.FormatAsDocument(fusionGraph)) + .BuildRequestExecutorAsync(); + + var request = Parse( + """ + query Test($number: Int!) { + testWithTwoArgumentsDifferingNullability(first: $number, second: $number) + } + """); + + // act + await using var result = await executor.ExecuteAsync( + OperationRequestBuilder + .New() + .SetDocument(request) + .SetVariableValues(new Dictionary { { "number", 1 } }) + .Build()); + + // assert + var snapshot = new Snapshot(); + CollectSnapshotData(snapshot, request, result); + await snapshot.MatchMarkdownAsync(); + + Assert.Null(result.ExpectOperationResult().Errors); + } + public sealed class HotReloadConfiguration : IObservable { private GatewayConfiguration _configuration; diff --git a/src/HotChocolate/Fusion/test/Core.Tests/RequestPlannerTests.cs b/src/HotChocolate/Fusion/test/Core.Tests/RequestPlannerTests.cs index c23e51b1624..97cbbfe9039 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/RequestPlannerTests.cs +++ b/src/HotChocolate/Fusion/test/Core.Tests/RequestPlannerTests.cs @@ -2859,6 +2859,34 @@ type Author { await snapshot.MatchMarkdownAsync(); } + [Fact] + public async Task Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables() + { + // arrange + using var demoProject = await DemoProject.CreateAsync(); + + var fusionGraph = await FusionGraphComposer.ComposeAsync( + new[] + { + demoProject.Accounts.ToConfiguration(AccountsExtensionSdl) + }); + + // act + var result = await CreateQueryPlanAsync( + fusionGraph, + """ + query Test($number: Int!) { + testWithTwoArgumentsDifferingNullability(first: $number, second: $number) + } + """); + + // assert + var snapshot = new Snapshot(); + snapshot.Add(result.UserRequest, nameof(result.UserRequest)); + snapshot.Add(result.QueryPlan, nameof(result.QueryPlan)); + await snapshot.MatchMarkdownAsync(); + } + private static async Task<(DocumentNode UserRequest, Execution.Nodes.QueryPlan QueryPlan)> CreateQueryPlanAsync( Skimmed.SchemaDefinition fusionGraph, [StringSyntax("graphql")] string query) diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ConfigurationRewriterTests.Rewrite_HttpClient_Configuration.md b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ConfigurationRewriterTests.Rewrite_HttpClient_Configuration.md index ba5246c6d86..56c7615d8b5 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ConfigurationRewriterTests.Rewrite_HttpClient_Configuration.md +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ConfigurationRewriterTests.Rewrite_HttpClient_Configuration.md @@ -15,6 +15,7 @@ type Query { reviewById(id: ID!): Review @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) reviewOrAuthor: ReviewOrAuthor! @resolver(subgraph: "Reviews2", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews2", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int @variable(subgraph: "Accounts", name: "first", argument: "first") @variable(subgraph: "Accounts", name: "second", argument: "second") @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) @@ -111,6 +112,7 @@ type Query { reviewById(id: ID!): Review @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) reviewOrAuthor: ReviewOrAuthor! @resolver(subgraph: "Reviews2", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews2", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int @variable(subgraph: "Accounts", name: "first", argument: "first") @variable(subgraph: "Accounts", name: "second", argument: "second") @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_AutoCompose.graphql b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_AutoCompose.graphql index 00533ede9bd..d3812cd4faf 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_AutoCompose.graphql +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_AutoCompose.graphql @@ -32,6 +32,10 @@ type Query { @resolver(subgraph: "Reviews2", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews2", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) topProducts(first: Int!): [Product!]! @variable(subgraph: "Products", name: "first", argument: "first") @resolver(subgraph: "Products", select: "{ topProducts(first: $first) }", arguments: [ { name: "first", type: "Int!" } ]) diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Introspection.md b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Introspection.md index bd8d5dd1e34..b98d97f2e05 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Introspection.md +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Introspection.md @@ -377,6 +377,13 @@ "kind": "NON_NULL" } }, + { + "name": "testWithTwoArgumentsDifferingNullability", + "type": { + "name": "Int", + "kind": "SCALAR" + } + }, { "name": "topProducts", "type": { diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_AutoCompose.graphql b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_AutoCompose.graphql index 7d49fe8eda2..563c418ad6d 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_AutoCompose.graphql +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_AutoCompose.graphql @@ -22,6 +22,10 @@ type Query { @resolver(subgraph: "Reviews2", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews2", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) userById(id: ID!): User @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Hot_Reload.md b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Hot_Reload.md index 1b16c39ba37..1eeabba54af 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Hot_Reload.md +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Hot_Reload.md @@ -13,6 +13,9 @@ { "name": "node" }, + { + "name": "testWithTwoArgumentsDifferingNullability" + }, { "name": "userById" }, @@ -59,6 +62,9 @@ { "name": "reviews" }, + { + "name": "testWithTwoArgumentsDifferingNullability" + }, { "name": "userById" }, diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables.md b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables.md new file mode 100644 index 00000000000..a236ec823cd --- /dev/null +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables.md @@ -0,0 +1,57 @@ +# Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables + +## Result + +```json +{ + "data": { + "testWithTwoArgumentsDifferingNullability": 2 + } +} +``` + +## Request + +```graphql +query Test($number: Int!) { + testWithTwoArgumentsDifferingNullability(first: $number, second: $number) +} +``` + +## QueryPlan Hash + +```text +FF4DCF0AAD873BD22B2F69452CFF5036466A422C +``` + +## QueryPlan + +```json +{ + "document": "query Test($number: Int!) { testWithTwoArgumentsDifferingNullability(first: $number, second: $number) }", + "operation": "Test", + "rootNode": { + "type": "Sequence", + "nodes": [ + { + "type": "Resolve", + "subgraph": "Accounts", + "document": "query Test_1($number: Int!) { testWithTwoArgumentsDifferingNullability(first: $number, second: $number) }", + "selectionSetId": 0, + "forwardedVariables": [ + { + "variable": "number" + } + ] + }, + { + "type": "Compose", + "selectionSetIds": [ + 0 + ] + } + ] + } +} +``` + diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.AutoCompose.graphql b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.AutoCompose.graphql index aab4deb0ef7..51d8a8a37da 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.AutoCompose.graphql +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.AutoCompose.graphql @@ -32,6 +32,10 @@ type Query { @resolver(subgraph: "Reviews2", select: "{ reviewOrAuthor }") reviews: [Review!]! @resolver(subgraph: "Reviews2", select: "{ reviews }") + testWithTwoArgumentsDifferingNullability(first: Int! second: Int): Int + @variable(subgraph: "Accounts", name: "first", argument: "first") + @variable(subgraph: "Accounts", name: "second", argument: "second") + @resolver(subgraph: "Accounts", select: "{ testWithTwoArgumentsDifferingNullability(first: $first, second: $second) }", arguments: [ { name: "first", type: "Int!" }, { name: "second", type: "Int" } ]) topProducts(first: Int!): [Product!]! @variable(subgraph: "Products", name: "first", argument: "first") @resolver(subgraph: "Products", select: "{ topProducts(first: $first) }", arguments: [ { name: "first", type: "Int!" } ]) diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/RequestPlannerTests.Fragment_Deduplication_3.md b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/RequestPlannerTests.Fragment_Deduplication_3.md index 6a7577ac89a..b2fa9fbf497 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/RequestPlannerTests.Fragment_Deduplication_3.md +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/RequestPlannerTests.Fragment_Deduplication_3.md @@ -282,7 +282,7 @@ fragment zeroResults on ShopSearchResult { { "type": "Resolve", "subgraph": "Subgraph_1", - "document": "query searchQuery_1($filters: [FilterInput!], $sortOrder: ShopSearchSortOrder!, $query: String!, $searchQueryConfig: ShopSearchConfigInput) { shopSearch(query: $query, searchQueryConfig: $searchQueryConfig) { additionalQueryInfo { correctedQuery didYouMeanQuery lastProductSearchPass isRerankedQuery testGroup } brands { edges { node { id } } } productTypes { edges { node { id } } } redirectionUrl galaxusReferral { __typename portalUrl productCount products { id } } alternativeQuerySuggestions { queryString productCount productPreviewImageUrls __typename } blogPages { nodes { id } } communityItems(first: 3) { nodes { __typename ... on CommunityDiscussion { __typename databaseId __isNode: __typename id } ... on ProductQuestion { __typename databaseId __isNode: __typename id } ... on ProductReview { __typename databaseId __isNode: __typename id } } } products(first: 48, filters: $filters, sortOrder: $sortOrder) { edges { node { id __typename } cursor } productFilters { edges { node { __typename ... on RangeFilter { __typename identifier title min max step dataPoints { count value } topOutliersMerged unitId unitName tooltip { absoluteUrl text } } ... on CheckboxFilter { __typename identifier title commonOptions { count optionIdentifier title tooltip { absoluteUrl text } } pinnedOptions { count optionIdentifier title tooltip { absoluteUrl text } } tooltip { absoluteUrl text } } } } } totalCount pageInfo { hasNextPage endCursor } quickFilters { edges { node { disabled filterIdentifier optionIdentifier optionTitle filterTitle } } } } id } }", + "document": "query searchQuery_1($filters: [FilterInput!], $sortOrder: ShopSearchSortOrder!, $query: String!, $searchQueryConfig: ShopSearchConfigInput!) { shopSearch(query: $query, searchQueryConfig: $searchQueryConfig) { additionalQueryInfo { correctedQuery didYouMeanQuery lastProductSearchPass isRerankedQuery testGroup } brands { edges { node { id } } } productTypes { edges { node { id } } } redirectionUrl galaxusReferral { __typename portalUrl productCount products { id } } alternativeQuerySuggestions { queryString productCount productPreviewImageUrls __typename } blogPages { nodes { id } } communityItems(first: 3) { nodes { __typename ... on CommunityDiscussion { __typename databaseId __isNode: __typename id } ... on ProductQuestion { __typename databaseId __isNode: __typename id } ... on ProductReview { __typename databaseId __isNode: __typename id } } } products(first: 48, filters: $filters, sortOrder: $sortOrder) { edges { node { id __typename } cursor } productFilters { edges { node { __typename ... on RangeFilter { __typename identifier title min max step dataPoints { count value } topOutliersMerged unitId unitName tooltip { absoluteUrl text } } ... on CheckboxFilter { __typename identifier title commonOptions { count optionIdentifier title tooltip { absoluteUrl text } } pinnedOptions { count optionIdentifier title tooltip { absoluteUrl text } } tooltip { absoluteUrl text } } } } } totalCount pageInfo { hasNextPage endCursor } quickFilters { edges { node { disabled filterIdentifier optionIdentifier optionTitle filterTitle } } } } id } }", "selectionSetId": 0, "forwardedVariables": [ { diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/RequestPlannerTests.Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables.md b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/RequestPlannerTests.Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables.md new file mode 100644 index 00000000000..2be67d7cdea --- /dev/null +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/RequestPlannerTests.Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables.md @@ -0,0 +1,41 @@ +# Two_Arguments_Differing_Nullability_Does_Not_Duplicate_Forwarded_Variables + +## UserRequest + +```graphql +query Test($number: Int!) { + testWithTwoArgumentsDifferingNullability(first: $number, second: $number) +} +``` + +## QueryPlan + +```json +{ + "document": "query Test($number: Int!) { testWithTwoArgumentsDifferingNullability(first: $number, second: $number) }", + "operation": "Test", + "rootNode": { + "type": "Sequence", + "nodes": [ + { + "type": "Resolve", + "subgraph": "Accounts", + "document": "query Test_1($number: Int!) { testWithTwoArgumentsDifferingNullability(first: $number, second: $number) }", + "selectionSetId": 0, + "forwardedVariables": [ + { + "variable": "number" + } + ] + }, + { + "type": "Compose", + "selectionSetIds": [ + 0 + ] + } + ] + } +} +``` + diff --git a/src/HotChocolate/Fusion/test/Shared/Accounts/AccountQuery.cs b/src/HotChocolate/Fusion/test/Shared/Accounts/AccountQuery.cs index 640a496e00d..003f674077f 100644 --- a/src/HotChocolate/Fusion/test/Shared/Accounts/AccountQuery.cs +++ b/src/HotChocolate/Fusion/test/Shared/Accounts/AccountQuery.cs @@ -36,4 +36,7 @@ public IEnumerable GetUsersById( context.ReportError("SOME TOP LEVEL USER ERROR"); return null; } + + public int? GetTestWithTwoArgumentsDifferingNullability(int first, int? second) + => first + second; }