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

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


The following commit(s) were added to refs/heads/master by this push:
     new d4abbe5e0ea [fix](cast) Compare fractional literal values in their own 
precision when casting to BOOLEAN (#68729)
d4abbe5e0ea is described below

commit d4abbe5e0eaa6b80651fe7abc8cd3862085e4ad5
Author: Abhinav <[email protected]>
AuthorDate: Fri Oct 9 17:14:28 2026 +0530

    [fix](cast) Compare fractional literal values in their own precision when 
casting to BOOLEAN (#68729)
    
    ### What problem does this PR solve?
    
    Issue Number: close #68714
    
    Problem Summary:
    
    `FractionalLiteral.uncheckedCastTo(BooleanType)` tested the value with
    `((Number) value).floatValue() == 0`. For a `DOUBLE` literal, narrowing
    to `float` first
    flushes every magnitude below the float32 rounding limit (about `7e-46`,
    i.e. half the
    smallest positive float32 subnormal) to `0.0f`, so a nonzero double
    folded to `FALSE`:
    
    ```sql
    SELECT CAST(5e-324 AS BOOLEAN);   -- FE fold: FALSE
    SELECT IF(1e-300, 't', 'f');      -- FE fold: f
    ```
    
    The same value read from a column goes through BE, where
    `be/src/exprs/function/cast/cast_to_boolean.h` compares the original
    `Float64` against zero
    and returns `TRUE`. So a constant expression and a column expression
    disagreed, and a
    constant `WHERE` predicate built from such a literal could drop every
    row.
    
    The fix compares in the value's own precision, `doubleValue() == 0`.
    Widening `float` to
    `double` is exact, so the `FloatLiteral` path keeps its previous
    behaviour; only the `DOUBLE`
    path changes, which is the one that was wrong. `NaN` and both infinities
    still fold to
    `TRUE` as before, which is what the existing assertions in
    `DoubleLiteralTest` require.
    
    
    Co-authored-by: abhinav-phi <[email protected]>
---
 .../nereids/trees/expressions/literal/FractionalLiteral.java |  2 +-
 .../nereids/trees/expressions/literal/DoubleLiteralTest.java | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/FractionalLiteral.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/FractionalLiteral.java
index 8a5b830375f..18350578891 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/FractionalLiteral.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/FractionalLiteral.java
@@ -89,7 +89,7 @@ public abstract class FractionalLiteral extends 
NumericLiteral {
         } else if (targetType.isBooleanType()) {
             Object value = getValue();
             if (value instanceof Float || value instanceof Double) {
-                if (((Number) value).floatValue() == 0) {
+                if (((Number) value).doubleValue() == 0) {
                     return BooleanLiteral.FALSE;
                 } else {
                     return BooleanLiteral.TRUE;
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/DoubleLiteralTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/DoubleLiteralTest.java
index 85cd94955e3..8aae87bd8fc 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/DoubleLiteralTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/DoubleLiteralTest.java
@@ -56,6 +56,18 @@ class DoubleLiteralTest {
         f1 = new DoubleLiteral(Double.POSITIVE_INFINITY);
         Assertions.assertTrue(((BooleanLiteral) 
f1.uncheckedCastTo(BooleanType.INSTANCE)).getValue());
 
+        // nonzero doubles that round to zero when narrowed to float must 
still be TRUE
+        f1 = new DoubleLiteral(Double.MIN_VALUE);
+        Assertions.assertTrue(((BooleanLiteral) 
f1.uncheckedCastTo(BooleanType.INSTANCE)).getValue());
+        f1 = new DoubleLiteral(-Double.MIN_VALUE);
+        Assertions.assertTrue(((BooleanLiteral) 
f1.uncheckedCastTo(BooleanType.INSTANCE)).getValue());
+        f1 = new DoubleLiteral(1e-300);
+        Assertions.assertTrue(((BooleanLiteral) 
f1.uncheckedCastTo(BooleanType.INSTANCE)).getValue());
+        f1 = new DoubleLiteral(1e-46);
+        Assertions.assertTrue(((BooleanLiteral) 
f1.uncheckedCastTo(BooleanType.INSTANCE)).getValue());
+        f1 = new DoubleLiteral(5e-324);
+        Assertions.assertTrue(((BooleanLiteral) 
f1.uncheckedCastTo(BooleanType.INSTANCE)).getValue());
+
         // To integral
         f1 = new DoubleLiteral(12.999);
         Expression expression = f1.uncheckedCastTo(TinyIntType.INSTANCE);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to