matrixorigin / matrixorigin/matrixone
[Bug]: BITMAP_CONSTRUCT_AGG accepts out-of-range positions and truncates UINT64 values
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 311
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 768
Description
## Description
`BITMAP_CONSTRUCT_AGG` accepts values outside its documented bit-position domain and silently narrows its `UINT64` SQL input to `uint32`. Values separated by `2^32` therefore alias to the same bit and cardinality is lost without an error.
The MatrixOne Bitmap documentation defines the argument as a bit position returned by `BITMAP_BIT_POSITION`, whose range is 0 through 32767.
## Environment
- MatrixOne: latest official `main`, commit `07fdd4ae0f80f287b93fc4b525fd296d5617abc7`
- Deployment: local standalone launch (isolated Log/TN/CN ports and data directory)
- Function contract: https://docs.matrixorigin.cn/en/dev/MatrixOne/Reference/Functions-and-Operators/Aggregate-Functions/bitmap/
## Reproduction
```sql
create table positions(v bigint unsigned);
insert into positions values
(0),(1),(32767),(32768),(4294967295),(4294967296),(4294967297);
select bitmap_count(bitmap_construct_agg(v)) direct_cardinality,
count(distinct v) source_cardinality
from positions;
create table collision(v bigint unsigned);
insert into collision values (0),(4294967296),(1),(4294967297);
select bitmap_count(bitmap_construct_agg(v)) direct_cardinality,
count(distinct v) source_cardinality
from collision;
```
## Actual behavior
```text
seven-value input: direct_cardinality=5, source_cardinality=7
collision input: direct_cardinality=2, source_cardinality=4
```
`32768` is also accepted even though it is outside the documented bit-position range. The results reproduced identically in 3/3 fresh-table runs.
## Expected behavior
Out-of-range bit positions must be rejected rather than accepted with silent aliasing. At minimum, values that cannot be represented by the internal bitmap element type must never be truncated to another valid bit.
## Control
Using the documented composition is correct:
```sql
bitmap_count(bitmap_construct_agg(bitmap_bit_position(v)))
```
returns 3, matching `COUNT(DISTINCT bitmap_bit_position(v))` for the seven-value fixture.
## Code-path analysis
The SQL overload accepts `types.T_uint64`. In `pkg/sql/colexec/aggexec/bitmap2.go`, the construct aggregate passes the argument into a bitmap state whose `add` method accepts `uint32`. The conversion silently discards the high 32 bits, so no domain or overflow error reaches SQL.
## Suggested regression coverage
- boundary positions `0`, `32767`, `32768`;
- `2^32-1`, `2^32`, `2^32+1`, and `UINT64_MAX`;
- direct and prepared input, grouped/partial/final/spill paths;
- documented `BITMAP_BIT_POSITION` + bucket composition as a control.
## Duplicate search
Open and closed issues were searched for bitmap input range, uint64/uint32 narrowing, overflow, wraparound, and bitmap cardinality; no matching report was found.
Contributor guide
Assessment
This issue has not been assessed yet.