matrixorigin / matrixorigin/matrixone

[Bug]: non-strict and IGNORE numeric assignments still reject out-of-range values

Open
#27,340 1 comment 0 reactions 1 assignee Claimed by @jiangxinmeng1 View on GitHub
kind/bug needs-triage
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.