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

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

commit 3193e71ae5dd5e0128ff8ffde3a6329e98af4d8d
Author: Ramin Gharib <[email protected]>
AuthorDate: Mon Sep 28 11:26:36 2026 +0200

    [FLINK-40825][table] Keep a stored NaN or infinity when casting VARIANT to 
FLOAT or DOUBLE
    
    Casting a VARIANT to FLOAT or DOUBLE rejected every non-finite result as an 
overflow, so a VARIANT holding NaN or infinity, for example one read by the 
Avro converter, could not be read back. The FLOAT cast now rejects only a 
finite value that does not fit, such as 1e40, and keeps a stored NaN or 
infinity. The DOUBLE cast needs no check, since every numeric kind fits a 
double.
---
 .../planner/functions/casting/CastRulesTest.java      | 11 +++++++++++
 .../table/runtime/functions/VariantCastUtils.java     | 19 ++++++++++---------
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/casting/CastRulesTest.java
 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/casting/CastRulesTest.java
index c560e8d1f82..cfe2b641bfd 100644
--- 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/casting/CastRulesTest.java
+++ 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/casting/CastRulesTest.java
@@ -1998,11 +1998,22 @@ class CastRulesTest {
                                 VARIANT(), VARIANT_BUILDER.of(new 
BigDecimal("123.456")), 123.456f)
                         // a magnitude a FLOAT cannot represent is still 
rejected
                         .fail(VARIANT(), VARIANT_BUILDER.of(1e40d), 
TableRuntimeException.class)
+                        // a stored NaN or infinity is not an overflow and is 
kept
+                        .fromCase(VARIANT(), VARIANT_BUILDER.of(Double.NaN), 
Float.NaN)
+                        .fromCase(
+                                VARIANT(),
+                                VARIANT_BUILDER.of(Double.POSITIVE_INFINITY),
+                                Float.POSITIVE_INFINITY)
                         .fail(VARIANT(), VARIANT_BUILDER.of("x"), 
TableRuntimeException.class),
                 CastTestSpecBuilder.testCastTo(DOUBLE())
                         .fromCase(VARIANT(), VARIANT_BUILDER.of(1.5d), 1.5d)
                         .fromCase(VARIANT(), VARIANT_BUILDER.of(1.5f), 1.5d)
                         .fromCase(VARIANT(), VARIANT_BUILDER.of(3), 3.0d)
+                        .fromCase(VARIANT(), VARIANT_BUILDER.of(Double.NaN), 
Double.NaN)
+                        .fromCase(
+                                VARIANT(),
+                                VARIANT_BUILDER.of(Float.NEGATIVE_INFINITY),
+                                Double.NEGATIVE_INFINITY)
                         .fromCase(
                                 VARIANT(), VARIANT_BUILDER.of(new 
BigDecimal("123.456")), 123.456d)
                         .fail(VARIANT(), VARIANT_BUILDER.of("x"), 
TableRuntimeException.class),
diff --git 
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/VariantCastUtils.java
 
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/VariantCastUtils.java
index 9a7ef8b4915..9f2deeb71d4 100644
--- 
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/VariantCastUtils.java
+++ 
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/VariantCastUtils.java
@@ -177,23 +177,24 @@ public final class VariantCastUtils {
 
     /**
      * Reads any numeric variant as a {@code float}. Dropping decimal digits 
is expected of an
-     * approximate type, but a magnitude outside the {@code FLOAT} range is 
rejected.
+     * approximate type, but a finite magnitude outside the {@code FLOAT} 
range is rejected. A
+     * stored {@code NaN} or infinity is kept as is.
      */
     public static float toFloat(Variant variant) {
-        final float value = numeric(variant, "FLOAT").floatValue();
-        if (!Float.isFinite(value)) {
+        final Number number = numeric(variant, "FLOAT");
+        final float value = number.floatValue();
+        if (!Float.isFinite(value) && Double.isFinite(number.doubleValue())) {
             throw overflow(variant.get(), "FLOAT");
         }
         return value;
     }
 
-    /** Reads any numeric variant as a {@code double}. See {@link 
#toFloat(Variant)}. */
+    /**
+     * Reads any numeric variant as a {@code double}. Every numeric kind fits 
the {@code DOUBLE}
+     * range, so only decimal digits can be dropped, and a stored {@code NaN} 
or infinity is kept.
+     */
     public static double toDouble(Variant variant) {
-        final double value = numeric(variant, "DOUBLE").doubleValue();
-        if (!Double.isFinite(value)) {
-            throw overflow(variant.get(), "DOUBLE");
-        }
-        return value;
+        return numeric(variant, "DOUBLE").doubleValue();
     }
 
     /**

Reply via email to