matrixorigin / matrixorigin/matrixone
[Compatibility]: SUBSTRING, LEFT, and RIGHT do not narrow bounded VARCHAR result metadata
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 311
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 768
Description
### Problem
`SUBSTRING`, `SUBSTR`, `MID`, `LEFT`, and `RIGHT` do not narrow the declared width of a bounded character result when the requested length is a constant. Values are sliced correctly, but View and CTAS schemas retain the full source width.
### Reproduction
```sql
drop database if exists substring_width_repro;
create database substring_width_repro;
use substring_width_repro;
create table src(id int primary key, wide varchar(5000));
insert into src values (1,repeat('Aé中',1000)),(2,'searchable'),(3,null);
create view v as
select id,
substring(wide,1,100) sub100,
substr(wide,2,3) sub3,
mid(wide,2,3) mid3,
left(wide,3) left3,
right(wide,3) right3
from src;
create table ctas as select * from v;
select table_name,column_name,column_type,character_maximum_length
from information_schema.columns
where table_schema=database() and table_name in ('v','ctas')
order by table_name,ordinal_position;
```
### MatrixOne result
All ten derived View/CTAS columns are declared as `VARCHAR(5000)`, regardless of whether the explicit result limit is 100 or 3 characters.
The returned values are correctly limited, including the multibyte input: `SUBSTRING(wide,1,100)` contains exactly 100 characters, `SUBSTR(wide,2,3)` / `MID(wide,2,3)` return `é中A`, and `LEFT` / `RIGHT` each return at most 3 characters.
### MySQL 8.0.45 result
- `SUBSTRING(wide,1,100)` is `VARCHAR(100)`;
- `SUBSTR(wide,2,3)`, `MID(wide,2,3)`, `LEFT(wide,3)`, and `RIGHT(wide,3)` are `VARCHAR(3)`;
- View and CTAS expose the same bounded metadata.
### Controls and scope
- `SUBSTRING(VARBINARY(128),1,2)` is `VARBINARY(2)` in both systems, so the issue is confined to the character-string overload in this reproduction.
- NULL, short input, long multibyte input, View, CTAS, and secondary indexes over the derived columns are covered.
- Three independent executions produced identical results on each database.
Incorrect declared width affects schema introspection, generated client models, storage sizing, and downstream DDL based on CTAS/View metadata even though the scalar bytes are correct.
### Code location
The affected character overloads in `pkg/sql/plan/function/list_builtIn.go` derive the return type only from argument 0 via `derivedStringReturnType(parameters, 0, ...)`; the constant length argument does not participate in the bound. Binary-string planning already produces the expected narrowed width and is a useful control.
### Environment
- MatrixOne: official `main` commit `0c3a04f390adaf6281fd592a49778ea5b1155e67`
- MySQL control: 8.0.45
- Local single-node MatrixOne deployment
Contributor guide
Assessment
This issue has not been assessed yet.