matrixorigin / matrixorigin/matrixone
[Bug]: DATA BRANCH misclassifies updates on DECIMAL256 primary keys as inserts
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 311
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 768
Description
### Is there an existing issue for the same bug?
- [x] I have checked the existing issues, including open and closed issues.
### Branch Name
main
### Commit ID
fc621e3616d229c7a29d0c80e73ed8eb1997459c
### Other Environment Information
- MatrixOne: locally built from the commit above (`8.0.30-MatrixOne-v1.3.0`)
- Verification date: 2026-09-10
### Actual Behavior
DATA BRANCH does not recognize an update to an existing row when the table has a Decimal256 primary key (`DECIMAL` precision 39 through 76).
After updating one existing row and inserting one new row on the branch, `DATA BRANCH DIFF ... OUTPUT SUMMARY` reports both rows as `INSERTED` and reports zero `UPDATED` rows:
```text
INSERTED 2
DELETED 0
UPDATED 0
```
Consequently, both `DATA BRANCH PICK ... WHEN CONFLICT ACCEPT` for the updated key and `DATA BRANCH MERGE ... WHEN CONFLICT ACCEPT` try to insert the already existing primary key and fail with error 1062. The target row remains unchanged and the final diff count remains 2.
The issue is specific to Decimal256 primary-key identity in the branch diff/update-pairing path:
- The same scenario with `DECIMAL(38,0)` primary key reports one INSERT and one UPDATE; PICK and MERGE complete and final diff is zero.
- The same scenario with BIGINT primary key also completes.
- INT primary key with a Decimal256 unique value column completes, so Decimal256 values outside the primary-key identity are not the cause.
- Ordinary Decimal256 primary-key INSERT, duplicate rejection, `ON DUPLICATE KEY UPDATE`, `REPLACE`, and prepared lookup work outside DATA BRANCH.
### Expected Behavior
The unchanged Decimal256 primary-key value should pair the before/after row versions as one UPDATE. `WHEN CONFLICT ACCEPT` should apply that update, merge the independent insert, and leave zero differences, matching the behavior for Decimal128 and integer primary keys.
### Steps to Reproduce
```sql
DROP DATABASE IF EXISTS data_branch_decimal256_pk;
CREATE DATABASE data_branch_decimal256_pk;
USE data_branch_decimal256_pk;
CREATE TABLE base (
k DECIMAL(40,0) PRIMARY KEY,
d INT,
v INT
);
INSERT INTO base VALUES
(9999999999999999999999999999999999999999,1,1);
DATA BRANCH CREATE TABLE branch_t FROM base;
-- Existing primary key is unchanged; only a non-key value changes.
UPDATE branch_t
SET v=11
WHERE k=9999999999999999999999999999999999999999;
INSERT INTO branch_t VALUES
(8888888888888888888888888888888888888888,2,22);
DATA BRANCH DIFF branch_t AGAINST base OUTPUT COUNT;
DATA BRANCH DIFF branch_t AGAINST base OUTPUT SUMMARY;
-- Both operations report duplicate entry for the existing key.
DATA BRANCH PICK branch_t INTO base
KEYS(9999999999999999999999999999999999999999)
WHEN CONFLICT ACCEPT;
DATA BRANCH MERGE branch_t INTO base WHEN CONFLICT ACCEPT;
SELECT * FROM base ORDER BY k;
DATA BRANCH DIFF branch_t AGAINST base OUTPUT COUNT;
```
Decimal128 boundary control:
```sql
CREATE TABLE d38 (
k DECIMAL(38,0) PRIMARY KEY,
d INT,
v INT
);
INSERT INTO d38 VALUES
(99999999999999999999999999999999999999,1,1);
DATA BRANCH CREATE TABLE d38_b FROM d38;
UPDATE d38_b SET v=11
WHERE k=99999999999999999999999999999999999999;
INSERT INTO d38_b VALUES
(88888888888888888888888888888888888888,2,22);
DATA BRANCH DIFF d38_b AGAINST d38 OUTPUT SUMMARY;
DATA BRANCH MERGE d38_b INTO d38 WHEN CONFLICT ACCEPT;
DATA BRANCH DIFF d38_b AGAINST d38 OUTPUT COUNT;
```
### Additional information
The hash-diff helpers and row decoder contain Decimal256 cases, but the existing Decimal256 unit fixture uses an integer as the hashmap key and Decimal256 only as a payload column. The end-to-end case where Decimal256 itself is the branch hashmap/primary key is not covered. Current behavior indicates that the before and after rows do not match under that key encoding, so the update replacement is emitted as a new insert.
Decimal256, Decimal128, BIGINT, and INT-plus-Decimal256 controls were reproduced three times on the same latest-main build. The Decimal256 result was consistently `INSERTED=2, UPDATED=0`, followed by duplicate-key failure in both PICK and MERGE.
Contributor guide
Assessment
This issue has not been assessed yet.