matrixorigin / matrixorigin/matrixone

[Bug]: CRC32(JSON) hashes internal binary encoding instead of JSON text

Open
#28,910 0 comments 0 reactions 1 assignee Claimed by @VioletQwQ-0 View on GitHub
area/compatibility kind/bug severity/s1
Dominant language
Go
Stars
1.9k
Forks
311
Avg merge
1d 3h
Merged PRs (30d)
768

Description

### Problem

`CRC32(JSON)` hashes MatrixOne's internal binary JSON representation instead of the SQL text representation of the JSON value. The returned checksum therefore differs from both `CRC32(CAST(json_value AS CHAR))` in MatrixOne and `CRC32(json_value)` in MySQL.

This is a result-correctness problem: the statement succeeds and returns a plausible unsigned checksum, but that checksum is for different bytes than the SQL value exposed by the JSON expression.

### Reproduction

```sql
CREATE DATABASE crc32_json_repro;
USE crc32_json_repro;

CREATE TABLE t(id INT PRIMARY KEY, js JSON);
INSERT INTO t VALUES
(1, '{"b":2,"a":1}'),
(2, 'null'),
(3, NULL),
(4, '[1,true,"x"]'),
(5, '1');

SELECT id,
CAST(js AS CHAR) AS json_text,
CRC32(js) AS direct_crc,
CRC32(CAST(js AS CHAR)) AS text_crc
FROM t ORDER BY id;
```

### MatrixOne result

```text
id JSON text CRC32(js) CRC32(CAST(js AS CHAR))
1 {"a": 1, "b": 2} 581034396 733321759
2 null 1387456365 634125391
3 SQL NULL NULL NULL
4 [1, true, "x"] 3799633758 3071756745
5 1 2248188523 2212294583
```

### Expected result / MySQL 8.0.45 result

The direct JSON expression and explicit character conversion identify the same SQL JSON value and return the same checksum:

```text
id CRC32(js) CRC32(CAST(js AS CHAR))
1 733321759 733321759
2 634125391 634125391
3 NULL NULL
4 3071756745 3071756745
5 2212294583 2212294583
```

### Scope and controls

- Object, array, numeric scalar, JSON null, and SQL NULL were covered.
- Ordinary text, VARBINARY including `0x00`/`0xff`, BIGINT, DECIMAL, DATETIME, invalid SHA2 lengths, and prepared reuse were also compared; their checksum/hash values match MySQL.
- The JSON mismatch reproduced in three fresh database runs.
- Explicit `CAST(js AS CHAR)` is a working control and returns the MySQL checksum.

### Code location

`crc32TypeMatch` intentionally preserves every varlen input without a cast. JSON is varlen internally, so it reaches `builtInCrc32`, which hashes the vector bytes directly. Those bytes are MatrixOne's binary JSON encoding rather than the JSON text representation used for SQL string conversion.

### Environment

- MatrixOne: official `main` commit `0c3a04f390adaf6281fd592a49778ea5b1155e67`
- MySQL control: 8.0.45
- Local single-node MatrixOne deployment

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.