This is an automated email from the ASF dual-hosted git repository.
mbudiu 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 b6e1a9deb2 [CALCITE-6395] Significant precision loss when representing
REAL literals
b6e1a9deb2 is described below
commit b6e1a9deb2664236d06df85de31a60c02a85aea5
Author: Mihai Budiu <[email protected]>
AuthorDate: Wed May 8 13:32:37 2024 -0700
[CALCITE-6395] Significant precision loss when representing REAL literals
Signed-off-by: Mihai Budiu <[email protected]>
---
core/src/main/java/org/apache/calcite/rex/RexBuilder.java | 5 -----
.../main/java/org/apache/calcite/runtime/SqlFunctions.java | 12 ++----------
.../test/java/org/apache/calcite/test/SqlFunctionsTest.java | 8 ++++----
.../main/java/org/apache/calcite/test/SqlOperatorTest.java | 10 +++++++++-
4 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
index f508b501fb..341759f57b 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -1887,11 +1887,6 @@ public class RexBuilder {
type.getSqlTypeName());
return new BigDecimal(((Number) o).longValue());
case REAL:
- if (o instanceof BigDecimal) {
- return o;
- }
- return new BigDecimal(((Number) o).doubleValue(), MathContext.DECIMAL32)
- .stripTrailingZeros();
case FLOAT:
case DOUBLE:
if (o instanceof BigDecimal) {
diff --git a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
index 8fbdfb11a4..37c70e7fe0 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -205,8 +205,6 @@ public class SqlFunctions {
private static final ThreadLocal<@Nullable Map<String, AtomicLong>>
THREAD_SEQUENCES =
ThreadLocal.withInitial(HashMap::new);
- private static final Pattern PATTERN_0_STAR_E = Pattern.compile("0*E");
-
/** A byte string consisting of a single byte that is the ASCII space
* character (0x20). */
private static final ByteString SINGLE_SPACE_BYTE_STRING =
@@ -3513,10 +3511,7 @@ public class SqlFunctions {
if (x == 0) {
return "0E0";
}
- BigDecimal bigDecimal =
- new BigDecimal(x, MathContext.DECIMAL32).stripTrailingZeros();
- final String s = bigDecimal.toString();
- return PATTERN_0_STAR_E.matcher(s).replaceAll("E").replace("E+", "E");
+ return Float.toString(x);
}
/** CAST(DOUBLE AS VARCHAR). */
@@ -3524,10 +3519,7 @@ public class SqlFunctions {
if (x == 0) {
return "0E0";
}
- BigDecimal bigDecimal =
- new BigDecimal(x, MathContext.DECIMAL64).stripTrailingZeros();
- final String s = bigDecimal.toString();
- return PATTERN_0_STAR_E.matcher(s).replaceAll("E").replace("E+", "E");
+ return Double.toString(x);
}
/** CAST(DECIMAL AS VARCHAR). */
diff --git a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
index 5543032c0e..00e057f0d5 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
@@ -132,22 +132,22 @@ class SqlFunctionsTest {
@Test void testToString() {
assertThat(SqlFunctions.toString(0f), is("0E0"));
- assertThat(SqlFunctions.toString(1f), is("1"));
+ assertThat(SqlFunctions.toString(1f), is("1.0"));
assertThat(SqlFunctions.toString(1.5f), is("1.5"));
assertThat(SqlFunctions.toString(-1.5f), is("-1.5"));
assertThat(SqlFunctions.toString(1.5e8f), is("1.5E8"));
assertThat(SqlFunctions.toString(-0.0625f), is("-0.0625"));
assertThat(SqlFunctions.toString(0.0625f), is("0.0625"));
- assertThat(SqlFunctions.toString(-5e-12f), is("-5E-12"));
+ assertThat(SqlFunctions.toString(-5e-12f), is("-5.0E-12"));
assertThat(SqlFunctions.toString(0d), is("0E0"));
- assertThat(SqlFunctions.toString(1d), is("1"));
+ assertThat(SqlFunctions.toString(1d), is("1.0"));
assertThat(SqlFunctions.toString(1.5d), is("1.5"));
assertThat(SqlFunctions.toString(-1.5d), is("-1.5"));
assertThat(SqlFunctions.toString(1.5e8d), is("1.5E8"));
assertThat(SqlFunctions.toString(-0.0625d), is("-0.0625"));
assertThat(SqlFunctions.toString(0.0625d), is("0.0625"));
- assertThat(SqlFunctions.toString(-5e-12d), is("-5E-12"));
+ assertThat(SqlFunctions.toString(-5e-12d), is("-5.0E-12"));
assertThat(SqlFunctions.toString(new BigDecimal("0")), is("0"));
assertThat(SqlFunctions.toString(new BigDecimal("1")), is("1"));
diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
index a7aa550e6f..05ced8e994 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -523,7 +523,7 @@ public class SqlOperatorTest {
}
f.checkString("cast(1.3243232e0 as varchar(4))", "1.32",
"VARCHAR(4) NOT NULL");
- f.checkString("cast(1.9e5 as char(4))", "1.9E", "CHAR(4) NOT NULL");
+ f.checkString("cast(1.9e5 as char(4))", "1900", "CHAR(4) NOT NULL");
// string
f.checkCastToString("'abc'", "CHAR(1)", "a", castType);
@@ -665,6 +665,14 @@ public class SqlOperatorTest {
});
}
+ /** Test case for <a
href="https://issues.apache.org/jira/browse/CALCITE-6395">
+ * [CALCITE-6395] Significant precision loss when representing REAL
literals</a>. */
+ @Test public void floatPrecisionTest() {
+ SqlOperatorFixture f = fixture();
+ f.checkScalar("CAST(CAST('36854775807.0' AS REAL) AS BIGINT)",
+ "36854775808", "BIGINT NOT NULL");
+ }
+
@ParameterizedTest
@MethodSource("safeParameters")
void testCastToExactNumeric(CastType castType, SqlOperatorFixture f) {