[Bug] Query entities implementing same interface: Failed to get entities from store: operator does not exist: text = bytea

Open
#5,443 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
25/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
graphql, postgresql, rust

Research direction

Start by reproducing the three GraphQL queries from the issue against the reported schema and inspect the generated PostgreSQL query and type bindings in the error log. Trace interface-reference traversal through the store query path. Done means the two nested queries return the expected interface entities without the text = bytea error, with coverage for this schema shape.

Written by the indexing model from the issue text.

Description

bug Stale
Bug report

Current graphql schema looks like this

interface IConfigForProcesses {
    id: ID!
}

type MajorityVotingConfig implements IConfigForProcesses @entity {
    id: ID!

    # flat fields with values
}

type MultiprocessConfig implements IConfigForProcesses @entity {
    id: ID!
    
    # flat fields with values
}

type NominationConfig implements IConfigForProcesses @entity {
    id: ID!

    # flat fields with values
}

type SignatureCollectionConfig implements IConfigForProcesses @entity {
    id: ID!

    # flat fields with values
}

type PetitionCreationConfig implements IConfigForProcesses @entity {
    id: ID!

    # flat fields with values
}

type ElectionActionConfig implements IConfigForProcesses @entity {
    id: ID!

    # flat fields with values
}

type ProcessSpawner implements IAddressable & ITimestamp @entity(immutable: true) {
    id: Bytes!

    staticConfig: IConfigForProcesses

    # flat fields with values
}

type Structure @entity {
    id: Bytes!

    processes: [StructureProcessSpawner!]! @derivedFrom(field: "structure")
}

type StructureProcessSpawner @entity {
    id: Bytes!
    title: String!
    structure: Structure!
    processSpawner: ProcessSpawner!
    timestamp: BigInt!
}

with this kind of structure I've tried three queries

query WORKING_PROCESS_SPAWNERS {
      processSpawners {
        staticConfig {
          id
        }
      }
}
query ERROR_INTERMEDIATE_OBJ_STRUCTURE_PROCESS {
  structureProcessSpawners {
    processSpawner {
      staticConfig {
        id
      }
    }
  }
}
query QUERY_RESULTING_IN_ERROR {
  structures {
    processes {
      processSpawner {
        staticConfig {
          id
        }
      }
    }
  }
}

First query return correct data, but the last two result in error, bubbling up from Postgres.

It does not error when ProcessSpawner.staticConfig is Bytes instead of interface reference, but it defeats the point of using interfaces.

Do you have any ideas why it can be occurring?

From what I've tried already:

  • changing id from Bytes to ID and back
  • changing running graph-node version from v0.35.0 to v0.34.1
  • updating ts packages to the latest versions (@graphprotocol/graph-cli to 0.73.0, 0.35.1)
  • cherry-picking starting from the last working commit didn't show any meaningful changes (please contact for more info, cannot share full code publicly)
Tested environments

Local setup:

  • OS: mac os
  • graph-node in docker container: v0.35.0 and v0.34.1

Remote setup:

  • OS: Debian 12
  • graph-node in docker container: v0.35.0
Relevant log output
{
  "errors": [
    {
      "message": "Failed to get entities from store: operator does not exist: text = bytea, query = /* controller='filter',application='sgd11',route='d701c3827c55de44-6dc8c4ef99f8cc6a',action='812812' */\nwith matches as (select c.* from unnest($1) as q(id)\n cross join lateral (select 'MajorityVotingConfig' as entity, c.id, c.vid, p.id::text as g$parent_id\n/* child_type_d */ from rows from (unnest($2), unnest($3)) as p(id, child_id), \"sgd11\".\"majority_voting_config\" c where c.block_range @> $4 and q.id = p.id and c.id = any($5) and c.id = p.child_id\nunion all\nselect 'MultiprocessConfig' as entity, c.id, c.vid, p.id::text as g$parent_id\n/* child_type_d */ from rows from (unnest($6), unnest($7)) as p(id, child_id), \"sgd11\".\"multiprocess_config\" c where c.block_range @> $8 and q.id = p.id and c.id = any($9) and c.id = p.child_id\nunion all\nselect 'NominationConfig' as entity, c.id, c.vid, p.id::text as g$parent_id\n/* child_type_d */ from rows from (unnest($10), unnest($11)) as p(id, child_id), \"sgd11\".\"nomination_config\" c where c.block_range @> $12 and q.id = p.id and c.id = any($13) and c.id = p.child_id\nunion all\nselect 'SignatureCollectionConfig' as entity, c.id, c.vid, p.id::text as g$parent_id\n/* child_type_d */ from rows from (unnest($14), unnest($15)) as p(id, child_id), \"sgd11\".\"signature_collection_config\" c where c.block_range @> $16 and q.id = p.id and c.id = any($17) and c.id = p.child_id\nunion all\nselect 'PetitionCreationConfig' as entity, c.id, c.vid, p.id::text as g$parent_id\n/* child_type_d */ from rows from (unnest($18), unnest($19)) as p(id, child_id), \"sgd11\".\"petition_creation_config\" c where c.block_range @> $20 and q.id = p.id and c.id = any($21) and c.id = p.child_id\nunion all\nselect 'ElectionActionConfig' as entity, c.id, c.vid, p.id::text as g$parent_id\n/* child_type_d */ from rows from (unnest($22), unnest($23)) as p(id, child_id), \"sgd11\".\"election_action_config\" c where c.block_range @> $24 and q.id = p.id and c.id = any($25) and c.id = p.child_id\n\n limit 100) c)\nselect m.*, to_jsonb(\"c\".*)|| jsonb_build_object('g$parent_id', m.g$parent_id) as data\n  from \"sgd11\".\"majority_voting_config\" c, matches m\n where c.vid = m.vid and m.entity = 'MajorityVotingConfig'\nunion all\nselect m.*, to_jsonb(\"c\".*)|| jsonb_build_object('g$parent_id', m.g$parent_id) as data\n  from \"sgd11\".\"multiprocess_config\" c, matches m\n where c.vid = m.vid and m.entity = 'MultiprocessConfig'\nunion all\nselect m.*, to_jsonb(\"c\".*)|| jsonb_build_object('g$parent_id', m.g$parent_id) as data\n  from \"sgd11\".\"nomination_config\" c, matches m\n where c.vid = m.vid and m.entity = 'NominationConfig'\nunion all\nselect m.*, to_jsonb(\"c\".*)|| jsonb_build_object('g$parent_id', m.g$parent_id) as data\n  from \"sgd11\".\"signature_collection_config\" c, matches m\n where c.vid = m.vid and m.entity = 'SignatureCollectionConfig'\nunion all\nselect m.*, to_jsonb(\"c\".*)|| jsonb_build_object('g$parent_id', m.g$parent_id) as data\n  from \"sgd11\".\"petition_creation_config\" c, matches m\n where c.vid = m.vid and m.entity = 'PetitionCreationConfig'\nunion all\nselect m.*, to_jsonb(\"c\".*)|| jsonb_build_object('g$parent_id', m.g$parent_id) as data\n  from \"sgd11\".\"election_action_config\" c, matches m\n where c.vid = m.vid and m.entity = 'ElectionActionConfig'\n  -- binds: [[], [], [], 812812, [], [], [], 812812, [], [], [], 812812, [], [], [], 812812, [], [], [], 812812, [], [], [], 812812, []]"
    }
  ]
}
IPFS hash

No response

Subgraph name or link to explorer

No response

Some information to help us out
  • Tick this box if this bug is caused by a regression found in the latest release.
  • Tick this box if this bug is specific to the hosted service.
  • I have searched the issue tracker to make sure this issue is not a duplicate.
OS information

Other (please specify in your bug report)

Dominant language
Rust
Stars
3.2k
Forks
1.1k
Avg merge
4d 1h
Merged PRs (30d)
1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from graphprotocol/graph-node

All issues in graphprotocol/graph-node

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.