Skip to content

Commit 945ece9

Browse files
author
Devanshu
committed
Cover corner case for float
1 parent 5d4887b commit 945ece9

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

datafusion/functions/src/math/floor.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,22 @@ impl ScalarUDFImpl for FloorFunc {
281281

282282
/// Compute preimage bounds for floor function on floating-point types.
283283
/// For floor(x) = n, the preimage is [n, n+1).
284-
/// Returns None if the value is non-finite or would lose precision.
284+
/// Returns None if:
285+
/// - The value is non-finite (infinity, NaN)
286+
/// - The value is not an integer (floor always returns integers, so floor(x) = 1.3 has no solution)
287+
/// - Adding 1 would lose precision at extreme values
285288
fn float_preimage_bounds<F: Float>(n: F) -> Option<(F, F)> {
286289
let one = F::one();
287-
// Check for non-finite values (infinity, NaN) or precision loss at extreme values
288-
if !n.is_finite() || n + one <= n {
290+
// Check for non-finite values (infinity, NaN)
291+
if !n.is_finite() {
292+
return None;
293+
}
294+
// floor always returns an integer, so if n has a fractional part, there's no solution
295+
if n.fract() != F::zero() {
296+
return None;
297+
}
298+
// Check for precision loss at extreme values
299+
if n + one <= n {
289300
return None;
290301
}
291302
Some((n, n + one))
@@ -383,6 +394,15 @@ mod tests {
383394
);
384395
}
385396

397+
#[test]
398+
fn test_floor_preimage_non_integer_float() {
399+
// floor(x) = 1.3 has NO SOLUTION because floor always returns an integer
400+
// Therefore preimage should return None for non-integer literals
401+
assert_preimage_none(ScalarValue::Float64(Some(1.3)));
402+
assert_preimage_none(ScalarValue::Float64(Some(-2.5)));
403+
assert_preimage_none(ScalarValue::Float32(Some(3.14)));
404+
}
405+
386406
#[test]
387407
fn test_floor_preimage_integer_overflow() {
388408
// All integer types at MAX value should return None

0 commit comments

Comments
 (0)