akashchamp opened a new pull request, #19653:
URL: https://github.com/apache/pinot/pull/19653

   ## Description
   
   Fixes #19603.
   
   `SELECT MIN(col), MAX(col) FROM table` on a `STRING`-typed column (e.g. a 
`dateTimeFieldSpec` with
   `SIMPLE_DATE_FORMAT`, or a plain `STRING` dimension) fails with a bare 
`NumberFormatException`
   (`For input string: "2013-07-01"`), even though the column is declared 
correctly. The error gives no
   indication that Pinot already has `MINSTRING`/`MAXSTRING`, or that 
`MIN`/`MAX` can be automatically
   rewritten to them via the `autoRewriteAggregationType=true` query option 
(added in #16980 / #17058).
   
   This PR implements suggestion 1 from the issue: **improve the error 
message**, without changing any
   query behavior or defaults (no breaking changes).
   
   ### Root cause
   
   `MIN`/`MAX` are numeric-only in Pinot (`AggregationFunctionType.MIN`/`MAX` 
map to `SqlTypeName.DOUBLE`).
   Two separate code paths convert the resolved value to a `double` without 
checking the column's type
   first, so a `STRING` value falls through to `Double.parseDouble(...)` and 
throws an opaque
   `NumberFormatException`:
   
   1. **Non-scan / dictionary-metadata path** 
(`NonScanBasedAggregationOperator`, used for e.g.
      `SELECT MIN(col) FROM t` with no filter): 
`AggregationFunctionUtils#toDouble`.
   2. **Scan-based group-by path** (`GroupByOperator`, used for e.g. `... GROUP 
BY ...`):
      `MinAggregationFunction`/`MaxAggregationFunction#aggregateSVGroupBySV` 
(and the MV group-by
      variants), which — unlike `aggregateSV`, which already validates the 
stored type — called
      `BlockValSet#getDoubleValuesSV/MV` directly.
   
   ### Changes
   
   - `AggregationFunctionUtils#toDouble`: catches the `NumberFormatException` 
and rethrows a
     `BadQueryRequestException` naming `MINSTRING`/`MAXSTRING` and 
`autoRewriteAggregationType`.
   - `MinAggregationFunction`/`MaxAggregationFunction`: added a 
`checkNumericType` guard, called from
     `aggregate()`, `aggregateGroupBySV()`, and `aggregateGroupByMV()` 
(mirroring the existing check
     already present in `aggregateSV()`), so every entry point fails fast with 
the same clear message
     instead of only the plain scalar SV path being covered. The pre-existing 
message in `aggregateSV()`'s
     `default` case was extended with the same guidance for consistency.
   
   No behavior changes for numeric columns; `MINSTRING`/`MAXSTRING` and 
`autoRewriteAggregationType` are
   unchanged.
   
   Documenting the workaround on the `MIN`/`MAX` docs page (suggestion 2) and 
defaulting
   `autoRewriteAggregationType` to `true` (suggestion 3, a behavior change 
needing separate discussion)
   are left out of scope for this PR.
   
   ## How was this tested?
   
   - Added unit tests reproducing both reported stack traces and asserting the 
new message:
     - `AggregationFunctionUtilsTest#testMinAndMaxOnNonNumericDictionaryThrows` 
— dictionary-encoded
       non-numeric value (the `NonScanBasedAggregationOperator` path from the 
issue).
     - 
`MinAggregationFunctionTest`/`MaxAggregationFunctionTest#testNonNumericColumnExceptionIn{Aggregate,
       AggregateGroupBySV,AggregateGroupByMV}Method` — `STRING` `BlockValSet`, 
mirroring the existing
       `MinStringAggregationFunctionTest` pattern for the reverse 
(numeric-on-*STRING-only* function) case.
   - `./mvnw -pl pinot-core -am test 
-Dtest=AggregationFunctionUtilsTest,MinAggregationFunctionTest,MaxAggregationFunctionTest
 -Dsurefire.failIfNoSpecifiedTests=false test`
   - `./mvnw -pl pinot-core spotless:apply license:format checkstyle:check 
license:check`
   - Manually verified against a local table with a `STRING` column that both 
queries below now return
     a `BadQueryRequestException` whose message points to 
`MINSTRING`/`MAXSTRING` and
     `autoRewriteAggregationType`, instead of a raw `NumberFormatException`:
     - `SELECT MIN(stringCol) FROM t` (no `GROUP BY`, non-scan path)
     - `SELECT dimCol, MIN(stringCol) FROM t GROUP BY dimCol` (scan-based 
group-by path)
   
   ## Notes for reviewers
   
   I don't have write access to add labels to this PR — happy to see the 
appropriate label
   (`bugfix`) applied.
   
   This change was prepared with AI assistance (Claude Code).
   


-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to