fix: regenerate reused array and block row IDs during bulk update#17017
Open
GermanJablo wants to merge 3 commits into
Open
fix: regenerate reused array and block row IDs during bulk update#17017GermanJablo wants to merge 3 commits into
GermanJablo wants to merge 3 commits into
Conversation
On relational databases each array and block row is stored in its own sub-table, where the row id is the primary key and must be unique across the entire table, not just within a single document. A bulk update applies the same submitted data, including client-generated row ids, to every matched document, so the first insert succeeds and subsequent documents fail with a duplicate-key ValidationError. Before applying the shared data to each document, collect the ids of that document's existing rows. Any incoming row whose id is not already part of the document is new to it, so its id is dropped and Payload generates a fresh unique one. Rows whose id already belongs to the document keep their id and are updated in place. Scoped to the bulk update operation, so single-document updates are unaffected, and applied recursively so nested arrays/blocks and localized arrays are covered.
Contributor
📦 esbuild Bundle Analysis for payloadThis analysis was generated by esbuild-bundle-analyzer. 🤖
Largest pathsThese visualization shows top 20 largest paths in the bundle.Meta file: packages/next/meta_index.json, Out file: esbuild/index.js
Meta file: packages/payload/meta_index.json, Out file: esbuild/index.js
Meta file: packages/payload/meta_shared.json, Out file: esbuild/exports/shared.js
Meta file: packages/richtext-lexical/meta_client.json, Out file: esbuild/exports/client_optimized/index.js
Meta file: packages/ui/meta_client.json, Out file: esbuild/exports/client_optimized/index.js
Meta file: packages/ui/meta_shared.json, Out file: esbuild/exports/shared_optimized/index.js
DetailsNext to the size is how much the size has increased or decreased compared with the base branch of this PR.
|
Replace the structural deep copy plus separate strip traversal with one schema-guided copy of the bulk update data that regenerates new array and block row ids inline. The existing document is still read once to know which ids already belong to it. Covers localized arrays, groups, tabs and nested blocks.
… update Detect locale-keyed group/tab values by configured locale codes instead of assuming the shape from the schema, so a localized group submitted in a single-locale bulk update no longer skips row-ID regeneration (and is no longer reshaped). Also traverse nameless groups so their nested arrays/blocks get fresh IDs. Adds a localized-group integration test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes #13783.
On relational databases (Postgres/SQLite) every array and block row lives in its own sub-table, and the row
idis the primary key, unique across the whole table (not just within one document). A bulk edit applies the same submitted data, including the row ids the admin UI generated, to every matched document. The first document inserts fine; the next one tries to insert a row with an id that already exists, causing a duplicate-keyValidationError(Postgres23505).How
In the bulk update operation, before applying the shared data to each matched document, we make a structural copy of the incoming data guided by the collection schema. During that single pass, for every array/block row we check the row
idagainst the set of ids already stored in that document:Why this is safe on both fronts:
This is scoped to the bulk update operation only. Single-document updates go through
updateByIDand are untouched, so there is no per-save cost on normal edits. The copy walks the schema recursively, so nested arrays/blocks, groups, and localized arrays are handled; the document's existing row ids are gathered withtraverseFields.Tests
Added integration tests in
test/array-update/int.spec.ts:Verified the new tests fail without the fix (duplicate-key errors on Postgres) and pass with it on both Postgres and MongoDB.