This is an automated email from the ASF dual-hosted git repository.

raminqaf pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git


The following commit(s) were added to refs/heads/master by this push:
     new e4d2b06ff33 [FLINK-41330][table] Return NULL for a VARIANT array index 
outside the INT range (#29785)
e4d2b06ff33 is described below

commit e4d2b06ff33a6065ac2f1ba10d823ba30cdc0ad9
Author: Ramin Gharib <[email protected]>
AuthorDate: Wed Nov 4 14:39:05 2026 +0100

    [FLINK-41330][table] Return NULL for a VARIANT array index outside the INT 
range (#29785)
    
    v[i] on an array VARIANT accepts any integer index, BIGINT included, but 
the generated code cast the index to int before the lookup. An index outside 
the INT range wrapped modulo 2^32 onto an existing element, so v[4294967297] 
returned the first element. A BIGINT index is now range-checked as a long 
before it is narrowed, and an index outside the INT range returns NULL like any 
other out-of-range index. Smaller integer index types keep the int lookup, 
since they cannot wrap onto a val [...]
    
    Generated-by: Claude Code 2.1.318 (Claude Opus 5.5)
---
 .../planner/codegen/calls/ScalarOperatorGens.scala | 14 ++++++++++---
 .../nodes/exec/stream/VariantSemanticTest.java     | 24 ++++++++++++++++++++++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git 
a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/calls/ScalarOperatorGens.scala
 
b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/calls/ScalarOperatorGens.scala
index 891f9c4b19a..b8f829b2205 100644
--- 
a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/calls/ScalarOperatorGens.scala
+++ 
b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/calls/ScalarOperatorGens.scala
@@ -1738,10 +1738,18 @@ object ScalarOperatorGens {
     val keyType = key.resultType
 
     val accessCode = if (isIntegerNumeric(keyType)) {
+      val elementAccess = if (keyType.is(BIGINT)) {
+        // Narrowing a BIGINT key to int before the range check would wrap an 
out-of-range key
+        // onto an existing element. A smaller key cannot wrap onto a valid 
index.
+        s"$keyTerm >= 1L && $keyTerm - 1L <= Integer.MAX_VALUE " +
+          s"? $variantTerm.getElement((int) ($keyTerm - 1L)) : null"
+      } else {
+        s"$variantTerm.getElement((int) $keyTerm - 1)"
+      }
       generateIntegerKeyAccess(
         variantTerm,
         variantTypeTerm,
-        keyTerm,
+        elementAccess,
         resultTerm,
         nullTerm,
         tmpValue
@@ -1807,13 +1815,13 @@ object ScalarOperatorGens {
   private def generateIntegerKeyAccess(
       variantTerm: String,
       variantTypeTerm: String,
-      keyTerm: String,
+      elementAccess: String,
       resultTerm: String,
       nullTerm: String,
       tmpValue: String): String = {
     s"""
        |  if ($variantTerm.isArray()){
-       |    $variantTypeTerm $tmpValue = $variantTerm.getElement((int) 
$keyTerm - 1);
+       |    $variantTypeTerm $tmpValue = $elementAccess;
        |    if ($tmpValue == null) {
        |      $nullTerm = true;
        |    } else {
diff --git 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/nodes/exec/stream/VariantSemanticTest.java
 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/nodes/exec/stream/VariantSemanticTest.java
index 1fba4b01203..d4616ecd75e 100644
--- 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/nodes/exec/stream/VariantSemanticTest.java
+++ 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/nodes/exec/stream/VariantSemanticTest.java
@@ -570,6 +570,29 @@ public class VariantSemanticTest extends SemanticTestBase {
                             "sink_t")
                     .build();
 
+    static final TableTestProgram 
VARIANT_ARRAY_ACCESS_WITH_INDEX_OUTSIDE_INT_RANGE =
+            TableTestProgram.of(
+                            
"variant-array-access-with-index-outside-int-range",
+                            "validates that a BIGINT index outside the INT 
range returns NULL")
+                    .setupTableSource(
+                            SourceTestStep.newBuilder("t")
+                                    .addSchema("v VARIANT", "i BIGINT")
+                                    .producedValues(
+                                            Row.of(
+                                                    
BUILDER.array().add(BUILDER.of(1)).build(),
+                                                    4294967297L),
+                                            Row.of(
+                                                    
BUILDER.array().add(BUILDER.of(1)).build(),
+                                                    -4294967295L))
+                                    .build())
+                    .setupTableSink(
+                            SinkTestStep.newBuilder("sink_t")
+                                    .addSchema("e VARIANT")
+                                    .consumedValues(new Row(1), new Row(1))
+                                    .build())
+                    .runSql("INSERT INTO sink_t SELECT v[i] FROM t")
+                    .build();
+
     static final TableTestProgram VARIANT_OBJECT_ACCESS =
             TableTestProgram.of(
                             "variant-object-access",
@@ -749,6 +772,7 @@ public class VariantSemanticTest extends SemanticTestBase {
                 VARIANT_ARRAY_ACCESS,
                 VARIANT_ARRAY_ACCESS_WITH_DIFFERENT_INDEX_TYPES,
                 VARIANT_ARRAY_ACCESS_WITH_NON_LITERAL_INDEX,
+                VARIANT_ARRAY_ACCESS_WITH_INDEX_OUTSIDE_INT_RANGE,
                 VARIANT_OBJECT_ACCESS,
                 VARIANT_OBJECT_ACCESS_WITH_NON_LITERAL_KEY,
                 VARIANT_NESTED_ACCESS,

Reply via email to