Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect results when querying 1 type and 2 interfaces using different selection sets #3636

Open
montykamath-reddit opened this issue Apr 4, 2025 · 0 comments

Comments

@montykamath-reddit
Copy link

Describe the bug

In a system with: 1 type (CompactPost) and 2 interfaces (PostInterface1, PostInterface2), when requesting different selections sets from the types/interfaces, the output differs depending on which selection set requests all fields or fewer fields.

To Reproduce

A repository with a reproduction is here:
https://github.com/montykamath/gqlgen-bug-repro-1

  1. Clone the repository.
  2. Start the gql server by cd b; make run
  3. Open the router sandbox url that shows in the terminal like http://127.0.0.1:8071/
  4. Run the BadQuery.graphql or GoodQuery.graphql to see the differences in output
  5. Place a breakpoint in 99designs/[email protected]/graphql/handler/transport/util.go in writeJson to see the output before it is written. It has duplicate keys for awards before the response is written. After the response is written it takes the last of those duplicate keys.

Expected behavior

Expect the output to be a deep merge of the selection sets into a single response list, rather than allowing the JSON writer to select the last of the duplicate keys.

The working query

# This query fetches posts and their associated awards.
# It includes inline fragments to handle different post types/interfaces
# It only works because it requests the same fields in all fragments for awards
query GoodQuery {
  posts {
    __typename
    awards {
      __typename
      id
      name
    }
    ... on CompactPost {
      __typename
      id
      awards {
        __typename
        id
        name
      }
    }
    ... on PostInterface2 {
      __typename
      id
      awards {
        __typename
        name
        id
      }
    }
  }  
}

Working query produces this output

{
  "data": {
    "posts": [
      {
        "__typename": "CompactPost",
        "awards": [
          {
            "__typename": "Award",
            "id": "1",
            "name": "One"
          },
          {
            "__typename": "Award",
            "id": "2",
            "name": "Two"
          },
          {
            "__typename": "Award",
            "id": "3",
            "name": "Three"
          }
        ],
        "id": "1"
      }
    ]
  }
}

The failing query

# This query is identical to the good query except that it comments out the name and id from the PostInterface2 fragment for Award
# This query fetches posts and their associated awards.
# It includes inline fragments to handle different post types/interfaces
# It does not work because it requests different fields in some of the fragments for awards
query BadQuery {
  posts {
    __typename
    awards {
      __typename
      id
      name
    }
    ... on CompactPost {
      __typename
      id
      awards {
        __typename
        id
        name
      }
    }
    ... on PostInterface2 {
      __typename
      id
      awards {
        __typename
        # name
        # id
      }
    }
  }  
}

Failing query produces this output

{
  "data": {
    "posts": [
      {
        "__typename": "CompactPost",
        "awards": [
          {
            "__typename": "Award"
          },
          {
            "__typename": "Award"
          },
          {
            "__typename": "Award"
          }
        ],
        "id": "1"
      }
    ]
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant