Skip to content

[Bug]: DATA BRANCH cannot apply primary-key updates with ON UPDATE CASCADE #28026

Description

@gouhongshen

Is there an existing issue for the same bug?

  • I searched open and closed DATA BRANCH issues; none covers primary-key update provenance with foreign-key ON UPDATE actions.

Branch Name

main

Commit ID

ad143902644719e65fa703df6397a011dc7d7dfa (PR #27996 head reviewed on 2026-09-02)

Other Environment Information

  • Local embedded single-CN / single-TN / single-Log test cluster
  • Parent table with an integer primary key and a referencing child foreign key using ON UPDATE CASCADE

Actual Behavior

A branch-side primary-key change is emitted as an independent delete of the old key plus an insert of the new key. DATA BRANCH MERGE and DATA BRANCH PICK replay that as DELETE/INSERT, so the parent-row delete fails with the foreign-key constraint error. An ordinary UPDATE on the same parent key succeeds and cascades to the child.

Expected Behavior

When a source update changes a referenced primary key, Data Branch apply should preserve it as one native destination UPDATE, allowing declared ON UPDATE CASCADE actions to run.

Steps to Reproduce

create database branch_pk_cascade;
use branch_pk_cascade;
create table parent_t (id int primary key, payload varchar(32));
create table child_t (id int primary key, parent_id int,
  constraint fk_child_parent foreign key (parent_id) references parent_t(id) on update cascade);
insert into parent_t values (2, 'two');
insert into child_t values (1, 2);

data branch create table merge_src from parent_t;
update merge_src set id = 3 where id = 2;
data branch merge merge_src into parent_t when conflict accept;

-- Control: update parent_t set id = 3 where id = 2; cascades child_t.parent_id.

The equivalent PICK setup (source and destination branches, keys(2)) fails for the same reason.

Root Cause and Scope

multi_update deletes the old row while writing the replacement without a durable operation identity. databranchutils.CollectChanges therefore exposes the old row ID/key as a tombstone and the replacement row ID/key as data. buildHashmapForTable and findDeleteAndUpdateBat correlate the two only by primary-key value; once the key changes, there is no safe association.

Matching rows by commit timestamp or iteration order would conflate independent delete/insert operations with updates and could trigger unintended cascades, so it is not a safe fix. This needs an explicit old-to-new update provenance link through the change stream, followed by native UPDATE apply and MERGE/PICK regressions for cascade, non-cascade rejection, and atomicity.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

ai-easyAI直接干,人扫一眼就行deferredkind/bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions