You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@flink.apache.org by "sepuri sai krishna (Jira)" <ji...@apache.org> on 2026/08/05 13:49:00 UTC
[jira] [Commented] (FLINK-40338) ELT() throws ClassCastException when the index argument is not INT
[ 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)