Skip to content

Dispatch on the stored type when an aggregation function picks a value getter - #19334

Open
Jackie-Jiang wants to merge 1 commit into
apache:masterfrom
Jackie-Jiang:stored_type_dispatch
Open

Dispatch on the stored type when an aggregation function picks a value getter#19334
Jackie-Jiang wants to merge 1 commit into
apache:masterfrom
Jackie-Jiang:stored_type_dispatch

Conversation

@Jackie-Jiang

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #19332, where this was noticed and deliberately left out.

FunnelEventsFunctionEvalAggregationFunction#getExtraFieldsBlocks and both switches in
TimeSeriesAggregationFunction chose their BlockValSet getter by the logical value type. The getters are
keyed to the stored representation, so:

Column Stored as Before After
BOOLEAN INT rejected as unsupported read via getIntValuesSV()
TIMESTAMP LONG needed a hand-written extra case folds into LONG
JSON STRING rejected as unsupported read via getStringValuesSV()

The tell was a hand-written case TIMESTAMP: glued onto case LONG: in the funnel switch. That case only existed
because the dispatch was on the wrong type — BOOLEAN and JSON never got the same manual patch, so they still
failed. It is removed, since TIMESTAMP folds into LONG once the stored type is used.

TimeSeriesAggregationFunction also gains the FLOAT case it was missing. Its numeric path reads
getDoubleValuesSV, which works for every numeric stored type, so FLOAT was excluded by omission rather than by
intent.

What was checked and deliberately left alone

The distinction is whether the code is choosing a getter or enforcing a contract:

  • Choosing a getter must use the stored type — the three sites fixed here.
  • Enforcing a contract must not. The sketch functions gate on logical BYTES to mean "this column holds a
    serialized sketch"
    rather than values to hash, which is the distinction [UUID 5/8] UUID aggregation, group-by and distinct #18873 introduced; testing the stored
    type there would misread a UUID column. BaseBooleanAggregationFunction rejects a non-BOOLEAN column on
    purpose, and using the stored type would wrongly accept plain INT.
  • Every dictionary.getValueType() call already returns the stored type — IntDictionary reports INT, so a
    BOOLEAN column's dictionary reports INT — so those are correct as written.

Swept for switch on a raw value type repo-wide and for equality comparisons across the aggregation package;
these three are the complete set.

Testing

StoredTypeDispatchTest is new and covers both functions, verified by mutation — reverting either fix, or dropping
the FLOAT case, fails the corresponding test.

It excludes one case deliberately. For the time-series function a JSON column now reaches
aggregateStringValues, but BaseTimeSeriesBuilder leaves string input unimplemented and the SUM builder throws
on it. That limitation sits downstream of this change, so asserting on it here would be testing the wrong
component. JSON is still covered on the funnel side, where all three types work.

…e getter

FunnelEventsFunctionEvalAggregationFunction#getExtraFieldsBlocks and both
switches in TimeSeriesAggregationFunction chose their BlockValSet getter by the
logical value type. The getters are keyed to the stored representation, so a
BOOLEAN column (stored as INT) and a JSON column (stored as STRING) were
rejected as unsupported even though the getter that reads them was already in
the switch.

The tell was a hand-written "case TIMESTAMP:" glued onto "case LONG:" in the
funnel switch. That case only existed because the dispatch was on the wrong
type; BOOLEAN and JSON never got the same manual patch and so still failed. It
is removed, since TIMESTAMP folds into LONG once the stored type is used.

TimeSeriesAggregationFunction also gains the FLOAT case it was missing. Its
numeric path reads getDoubleValuesSV, which works for every numeric stored
type, so FLOAT was excluded by omission rather than by intent.

The distinction is whether the code is choosing a getter or enforcing a
contract. Choosing a getter must use the stored type. Enforcing a contract must
not: the sketch functions gate on logical BYTES to mean "this column holds a
serialized sketch" rather than values to hash, and BaseBooleanAggregationFunction
rejects a non-BOOLEAN column on purpose. Both were checked and left alone, along
with every dictionary.getValueType() call, which already returns the stored type.

StoredTypeDispatchTest is new and covers both functions, verified by mutation.
It excludes one case deliberately: for the time-series function a JSON column
now reaches aggregateStringValues, but BaseTimeSeriesBuilder leaves string input
unimplemented and the SUM builder throws on it, so that limitation sits
downstream of this change and asserting on it would test the wrong component.
@Jackie-Jiang Jackie-Jiang added bug Something is not working as expected query Related to query processing functions Related to scalar or aggregation functions release-notes Referenced by PRs that need attention when compiling the next release notes labels Aug 21, 2026
@codecov-commenter

codecov-commenter commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.01%. Comparing base (3c92923) to head (d71f898).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
...gation/function/TimeSeriesAggregationFunction.java 0.00% 0 Missing and 2 partials ⚠️
...w/FunnelEventsFunctionEvalAggregationFunction.java 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19334      +/-   ##
============================================
+ Coverage     66.97%   67.01%   +0.03%     
  Complexity     1424     1424              
============================================
  Files          3463     3463              
  Lines        222078   222078              
  Branches      34957    34957              
============================================
+ Hits         148743   148822      +79     
+ Misses        61467    61376      -91     
- Partials      11868    11880      +12     
Flag Coverage Δ
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-25 67.01% <0.00%> (+0.03%) ⬆️
lane-a 100.00% <ø> (ø)
lane-b 0.00% <ø> (ø)
temurin 67.01% <0.00%> (+0.03%) ⬆️
unittests 67.01% <0.00%> (+0.03%) ⬆️
unittests1 57.72% <0.00%> (+0.02%) ⬆️
unittests2 38.89% <0.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something is not working as expected functions Related to scalar or aggregation functions query Related to query processing release-notes Referenced by PRs that need attention when compiling the next release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants