matrixorigin / matrixorigin/matrixone
[Compatibility]: BLOB and TEXT columns do not enforce MySQL family byte limits
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 311
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 768
Description
## 问题
在 `STRICT_TRANS_TABLES` 下,MO 接受并持久化超出 MySQL 类型上限的 `TINYBLOB`、`TEXT` 与 `BLOB` 值。相同 SQL 在 MySQL 8.3 返回 `ERROR 1406 (22001): Data too long for column`,且不写入该行。
这会让声明为这些类型的列失去 MySQL 语义中的容量约束;同一数据在 MO 可写入、迁移到 MySQL 时会失败。
## 环境
* MatrixOne `main`:`7013fbbd6e152ba31da2d3dbba7012ac7f8b8462`,新启动的 2 CN 环境。
* MO `@@sql_mode` 包含 `STRICT_TRANS_TABLES`。
* 对照:MySQL 8.3,`@@sql_mode` 包含 `STRICT_TRANS_TABLES`。
## 最小复现
```sql
create table tinyblob_direct(id int primary key, v tinyblob);
insert into tinyblob_direct values(1, repeat('a', 256)); -- TINYBLOB 上限为 255 bytes
select id, length(v) from tinyblob_direct;
create table text_direct(id int primary key, v text);
insert into text_direct values(1, repeat('b', 65536)); -- TEXT 上限为 65535 bytes
select id, length(v) from text_direct;
create table blob_direct(id int primary key, v blob);
insert into blob_direct values(1, repeat('c', 65536)); -- BLOB 上限为 65535 bytes
select id, length(v) from blob_direct;
```
MO 实际结果:
```
1 256
1 65536
1 65536
```
MySQL 8.3 对三条 INSERT 分别返回:
```
ERROR 1406 (22001): Data too long for column 'v' at row 1
```
## 覆盖范围
在同一 MO 版本中,下列写入路径均保存了这三个超界值:
* 直接 INSERT:每种类型独立重复 3 次;
* `UPDATE`;
* `INSERT ... ON DUPLICATE KEY UPDATE`;
* SQL `PREPARE` / `EXECUTE`;
* 源表写入后 `CREATE TABLE ... AS SELECT`。
MO 的 `information_schema.columns` 同时将 `TINYBLOB` 暴露为 `BLOB(0)`,普通 `BLOB` 也为 `BLOB(0)`;对照 MySQL 分别是 `tinyblob` / `blob`,`CHARACTER_MAXIMUM_LENGTH` 都是 65535 或对应的 255。
## 代码定位
`pkg/sql/plan/build_util.go` 中 `MYSQL_TYPE_BLOB` 无条件映射为不带宽度的 `T_blob`,没有保留 `tinyblob/blob/mediumblob/longblob` 家族容量;而 `pkg/sql/plan/function/func_cast.go` 的 `castResultExceedsByteWidth` 对 `T_blob` 直接返回 false,普通 `T_text` 也被豁免。相比之下,TEXT 家族已有 `tinytext` / `mediumtext` / `longtext` 的宽度映射和 `TINYTEXT` 长度检查。
## 预期
MO 应保留并在赋值路径按字节执行 MySQL BLOB/TEXT 家族容量:`TINYBLOB/TINYTEXT` 255、`BLOB/TEXT` 65535、`MEDIUM*` 16777215、`LONG*` 4294967295(受 MO 单值上限约束时应清晰报错)。在严格模式,超界 DML 应拒绝且不持久化;非严格模式的截断/告警行为应与已支持的字符串赋值语义一致。
Contributor guide
Assessment
This issue has not been assessed yet.