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) {

Reply via email to