You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by ar...@apache.org on 2026/10/02 05:46:57 UTC
(flink) 01/02: [FLINK-40825][table] Keep a stored NaN or infinity when casting VARIANT to FLOAT or DOUBLE
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 <ra...@gmail.com>
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();
}
/**