Skip to content

Comments

state_changes table: Replace JSONB columns with typed columns#476

Open
aditya1702 wants to merge 447 commits intomainfrom
statechanges-remove-jsonb
Open

state_changes table: Replace JSONB columns with typed columns#476
aditya1702 wants to merge 447 commits intomainfrom
statechanges-remove-jsonb

Conversation

@aditya1702
Copy link
Contributor

@aditya1702 aditya1702 commented Jan 30, 2026

What

Refactors the state_changes table schema to replace JSONB columns with explicit typed columns for better query performance, type safety and data integrity.

Note that the API still returns a response as key-value JSON with old and new keys. Only the storage design has changed

Why

The previous schema used JSONB columns (flags, key_value, signer_weights, thresholds, trustline_limit, offer_id) for storing
variable structured data. This approach had several drawbacks:

  1. Query Performance: JSONB fields require parsing and cannot leverage efficient PostgreSQL indexes for common query patterns
  2. Type Safety: JSONB allows arbitrary data structures, making schema validation at the application layer necessary
  3. Storage Efficiency: JSONB has higher storage overhead compared to native column types

This PR introduces explicit typed columns:

New Column(s) Replaces Type
signer_weight_old, signer_weight_new signer_weights JSONB SMALLINT
threshold_old, threshold_new thresholds JSONB SMALLINT
trustline_limit_old, trustline_limit_new trustline_limit JSONB TEXT
flags flags JSON array SMALLINT (bitmask)
claimable_balance_id, liquidity_pool_id, sponsored_data Extracted from key_value JSONB TEXT

Additionally:

  • Removes unused offer_id column
  • Retains key_value JSONB only for truly variable data (data entries, home domain) that cannot be flattened into a fixed schema

Known limitations

N/A

Issue that this PR addresses

Closes #477

aditya1702 and others added 30 commits January 14, 2026 17:35
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Split trustline operations from AccountTokensModel into dedicated model.
- TrustlineBalance struct (renamed from Trustline)
- TrustlineBalanceModelInterface with GetByAccount, BatchUpsert, BatchInsert
- Updated table name to account_trustline_balances
Split contract operations from AccountTokensModel into dedicated model.
- AccountContractTokensModelInterface with GetByAccount, BatchInsert
- Manages account_contracts junction table
- Renamed account_trustlines to account_trustline_balances
- Merged balance columns from separate migration into main table creation
- Removed redundant migration file (2026-01-13.0-add-trustline-balance-fields.sql)
Replace AccountTokens with:
- TrustlineBalance (TrustlineBalanceModelInterface)
- AccountContractTokens (AccountContractTokensModelInterface)
- account_trustline_balances.sql for TrustlineBalanceModel
- account_contract_tokens.sql for AccountContractTokensModel
- Removed combined migration file
- Replace accountTokensModel with trustlineBalanceModel and accountContractTokensModel
- Update trustlineBatch to use TrustlineBalance struct
- Update all model method calls to use new interfaces
- Replace AccountTokensReader with BalanceReader + AccountContractTokensModelInterface
- Create balanceReaderAdapter to wrap TrustlineBalanceModelInterface
- Update queries.resolvers.go to use new interface methods
- Update accountKeyInfo to use TrustlineBalance type
- Replace AccountTokensModel with TrustlineBalanceModel and AccountContractTokensModel
- Use NewBalanceReader adapter for GraphQL resolver injection
Pass TrustlineBalance and AccountContractTokens models to NewTokenIngestionService
@aditya1702 aditya1702 marked this pull request as ready for review February 1, 2026 17:13
@aditya1702 aditya1702 requested a review from Copilot February 1, 2026 17:17
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the state_changes table schema by replacing JSONB columns with explicit typed columns to improve query performance, type safety, and storage efficiency. The changes maintain backward compatibility at the API layer by formatting the typed columns back to JSON in GraphQL resolvers.

Changes:

  • Replaces JSONB/JSON columns (flags, signer_weights, thresholds, trustline_limit) with typed columns (SMALLINT for numeric values, TEXT for limits)
  • Extracts entity identifiers (claimable_balance_id, liquidity_pool_id, sponsored_data) from the key_value JSONB into dedicated columns
  • Implements bitmask encoding/decoding for flags instead of JSON arrays
  • Updates GraphQL resolvers to format typed values as JSON for backward compatibility
  • Removes the unused offer_id column
  • Fixes spelling of "authorized_to_maintain_liabilities" (was "authorized_to_maintain_liabilites" in several places)

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
internal/db/migrations/2025-06-10.4-create_indexer_table_state_changes.sql Defines new table schema with typed columns instead of JSONB
internal/indexer/types/types.go Adds bitmask constants/helpers, removes NullableJSON, updates StateChange struct with typed fields
internal/indexer/processors/state_change_builder.go Updates builder methods to accept typed values instead of JSONB maps
internal/indexer/processors/effects.go Updates effects processor to use typed columns and new sponsorship field structure
internal/indexer/processors/effects_horizon.go Fixes flag name spelling to "authorized_to_maintain_liabilities"
internal/indexer/processors/utils.go Adds getContractIDFromAssetString helper for sponsorship asset conversion
internal/indexer/processors/contracts/sac.go Fixes flag name spelling constant
internal/data/statechanges.go Updates batch insert/copy logic for new column structure
internal/data/query_utils.go Adds pgtypeInt2FromNullInt16 helper, removes jsonbFromSlice
internal/serve/graphql/schema/statechange.graphqls Updates GraphQL schema to use new field names (removes keyValue, adds specific fields)
internal/serve/graphql/resolvers/statechange.resolvers.go Implements resolvers that format typed values back to JSON for compatibility
internal/serve/graphql/resolvers/utils.go Updates column mapping for old/new paired fields
internal/serve/graphql/generated/generated.go Auto-generated code updates for schema changes
pkg/wbclient/types/types.go Removes unused StateChange type
pkg/wbclient/types/statechange.go Updates client types to match new GraphQL schema
pkg/wbclient/queries.go Updates GraphQL queries to use new field names
internal/integrationtests/data_validation_test.go Updates validation functions to use new typed fields
internal/serve/graphql/resolvers/statechange_resolvers_test.go Updates unit tests for typed field resolvers
internal/indexer/processors/effects_test.go Updates tests to use typed fields and bitmasks
internal/indexer/processors/contracts/sac_test.go Updates tests to use bitmask values for flags
internal/data/statechanges_test.go Updates test data generation with typed fields

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Base automatically changed from store-failed-ops to main February 4, 2026 14:42
@aditya1702 aditya1702 changed the title Replace JSONB columns from state changes table with typed columns state_changes table: Replace JSONB columns with typed columns Feb 5, 2026
aditya1702 and others added 5 commits February 20, 2026 11:52
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.

Remove JSONB columns in state changes table and replace with typed columns

1 participant