Skip to content

fix(store): cast entity id to bytea in FindPossibleDeletionsQuery UNION - #6709

Open
SnowingFox wants to merge 1 commit into
graphprotocol:masterfrom
SnowingFox:fix/possible-deletions-union-id-cast
Open

fix(store): cast entity id to bytea in FindPossibleDeletionsQuery UNION#6709
SnowingFox wants to merge 1 commit into
graphprotocol:masterfrom
SnowingFox:fix/possible-deletions-union-id-cast

Conversation

@SnowingFox

Copy link
Copy Markdown

Summary

Fixes #6695 - entityChangesInBlock fails with UNION types bytea and text cannot be matched on deployments whose entity types use different ID types (some Bytes, some String/ID).

Root cause

FindPossibleDeletionsQuery (store/postgres/src/relational_queries.rs) builds one UNION ALL statement per deployment with one branch per entity table:

select 'Transfer' as entity, 0 as causality_region, e.id from sgdN.transfer e where ...
union all
select 'Account'  as entity, 0 as causality_region, e.id from sgdN.account  e where ...

e.id is selected raw, so its column type follows the entity: text for ID/String ids and bytea for Bytes ids (and int8 for Int8 ids). UNION ALL requires a common type per column position, so any schema mixing text and bytea ids is rejected by Postgres before a single row is read.

This is the same class of bug that FindRangeQuery already guards against - its walk_ast selects the id through a per-type cast (id::bytea / id / id::text::bytea via the match pk_column.column_type block). FindPossibleDeletionsQuery never got the same treatment.

The fix

Mirror FindRangeQuery: select the primary-key column through a per-type cast so every branch of the UNION ALL produces a bytea id column:

ID type Column SQL
String/ID e.id::bytea
Bytes e.id
Int8 e.id::text::bytea
other e.id::bytea

Only the deletions query is affected. FindChangesQuery selects to_jsonb(e.*) (always jsonb), which is why it never trips on this error.

Test

Adds find_possible_deletions_query_id_type_casting to store/postgres/src/relational/query_tests.rs (alongside the existing find_range_query_id_type_casting). It builds layouts with String, Bytes, and Int8 ids, renders FindPossibleDeletionsQuery for each id type individually and combined, and asserts the id column carries the correct cast so the UNION ALL branches share a common bytea type. On the pre-fix code the test fails (no cast emitted); on the fixed code it passes.

Impact

Read-only query path (entityChangesInBlock -> SubgraphStore::entity_changes_in_block -> DeploymentStore::get_changes -> Layout::find_changes). Indexing and query serving are unaffected.

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

Successfully merging this pull request may close these issues.

entityChangesInBlock fails with "UNION types bytea and text cannot be matched" on schemas mixing Bytes and String IDs

1 participant