hulincup opened a new pull request, #28931:
URL: https://github.com/apache/flink/pull/28931

   ## Problem fixed & how
   
   `ELT(index, expr, exprs...)` accepts any `INTEGER_NUMERIC` index 
(`TINYINT`/`SMALLINT`/`INT`/`BIGINT`). However, `EltFunction#eval` declares 
`index` as `java.lang.Number` and indexes the varargs array with `exprs[(int) 
index - 1]`. Per JLS 5.5, casting a `Number` reference to `int` compiles to a 
`checkcast` to `Integer` followed by unboxing, so a `Byte`, `Short`, or `Long` 
value throws `ClassCastException` on the success path (`1 <= index <= 
exprs.length`).
   
   ```sql
   SELECT ELT(CAST(2 AS BIGINT), 'scala', 'java');
   -- java.lang.ClassCastException: class java.lang.Long cannot be cast to 
class java.lang.Integer
   ```
   
   Same for `CAST(2 AS TINYINT)` and `CAST(2 AS SMALLINT)`.
   
   The out-of-range guard above the cast uses `index.longValue()`, so 
out-of-range indices of any type still return `NULL` correctly; the exception 
only fires in the valid range. That is why the existing test 
`ELT(9223372036854775807, 'ab', 'b')` passes (returns `NULL` before reaching 
the cast) and every other existing test uses an `INT` literal.
   
   Present since 
[FLINK-35987](https://issues.apache.org/jira/browse/FLINK-35987) introduced 
ELT; confirmed absent from release-1.20 and present from release-2.0.
   
   **Fix:** narrow the already-unboxed `long idx` (computed above for the range 
check) via primitive narrowing `(int) idx` (JLS 5.1.3, no `checkcast`) instead 
of casting the `Number` reference.
   
   ## Behavior modified
   
   - **previous:** `ELT` with a non-INT `INTEGER_NUMERIC` index 
(`TINYINT`/`SMALLINT`/`BIGINT`) in the valid range `1 <= index <= exprs.length` 
threw `ClassCastException`.
   - **now:** non-INT integer indices correctly return the corresponding 
expression.
   - **impact:** only the success path for non-INT integer indices; `INT` 
indices, `NULL`, and out-of-range behavior are unchanged.
   
   ## Code refactored
   
   `EltFunction.eval`: `exprs[(int) index - 1]` → `exprs[(int) idx - 1]`, with 
a 3-line comment explaining the JLS rationale.
   
   ## Features added
   
   N/A
   
   ## Functions optimized
   
   N/A
   
   ## Test plan
   
   - [x] Added 3 regression cases to `StringFunctionsITCase.eltTestCases()` 
covering `TINYINT`, `SMALLINT`, and `BIGINT` indices (the three types that 
previously threw `ClassCastException`). Each expects the correct expression 
(`"java"` for index 2).
   - [ ] The local environment runs Java 8 and cannot build Flink master 
(requires Java 11+), so verification relies on CI:
     ```
     mvn -pl flink-table/flink-table-planner -am test 
-Dtest=StringFunctionsITCase
     ```
   


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