matrixorigin / matrixorigin/matrixone
[Bug]: Regression: prepared JSON boolean predicates return wrong SUM/GROUP_CONCAT results after #27540
- 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 have checked the existing issues.
Related: #27529, fixed by #27540. This report is a **confirmed subsequent regression**, rather than an assertion that the original fix never worked: the same aggregate repro passes on an official main image containing #27540 and fails on a later descendant. Please keep the historical fix and this regression distinguishable.
### Branch Name
main
### Commit ID
Confirmed affected: `76e1a9bd9f75480ee76f686c43994f938a15a8d5`.
Verified earlier good control: `34fb54084ca14275989944ae5994ae79e1ab285e` (2026-08-31), which contains the #27540 merge commit `1a4f656bb2b5b7f2fb1a6d951c4806ce7d124ba5` and is an ancestor of the affected commit.
This bounds an observed good-to-bad interval; it does **not** identify the introducing commit.
### Other Environment Information
- Independently reproduced on 2026-09-17 using two official MatrixOne images, sequentially on the same Linux 6.1.0-31-amd64 development host.
- Both: standalone quickstart, 2 CPU quota, 4 GiB memory, memory+swap limit 4 GiB, `GOMEMLIMIT=3GiB`, fresh isolated container data, identical six-row fixture and SQL.
- Affected image: `ccr.ccs.tencentyun.com/matrixone-dev/matrixone:commit-76e1a9bd9f75480ee76f686c43994f938a15a8d5`, digest `sha256:ce759897a039d1aa432d258a5bdab534ae3709f7321d014b8fa0428b5e52198c`.
- Good image: `ccr.ccs.tencentyun.com/matrixone-dev/matrixone:commit-34fb54084`, digest `sha256:36a312f79cabb5119848670c43bff1ef5569c765def0b74a3bfc9fdfc7bc08dd`; the binary reports commit `34fb54084`.
- SQL-text `PREPARE`/`EXECUTE` reproduced through PyMySQL; the affected minimal SQL was independently replayed through the MySQL CLI, without MOTR.
- No OOM was recorded for either isolated instance. Each completed its queries and a health query successfully. The stopped good-control container later had exit 137 from the bounded manual stop, with `OOMKilled=false`; that shutdown occurred after its successful measurements.
### Actual Behavior
For a JSON boolean predicate with a genuine SQL boolean parameter, the result changes depending on the SELECT projection. In the affected version, prepared `GROUP_CONCAT` and `SUM` also match JSON strings `"true"`/`"false"`.
| Query shape / parameter | Expected | Official good `34fb54084` | Affected `76e1a9bd9f` |
| --- | --- | --- | --- |
| Direct `GROUP_CONCAT(id ORDER BY id)`, literal TRUE | `1` | `1` | `1` |
| Prepared `SELECT id ORDER BY id`, TRUE | row `1` | row `1` | row `1` |
| Prepared `COUNT(*)`, TRUE | `1` | `1` | `1` |
| Prepared `GROUP_CONCAT(id ORDER BY id)`, TRUE | `1` | `1` | **`1,3`** |
| Prepared `GROUP_CONCAT(id ORDER BY id)`, FALSE | `2` | `2` | **`2,4`** |
| Direct `SUM(id)`, literal TRUE | `1` | `1` | `1` |
| Prepared `SUM(id)`, TRUE | `1` | `1` | **`4`** |
| Prepared `SUM(id)`, FALSE | `2` | `2` | **`6`** |
Prepared `GROUP_CONCAT(id)` without aggregate ORDER BY also fails, so the symptom is not specific to ordered GROUP_CONCAT. The failure occurs on the first execution and after parameter rebind/reuse. A diagnostic `JSON_OBJECT('v', @b)` confirms the parameter is a JSON boolean after `SET @b=TRUE`, not a SQL string `'true'`.
This is a wrong-result bug, not formatting, an expected-output mistake, or only a test-runner failure. The repro demonstrates query correctness impact; it does not establish storage corruption.
### Expected Behavior
The predicate must preserve the #27529/#27540 JSON/SQL boolean comparison contract across prepared execution and aggregate plan shapes:
- TRUE matches JSON boolean `true`, not JSON string `"true"`.
- FALSE matches JSON boolean `false`, not JSON string `"false"`.
- The matched-row multiset must not change merely because the projection is `id`, `COUNT(*)`, `SUM(id)`, or `GROUP_CONCAT(id)`.
- JSON null and missing keys must not introduce matches.
### Steps to Reproduce
Run in one SQL connection using a disposable database name that does not already exist. No production data is required.
```sql
CREATE DATABASE json_bool_aggregate_repro;
USE json_bool_aggregate_repro;
CREATE TABLE docs(id INT PRIMARY KEY, meta JSON);
INSERT INTO docs VALUES
(1, '{"active":true}'),
(2, '{"active":false}'),
(3, '{"active":"true"}'),
(4, '{"active":"false"}'),
(5, '{"active":null}'),
(6, '{}');
-- Correct: 1 on both versions.
SELECT GROUP_CONCAT(id ORDER BY id)
FROM docs WHERE JSON_EXTRACT(meta, '$.active') = TRUE;
PREPARE p FROM
'SELECT GROUP_CONCAT(id ORDER BY id) FROM docs
WHERE JSON_EXTRACT(meta, ''$.active'') = ?';
SET @b = TRUE;
EXECUTE p USING @b;
-- Expected 1; affected version returns 1,3.
SET @b = FALSE;
EXECUTE p USING @b;
-- Expected 2; affected version returns 2,4.
DEALLOCATE PREPARE p;
-- Correct: 1 on both versions.
SELECT SUM(id) FROM docs WHERE JSON_EXTRACT(meta, '$.active') = TRUE;
PREPARE p FROM
'SELECT SUM(id) FROM docs WHERE JSON_EXTRACT(meta, ''$.active'') = ?';
SET @b = TRUE;
EXECUTE p USING @b;
-- Expected 1; affected version returns 4.
DEALLOCATE PREPARE p;
-- Optional cleanup: only the disposable database created above.
DROP DATABASE json_bool_aggregate_repro;
```
### Additional information
#### Original CI evidence
- [MOTR job 104966172817](https://github.com/matrixorigin/mo-nightly-regression/actions/runs/35113264245/job/104966172817), run `35113264245`, attempt 1.
- Job: `TKE TP/AP Family (1TP+2AP Weekly Full) / weekly-shadow-1x2 / TP Tail / MOTR regression`.
- Job interval: **2026-09-16 20:38:06–21:35:30 UTC** (2026-09-17 04:38:06–05:35:30 Asia/Shanghai).
- Case: `14_issue_regression.issue_27529_json_boolean_string`.
- MOTR revision: `ddc14f58389b2ddf883fbc5744095d4869a96e82`.
- Workflow repository revision: `8b5fd51cdb4196d39714fc726092a9b0fa4504e6`.
- Namespace: `mo-main-family-35113264245-1`.
- Artifact: `tke-family-weekly-shadow-1x2-motr-35113264245-1`, `failures_parallel.txt`, around line 6741. Direct boolean comparisons passed; the prepared TRUE aggregate differed as `-1` / `+1,3`.
- Subject identity is corroborated by `test-control-evidence-v1-tke-35113264245-1` and then independently reproduced using that exact image.
#### Why this is a new regression report
- #27529's [closure validation](https://github.com/matrixorigin/matrixone/issues/27529#issuecomment-5472985544) records successful direct and prepared checks.
- The independent official-image comparison above shows this exact aggregate repro **also worked after that fix**, at `34fb54084`, and now fails at its descendant `76e1a9bd9f`.
- The existing `pkg/tests/issues/issue_27529_test.go` primarily checks returned IDs rather than this SUM/GROUP_CONCAT shape. Passing that narrow test does not close the demonstrated aggregate regression.
#### Investigation and acceptance boundaries
- The exact introducing commit and complete code-level root cause are not yet established. Prepared parameter category preservation during plan specialization/rebinding is an investigation direction, not a proven culprit PR.
- SQL-text PREPARE is confirmed affected. Binary-protocol prepared execution has not been independently validated in this investigation and must not be assumed affected or unaffected.
- At investigation time, official main HEAD was `8e8e1998ef02b1f6233ddb1c2d3208f3b70d2d83`; its exact image tag was not available. **This report does not claim runtime verification of that later HEAD.**
- Fix validation should retain the original direct/row-selection checks and add TRUE/FALSE, JSON boolean/string/null/missing controls, SUM and GROUP_CONCAT (with/without ORDER BY), first execute and rebind/reuse. Check SQL-text and binary prepared protocols separately and compare typed results against the equivalent literal predicate.
Contributor guide
Assessment
This issue has not been assessed yet.