Skip to content

perf(calcite): fold GROUP BY on boolean and integer columns per value - #561

Merged
dfa1 merged 2 commits into
mainfrom
feat/groupby-numeric
Oct 18, 2026
Merged

dfa1 merged 2 commits into
mainfrom
feat/groupby-numeric

Conversation

@dfa1

@dfa1 dfa1 commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Two commits:

  1. refactor: LongIntMap moves from writer.encode to core.compute, so the reader can use it (the reader cannot depend on the writer).
  2. perf: Compute.groupedAggregate also groups by a boolean column and an integer column other than u64: group ids are assigned through LongIntMap in a first pass, rows fold per id in a second, no key boxed per row. More than 65,536 values in a chunk (or 10,000 groups in all) falls back to the scan. Keys become Object (String/Boolean/Long); the method is unreleased.
Raincloud, best of 3 Before After
appian-order group by order_isExpeditedShipped 116 ms 32 ms
store_sales group by ss_store_sk, count, sum 154 ms 76 ms
imdb title group by kind_id 93 ms 36 ms
customer where segment = 'BUILDING' group by nation 30 ms 16 ms

Tests

  • ComputeTest: boolean keys with a null group, integer keys with a filter, u64 and too-many-values declines.
  • vortex-jni cross-check: GROUP BY on a Rust-written integer column, with and without WHERE, pushed down and equal to the scan.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WtuVGQ5h5Lk6Zn4JnkxF1K

dfa1 and others added 2 commits October 18, 2026 12:54
The reader needs the same primitive long-to-int map for grouped
aggregation that the writer uses for dictionary encoding and stats, and
the reader cannot depend on the writer. core.compute already holds the
kernels both sides share.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WtuVGQ5h5Lk6Zn4JnkxF1K
Only a dictionary-encoded string column grouped in the scan; a GROUP BY
on a boolean or integer column built a row per record for Calcite to
hash.

Compute.groupedAggregate now also groups by a boolean column (two ids)
and an integer column other than u64: a first pass assigns group ids
through the primitive LongIntMap, a second folds the rows per id, so no
key is boxed per row. More than 65,536 distinct values in a chunk
declines, and so do more than 10,000 groups in all, as before. The
result keys are Object (String, Boolean or Long); the method is
unreleased, so the signature changes in place.

Raincloud, best of 3, ms:
  appian-order  group by order_isExpeditedShipped           116 -> 32
  store_sales   group by ss_store_sk, count, sum           154 -> 76
  imdb title    group by kind_id                            93 -> 36
  customer      where segment = 'BUILDING' group by nation   30 -> 16

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WtuVGQ5h5Lk6Zn4JnkxF1K
@dfa1
dfa1 merged commit b1d7525 into main Oct 18, 2026
9 checks passed
@dfa1
dfa1 deleted the feat/groupby-numeric branch October 18, 2026 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant