Skip to content

[4.2-dev] fix(hashmap): accept broadcast const iterator vectors - #26843

Merged
mergify[bot] merged 2 commits into
matrixorigin:4.2-devfrom
LeftHandCold:backport/4.2-const-vector-hash
Aug 9, 2026
Merged

[4.2-dev] fix(hashmap): accept broadcast const iterator vectors#26843
mergify[bot] merged 2 commits into
matrixorigin:4.2-devfrom
LeftHandCold:backport/4.2-const-vector-hash

Conversation

@LeftHandCold

Copy link
Copy Markdown
Collaborator

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue #25992

What this PR does / why we need it:

Backport #26836 to 4.2-dev.

#26042 fixed the original prepared-parameter identity problem. Later, #26531
added strict HashMap iterator row-range validation and incorrectly treated a
physical length-1 const vector as a flat vector. Prepared GROUP BY ? therefore
fails whenever the input batch contains more than one logical row.

This change preserves strict bounds for flat vectors while accepting non-empty
const and const-null vectors as broadcast inputs, matching the existing IntHashMap
and StrHashMap encoders. Zero-length const vectors are still rejected whenever
rows are requested.

Validation on the 4.2-dev base (4066fffaf7):

  • malformed-flat and const-broadcast regression tests, -count=10
  • full pkg/common/hashmap test and race test
  • go build and go vet for pkg/common/hashmap
  • validateIteratorVectors coverage: 100%

The cherry-picked commit retains -x provenance for #26836.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep-reviewed exact head 917f6bc. No blocking correctness, performance, or unhappy-path findings. The cherry-pick has the same stable patch-id as source PR #26836. Const and const-null broadcast semantics are restored while malformed flat and empty const reads remain rejected. Focused tests, race x100, full hashmap tests and race, direct group consumer tests, build, vet, diff-check, and base/head benchmarks all pass. Flat Find remains 0 B/op and 0 allocs/op. Review submitted without waiting for remaining CI.

@mergify

mergify Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • Entered queue2026-08-09 08:09 UTC · Rule: release-4.2 · triggered by rule Automatic queue on approval for release-4.2
  • Checks skipped · PR is already up-to-date
  • Merged2026-08-09 08:09 UTC · at 06172fae718514c71a0c7187249ce7c97b596532 · squash

This pull request spent 11 seconds in the queue, including 1 second running CI.

Required conditions to merge
  • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
  • github-review-approved [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / SCA Test on Linux/arm64
    • check-neutral = Matrixone CI / SCA Test on Linux/arm64
    • check-skipped = Matrixone CI / SCA Test on Linux/arm64
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / UT Test on Ubuntu/x86
    • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
    • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
    • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
    • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Utils CI / Coverage
    • check-neutral = Matrixone Utils CI / Coverage
    • check-skipped = Matrixone Utils CI / Coverage
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PROXY)
    • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PROXY)
    • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PROXY)

@mergify
mergify Bot merged commit 9301a23 into matrixorigin:4.2-dev Aug 9, 2026
24 of 25 checks passed
@mergify mergify Bot removed the queued label Aug 9, 2026
XuPeng-SH added a commit that referenced this pull request Aug 9, 2026
## What type of PR is this?

- [ ] API-change
- [x] BUG
- [ ] Improvement
- [ ] Documentation
- [ ] Feature
- [ ] Test and CI
- [ ] Code Refactoring

## Which issue(s) this PR fixes:

issue #25992

Follow-up to #26843 (the `4.2-dev` backport of #26836).

## What this PR does / why we need it:

After #26843 accepts a physical length-1 const vector as a broadcast
input, a
prepared grouped query can correctly produce a projection batch whose
logical
row count is greater than its first vector's physical length:

```sql
SELECT ? AS projection_value, SUM(value_col) AS total
FROM metric_rows GROUP BY bucket ORDER BY total;
```

The frontend still derived result cardinality from
`bat.Vecs[0].Length()`.
Consequently, it emitted only one MySQL result row for a three-row batch
and
also undercounted `sentRows`. Saved query results had a second
inconsistency:
their metadata reported three rows, but object storage and `result_scan`
preserved only the first physical row.

This change uses `batch.RowCount()`, the logical cardinality propagated
by the
projection operator, for protocol output and row accounting. At the
query-result
persistence boundary, it validates vector shapes and creates an owned
writer
view only when compact const vectors need their logical lengths
normalized.
Aligned vectors are borrowed, mismatched const/const-null vectors remain
physically scalar, and the executor-owned input batch is never mutated.

Regression coverage includes flat, const, broadcast const, const-null,
malformed
and zero-row batches; allocation/write failure cleanup; real object
writer plus
`result_scan`; SQL-level prepared statement reuse; and the original
`GROUP BY ?`
path.

Validation on the exact `4.2-dev` base `9301a23cc8`:

- The direct-output BVT on the unfixed base: 19/21 statements pass; both
  parameter-first executions incorrectly return one row.
- On the direct-output-only candidate, `EXECUTE` returns 3 rows but the
immediate
  `result_scan(last_query_id())` returns 1 row.
- Focused frontend regressions, `-count=10`: pass.
- Full `pkg/frontend` test suite: pass.
- `go build -mod=readonly ./pkg/frontend`: pass.
- `go vet -mod=readonly ./pkg/frontend`: pass.
- `make build`: pass.
- Isolated single-node fixed candidate BVT, including saved scans for
first,
  NULL-reuse, and non-first parameters: 26/26 statements pass.
- MySQL binary `COM_STMT_PREPARE/EXECUTE` probe: parameter-first returns
3 rows,
NULL statement reuse returns 3 rows, and the #26843 grouped-parameter
control
  returns 1 row.

Direct output keeps an O(1) cardinality lookup. Saved aligned batches
allocate
nothing beyond the existing path. A mismatched const adds an O(column
count)
validation and copies only scalar physical storage; no per-row
materialization
or global object-writer contract change is introduced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Something isn't working size/S Denotes a PR that changes [10,99] lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants