eugenegujing opened a new pull request, #7532:
URL: https://github.com/apache/texera/pull/7532

   ### What changes were proposed in this PR?
   
   One-line fix in `AggregationOperation.scala`: the `max` aggregation starts 
its running maximum from the type's minimum value, so its final "was this group 
empty?" check must compare against that same minimum value, but it compared 
against the type's maximum value instead (the line was copied from `min`, where 
that comparison is correct because `min` starts from the maximum).
   
   Because the check looked at the wrong sentinel, two results were silently 
wrong while the workflow completed with no error:
   
   - A group with only null values returned the sentinel itself instead of 
`null`, e.g. `-2147483648` for INTEGER or `1970-01-01 00:00:00` for TIMESTAMP.
   - A true maximum equal to the type's maximum value was mistaken for "no 
value seen" and discarded, so `max` over `{1, 5, 2147483647}` reported `5` (the 
largest value from the other local aggregation worker) instead of `2147483647`.
   
   #### Before-and-after
   
   Test data: group `g1` has only nulls, `g2` contains `{1, 5, 2147483647}`, 
`g3` contains `{10, 42}`.
   
   <img width="1347" height="900" alt="Screenshot 2026-08-07 at 2 27 40 PM" 
src="https://github.com/user-attachments/assets/faac65fd-e83f-4952-a0dd-b8109d56334d";
 />
   
   Before the fix, `max(v)` grouped by `k` returns `-2147483648` for `g1` 
(expected `null`) and `5` for `g2` (expected `2147483647`):
   
   <img width="1341" height="866" alt="Screenshot 2026-08-07 at 2 27 51 PM" 
src="https://github.com/user-attachments/assets/fdf7f045-aa34-44eb-adee-6e722839d7eb";
 />
   
   `min(v)` on the same data is correct (`null` for `g1`, `1` for `g2`, `10` 
for `g3`), confirming only `max`'s empty-group check is broken:
   
   <img width="1342" height="868" alt="Screenshot 2026-08-07 at 2 28 00 PM" 
src="https://github.com/user-attachments/assets/3df9c390-626f-4f01-9ca6-7e634927386b";
 />
   
   After the fix, `max(v)` returns `null` for `g1`, `2147483647` for `g2`, and 
`42` for `g3`:
   
   <img width="1131" height="756" alt="Screenshot 2026-08-07 at 5 54 17 PM" 
src="https://github.com/user-attachments/assets/68ba757c-8b4b-4682-b04e-8db740d1583c";
 />
   
   ### Any related issues, documentation, discussions?
   
   Closes #7531
   
   The regression was introduced by #1840, which generalised the hard-coded 
`Double` sentinels to per-type `minValue`/`maxValue` helpers and updated 
`maxAgg`'s initialiser but not its finaliser.
   
   ### How was this PR tested?
   
   Added 5 regression tests, all of which fail without the one-line fix and 
pass with it (verified in both directions):
   
   - `AggregateOpSpec`: `max` over empty input and over all-null input returns 
`null`; `max` keeps a true maximum equal to the type's maximum value, covering 
INTEGER, LONG, DOUBLE, and TIMESTAMP.
   - `AggregationOperationSpec`: a worker-to-final pipeline via `getFinal` 
keeps `Int.MaxValue` when partial results are re-aggregated, reproducing the 
two-worker scenario shown above; `max`'s merge stays neutral when one side saw 
no values.
   
   Full aggregate suite: `sbt "WorkflowOperator/testOnly 
org.apache.texera.amber.operator.aggregate.*"` — 68 tests, all passing.
   
   Also verified end to end in the UI with the workflow shown above 
(screenshots are from before and after rebuilding the backend with this fix).
   
   ### Was this PR authored or co-authored using generative AI tooling?
   
   Co-authored by: Claude Code (Claude Fable 5)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to