Skip to content

[Postgres] Skip redundant current_data copies for REPLICA IDENTITY FULL#655

Open
joshuabrink wants to merge 4 commits into
mainfrom
feat/per-table-store-current-data
Open

[Postgres] Skip redundant current_data copies for REPLICA IDENTITY FULL#655
joshuabrink wants to merge 4 commits into
mainfrom
feat/per-table-store-current-data

Conversation

@joshuabrink
Copy link
Copy Markdown
Contributor

Re-implements #459 (which resolves #398)

Tables with REPLICA IDENTITY FULL always send the complete row on every change, so PowerSync's per-row copy in current_data is redundant for them. This makes store_current_data a per-table flag rather than a global one, skipping the copy (and the TOAST-merge read) for FULL tables while keeping it for every other replica identity.

What changed

The source reports a source-agnostic sendsCompleteRows on the entity descriptor (true only for FULL in Postgres), and resolveStoreCurrentData in service-core derives the stored flag from it: reported true = no copy, reported false = keep a copy, unreported = preserve the persisted value. Keeping the resolution in core means the storage backends don't each re-derive the three-state logic.

The flag is resolved during table resolution and re-evaluated on every pgoutput Relation message, so a mid-stream ALTER TABLE ... REPLICA IDENTITY is picked up without a re-snapshot. Reverting FULL to DEFAULT correctly falls back to a targeted resnapshot for any row that can no longer be completed from storage.

Compatibility

Backward compatible, the column defaults to NULL (treated as true), and existing FULL tables pick up the optimization on their next DML or ALTER. No re-snapshot required on upgrade.

Testing

E2E tests in module-postgres cover both ALTER directions (including TOAST recovery), and module-mongodb-storage covers the storage-layer flag for v1 and v3.

AI Usage

This PR was AI-assisted (Claude Code), manually directed, reviewed, and tested.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 29, 2026

🦋 Changeset detected

Latest commit: 65ca4e7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@powersync/service-core Minor
@powersync/service-module-mongodb-storage Minor
@powersync/service-module-postgres-storage Minor
@powersync/service-module-postgres Minor
@powersync/service-module-core Patch
@powersync/service-module-mongodb Patch
@powersync/service-module-mssql Patch
@powersync/service-module-mysql Patch
@powersync/service-image Minor
test-client Patch
@powersync/service-schema Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown
Contributor

@rkistner rkistner left a comment

Choose a reason for hiding this comment

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

Before I did too far into the details - is there a way to do this that would avoid persisting the store_current_data flag on the SourceTable?

If that's not feasible, we should look into a more generic way of storing db-specific metadata on the SourceTable - I know we have another similar requirement for persisting MSSQL change capture instances - cc @Rentacookie.

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.

[Postgres] Avoid storing copy of replicated rows with REPLICA IDENTITY FULL

2 participants