diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/StringFunctionsITCase.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/StringFunctionsITCase.java index 0fd1c53dac979..076eeb5ba5a33 100644 --- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/StringFunctionsITCase.java +++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/StringFunctionsITCase.java @@ -149,12 +149,15 @@ private Stream bTrimTestCases() { private Stream eltTestCases() { return Stream.of( TestSetSpec.forFunction(BuiltInFunctionDefinitions.ELT) - .onFieldsWithData(null, null, null, new byte[] {1, 2, 3}) + .onFieldsWithData(null, null, null, new byte[] {1, 2, 3}, (byte) 2, (short) 2, 2L) .andDataTypes( DataTypes.INT(), DataTypes.STRING(), DataTypes.BYTES(), - DataTypes.BYTES()) + DataTypes.BYTES(), + DataTypes.TINYINT(), + DataTypes.SMALLINT(), + DataTypes.BIGINT()) // null input .testResult( $("f0").elt("a", "b"), "ELT(f0, 'a', 'b')", null, DataTypes.CHAR(1)) @@ -182,6 +185,29 @@ private Stream eltTestCases() { DataTypes.VARCHAR(5)) .testResult( lit(2).elt("a", "b"), "ELT(2, 'a', 'b')", "b", DataTypes.CHAR(1)) + // FLINK-40338: non-INT INTEGER_NUMERIC index must not throw ClassCastException. + // Constant case covers the ExpressionReducer (constant-folding) path; + // field-reference cases below cover the codegen'd operator path. + .testResult( + lit(2).cast(DataTypes.TINYINT()).elt("scala", "java"), + "ELT(CAST(2 AS TINYINT), 'scala', 'java')", + "java", + DataTypes.VARCHAR(5)) + .testResult( + $("f4").elt("scala", "java"), + "ELT(f4, 'scala', 'java')", + "java", + DataTypes.VARCHAR(5)) + .testResult( + $("f5").elt("scala", "java"), + "ELT(f5, 'scala', 'java')", + "java", + DataTypes.VARCHAR(5)) + .testResult( + $("f6").elt("scala", "java"), + "ELT(f6, 'scala', 'java')", + "java", + DataTypes.VARCHAR(5)) .testResult( lit(2).elt($("f2"), $("f3"), $("f3")), "ELT(2, f2, f3, f3)", diff --git a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/EltFunction.java b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/EltFunction.java index 9af2cf20367d8..9ad4ac7116dff 100644 --- a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/EltFunction.java +++ b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/EltFunction.java @@ -40,6 +40,9 @@ public EltFunction(SpecializedContext context) { if (idx < 1 || idx > exprs.length) { return null; } - return exprs[(int) index - 1]; + // Narrow the already-unboxed long instead of casting the Number reference. + // Casting `index` (java.lang.Number) to int compiles to a checkcast to Integer + // followed by unboxing, which throws ClassCastException for Byte/Short/Long. + return exprs[(int) idx - 1]; } }