[
https://issues.apache.org/jira/browse/FLINK-40338?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18102086#comment-18102086
]
sepuri sai krishna commented on FLINK-40338:
--------------------------------------------
I've root-caused this and have a fix plus a regression test ready
(StringFunctionsITCase covering a TINYINT, SMALLINT and BIGINT index — it fails
with ClassCastException on all three without the fix). Could someone assign
this to me?
> ELT() throws ClassCastException when the index argument is not INT
> ------------------------------------------------------------------
>
> Key: FLINK-40338
> URL: https://issues.apache.org/jira/browse/FLINK-40338
> Project: Flink
> Issue Type: Bug
> Components: Table SQL / Runtime
> Affects Versions: 2.0.0, 2.1.0, 2.2.0, 2.3.0
> Reporter: sepuri sai krishna
> Priority: Major
>
> {{ELT}} accepts any {{INTEGER_NUMERIC}} index. {{IndexArgumentTypeStrategy}}
> returns the argument's own data type unchanged (no implicit cast to {{INT}}),
> and the documentation lists the supported signatures as:
> {noformat}
> index <TINYINT | SMALLINT | INTEGER | BIGINT>, expr <CHAR | VARCHAR>, exprs
> <CHAR | VARCHAR>
> index <TINYINT | SMALLINT | INTEGER | BIGINT>, expr <BINARY | VARBINARY>,
> exprs <BINARY | VARBINARY>
> {noformat}
> But {{EltFunction#eval}} indexes the varargs array with {{exprs[(int) index -
> 1]}}, where {{index}} is declared as {{java.lang.Number}}. Per JLS 5.5,
> casting a {{Number}} reference to {{int}} compiles to a narrowing reference
> conversion to {{Integer}} followed by unboxing, i.e. {{((Integer)
> index).intValue()}}. The call therefore succeeds only when the boxed value is
> exactly an {{Integer}}; a {{Byte}}, {{Short}} or {{Long}} fails the
> {{checkcast}}.
> h3. Reproducer
> {code:sql}
> SELECT ELT(CAST(2 AS BIGINT), 'scala', 'java');
> {code}
> {noformat}
> java.lang.ClassCastException: class java.lang.Long cannot be cast to class
> java.lang.Integer
> {noformat}
> Same for {{CAST(2 AS TINYINT)}} and {{CAST(2 AS SMALLINT)}}.
> h3. Why this was not caught
> 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 on the success path, when {{1 <= index <= number of
> expressions}}. That is why the existing test {{ELT(9223372036854775807, 'ab',
> 'b')}} passes -- it returns {{NULL}} before ever reaching the cast. Every
> other existing test uses an {{INT}} literal.
> h3. Fix
> Narrow the already-unboxed {{long idx}} rather than casting the {{Number}}
> reference.
> Present since FLINK-35987 introduced ELT; confirmed absent from release-1.20
> and present from release-2.0.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)