matrixorigin / matrixorigin/matrixone
[Bug]: non-strict and IGNORE numeric assignments still reject out-of-range values
- 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 searched open and closed issues and fix PRs.
Related but not a duplicate:
- #25200 covers CHAR/VARCHAR width assignment behavior. This report covers numeric range assignment for unsigned integer and DECIMAL columns.
- #27339 covers missing string-truncation warnings after truncation already succeeds.
Searches included `numeric overflow sql_mode`, `non-strict numeric out of range`, `decimal overflow sql_mode`, `tinyint overflow warning`, and `unsigned overflow sql_mode`.
### Branch Name
main
### Commit ID
`493ab8a9585576b76508d054fef58ccb55c206c5`
### Other Environment Information
- MatrixOne was built from the exact current `origin/main` commit above.
- MySQL control: 8.0.46.
- MySQL Connector/J: 8.0.33 and 26.7.0.
- Real server PreparedStatements were forced with `useServerPrepStmts=true`, `cachePrepStmts=false`, and `emulateUnsupportedPstmts=false`.
### Actual Behavior
For numeric assignments outside the target column range, MatrixOne always returns an error, regardless of `sql_mode` or `IGNORE`:
- strict INSERT / UPDATE: rejected;
- strict INSERT IGNORE / UPDATE IGNORE: rejected;
- non-strict INSERT / UPDATE: rejected;
- non-strict INSERT IGNORE / UPDATE IGNORE: rejected.
The matrix used:
```sql
CREATE TABLE t(
id INT PRIMARY KEY,
u TINYINT UNSIGNED,
d DECIMAL(5,2)
);
```
and server PreparedStatements that assign `u=300` and `d=1234.56`.
The behavior reproduced 3/3 with Connector/J 8.0.33 and 3/3 with 26.7.0.
MySQL 8.0.46 control:
- strict regular INSERT / UPDATE rejects the assignment;
- strict `IGNORE`, non-strict regular, and non-strict `IGNORE` all succeed;
- accepted rows contain the column boundary values `u=255` and `d=999.99`.
The MySQL result reproduced 3/3 with both Connector/J versions.
### Expected Behavior
Match MySQL numeric assignment policy:
- strict regular DML rejects an out-of-range numeric value;
- non-strict DML adjusts the value to the nearest column boundary and succeeds;
- `INSERT IGNORE` and `UPDATE IGNORE` downgrade the strict assignment error, adjust to the boundary, and succeed;
- adjusted assignments should also produce the corresponding warning diagnostics.
### Steps to Reproduce
Prepare either of these as a real server PreparedStatement:
```sql
INSERT INTO t VALUES (?, ?, ?);
UPDATE t SET u=?, d=? WHERE id=?;
```
Bind the out-of-range values above and execute under each session mode:
```sql
SET SESSION sql_mode='STRICT_TRANS_TABLES';
SET SESSION sql_mode='';
```
Repeat with `INSERT IGNORE` and `UPDATE IGNORE`.
### Root Cause
The DML planner routes assignments through `cast_assign` and `cast_ignore`, but their execution-mode distinctions currently affect the CHAR/VARCHAR width branch. Numeric conversion helpers still return range errors unconditionally; `castModeAssignmentIgnore` and non-strict session mode do not select a boundary-adjusting numeric assignment path.
### Consistency and Recovery Checks
- Latest official `main`: reproduced 3/3 per Connector/J version.
- MySQL control: stable 3/3 per Connector/J version.
- Rejected INSERT left no row.
- Rejected UPDATE preserved the exact original row.
- The same server PreparedStatement accepted a valid assignment immediately after each error.
- Fresh connections remained usable and temporary objects were removed.
Contributor guide
Assessment
This issue has not been assessed yet.