Skip to content

perf(calcite): total decimal SUM/AVG exactly as unscaled longs in the scan - #563

Merged
dfa1 merged 1 commit into
mainfrom
feat/decimal-sum
Oct 18, 2026
Merged

dfa1 merged 1 commit into
mainfrom
feat/decimal-sum

Conversation

@dfa1

@dfa1 dfa1 commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Stacked on #562 (rebased onto main once it merges).

Zone statistics carry no decimal sum, so every decimal SUM/AVG was left to Calcite (a BigDecimal per row).

  • DecimalArray.getUnscaledLong(i) reads the unscaled value without a BigDecimal; precision ≤ 18 always fits a long.
  • VortexTable.decimalFold totals a whole-table or filtered decimal SUM with Math.addExact (and backs COUNT/MIN/MAX of a decimal column when the zone fold declines); the grouped kernel gains a decimal lane.
  • Precision > 18 or a sum past a long declines to Calcite. DECIMAL literals are now exact (they went through a double), and $SUM0 (Calcite's reduction of AVG) is handled.
Raincloud, best of 3 Before After
store_sales sum(ss_net_paid), sum(ss_net_profit) 143 ms 25 ms
customer group by c_mktsegment, sum(c_acctbal) 65 ms 15 ms

Tests

  • getUnscaledLong at every width (and past a long), byte-parts; grouped decimal lane (exact at scale, overflow and precision > 18 decline).
  • DecimalSumTest: whole-table, filtered (SUM/AVG/COUNT) and grouped against scanning oracles.
  • vortex-jni cross-check: the same over a Rust-written nullable DECIMAL(10, 2).

🤖 Generated with Claude Code

https://claude.ai/code/session_01WtuVGQ5h5Lk6Zn4JnkxF1K

… scan

Zone statistics carry no decimal sum, so every SUM or AVG of a decimal
column was left to Calcite, which adds a BigDecimal per row.

DecimalArray.getUnscaledLong reads a value's unscaled long without a
BigDecimal (the direct-buffer, byte-parts and constant arrays read it
straight from their storage). Every value of a decimal with precision 18
or less fits a long, so:
- VortexTable.decimalFold totals a whole-table or filtered decimal SUM
  with Math.addExact, and also backs COUNT/MIN/MAX of a decimal column
  when the zone fold declines;
- the grouped kernel gains a decimal lane, so GROUP BY ... SUM(decimal)
  folds in the scan too.
A precision past 18 or a sum past a long declines to Calcite. DECIMAL
literals are now exact (they went through a double), and the rule
handles $SUM0, which Calcite reduces AVG to, so AVG pushes down too.

Raincloud, best of 3, ms:
  store_sales  sum(ss_net_paid), sum(ss_net_profit)          143 -> 25
  customer     group by c_mktsegment, sum(c_acctbal)          65 -> 15

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WtuVGQ5h5Lk6Zn4JnkxF1K
@dfa1
dfa1 force-pushed the feat/decimal-sum branch from 41d2ab0 to 95d21be Compare October 18, 2026 11:18
@dfa1
dfa1 merged commit 182d323 into main Oct 18, 2026
9 checks passed
@dfa1
dfa1 deleted the feat/decimal-sum 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