This is an automated email from the ASF dual-hosted git repository.
xuzifu666 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new bbd083fd6b [CALCITE-7432] NumberFormatException when convert `NaN`
literal to sql
bbd083fd6b is described below
commit bbd083fd6b0e55f3a13c142626adf03ffe0eb5e1
Author: krooswu <[email protected]>
AuthorDate: Sat Mar 14 21:56:09 2026 +0800
[CALCITE-7432] NumberFormatException when convert `NaN` literal to sql
---
.../apache/calcite/rel/rel2sql/SqlImplementor.java | 14 +++++++--
.../calcite/rel/rel2sql/RelToSqlConverterTest.java | 34 ++++++++++++++++++++++
2 files changed, 46 insertions(+), 2 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
index dec24ca1f2..410cc5ea33 100644
--- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
+++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
@@ -66,8 +66,10 @@
import org.apache.calcite.sql.JoinType;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlBasicTypeNameSpec;
import org.apache.calcite.sql.SqlBinaryOperator;
import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlDataTypeSpec;
import org.apache.calcite.sql.SqlDialect;
import org.apache.calcite.sql.SqlDynamicParam;
import org.apache.calcite.sql.SqlIdentifier;
@@ -1536,8 +1538,16 @@ public static SqlNode toSql(RexLiteral literal) {
case NUMERIC:
case EXACT_NUMERIC: {
if (SqlTypeName.APPROX_TYPES.contains(typeName)) {
- return SqlLiteral.createApproxNumeric(
- castNonNull(literal.getValueAs(Double.class)).toString(), POS);
+ final Double d = castNonNull(literal.getValueAs(Double.class));
+ // BigDecimal cannot represent IEEE 754 special values (NaN,
±Infinity).
+ if (!Double.isFinite(d)) {
+ final SqlNode strLiteral =
+ SqlLiteral.createCharString(d.toString(), POS);
+ final SqlDataTypeSpec typeSpec =
+ new SqlDataTypeSpec(new SqlBasicTypeNameSpec(typeName, POS),
POS);
+ return SqlStdOperatorTable.CAST.createCall(POS, strLiteral,
typeSpec);
+ }
+ return SqlLiteral.createApproxNumeric(d.toString(), POS);
} else {
return SqlLiteral.createExactNumeric(
castNonNull(literal.getValueAs(BigDecimal.class)).toPlainString(),
POS);
diff --git
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index 4105431220..2deca5f9d8 100644
---
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -11913,5 +11913,39 @@ public Sql schema(CalciteAssert.SchemaSpec schemaSpec)
{
.schema(CalciteAssert.SchemaSpec.JDBC_SCOTT)
.ok(expected2);
}
+ /**
+ * Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-7432">[CALCITE-7432]
+ * NumberFormatException when convert `NaN` literal to sql</a>.
+ *
+ * <p>Tests support for all IEEE 754 floating-point special values:
+ * NaN, positive/negative infinity, signed zero, and subnormal values.
+ */
+ @Test void testCastFloatingPointSpecialValuesToDouble() {
+ // Test NaN
+ sql("select cast('NaN' as DOUBLE)")
+ .ok("SELECT *\n"
+ + "FROM (VALUES (CAST('NaN' AS DOUBLE))) AS \"t\" (\"EXPR$0\")");
+
+ // Test Positive Infinity
+ sql("select cast('Infinity' as DOUBLE)")
+ .ok("SELECT *\n"
+ + "FROM (VALUES (CAST('Infinity' AS DOUBLE))) AS \"t\"
(\"EXPR$0\")");
+
+ // Test Negative Infinity
+ sql("select cast('-Infinity' as DOUBLE)")
+ .ok("SELECT *\n"
+ + "FROM (VALUES (CAST('-Infinity' AS DOUBLE))) AS \"t\"
(\"EXPR$0\")");
+
+ // Test Negative Zero
+ sql("select cast('-0.0' as DOUBLE)")
+ .ok("SELECT *\n"
+ + "FROM (VALUES (0E0)) AS \"t\" (\"EXPR$0\")");
+
+ // Test Subnormal values
+ sql("select cast('1e-310' as DOUBLE)")
+ .ok("SELECT *\n"
+ + "FROM (VALUES (1.0E-310)) AS \"t\" (\"EXPR$0\")");
+ }
}