Skip to content

Commit 84b2f96

Browse files
fix[array]: min_max of nan is none constant array (#5200)
Signed-off-by: Joe Isaacs <[email protected]>
1 parent 6a54fbe commit 84b2f96

File tree

5 files changed

+37
-4
lines changed

5 files changed

+37
-4
lines changed

fuzz/fuzz_targets/array_ops.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::backtrace::Backtrace;
88

99
use libfuzzer_sys::{Corpus, fuzz_target};
1010
use vortex_array::arrays::ConstantArray;
11-
use vortex_array::compute::{cast, compare, fill_null, filter, min_max, sum, take};
11+
use vortex_array::compute::{cast, compare, fill_null, filter, mask, min_max, sum, take};
1212
use vortex_array::search_sorted::{SearchResult, SearchSorted, SearchSortedSide};
1313
use vortex_array::{Array, ArrayRef, IntoArray};
1414
use vortex_btrblocks::BtrBlocksCompressor;
@@ -99,7 +99,6 @@ fuzz_target!(|fuzz_action: FuzzArrayAction| -> Corpus {
9999
assert_array_eq(&expected.array(), &current_array, i).unwrap();
100100
}
101101
Action::Mask(mask_val) => {
102-
use vortex_array::compute::mask;
103102
current_array = mask(&current_array, &mask_val).vortex_unwrap();
104103
assert_array_eq(&expected.array(), &current_array, i).unwrap();
105104
}

vortex-array/src/arrays/constant/compute/min_max.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::register_kernel;
1010
impl MinMaxKernel for ConstantVTable {
1111
fn min_max(&self, array: &ConstantArray) -> VortexResult<Option<MinMaxResult>> {
1212
let scalar = array.scalar();
13-
if scalar.is_null() {
13+
if scalar.is_null() || scalar.as_primitive_opt().is_some_and(|p| p.is_nan()) {
1414
return Ok(None);
1515
}
1616
let non_nullable_dtype = scalar.dtype().as_nonnullable();
@@ -22,3 +22,21 @@ impl MinMaxKernel for ConstantVTable {
2222
}
2323

2424
register_kernel!(MinMaxKernelAdapter(ConstantVTable).lift());
25+
26+
#[cfg(test)]
27+
mod test {
28+
use vortex_dtype::Nullability;
29+
use vortex_dtype::half::f16;
30+
use vortex_scalar::Scalar;
31+
32+
use crate::arrays::ConstantArray;
33+
use crate::compute::min_max;
34+
35+
#[test]
36+
fn test_min_max_nan() {
37+
let scalar = Scalar::primitive(f16::NAN, Nullability::NonNullable);
38+
let array = ConstantArray::new(scalar, 2).to_array();
39+
let result = min_max(&array).unwrap();
40+
assert_eq!(result, None);
41+
}
42+
}

vortex-array/src/compute/min_max.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ fn min_max_impl(
178178
vortex_bail!(NotImplemented: "min_max", array.encoding_id());
179179
}
180180

181-
/// The minimum and maximum non-null values of an array, or None if there are no non-null values.
181+
/// The minimum and maximum non-null values of an array, or None if there are no non-null/or non-nan
182+
/// values.
182183
pub trait MinMaxKernel: VTable {
183184
fn min_max(&self, array: &Self::Array) -> VortexResult<Option<MinMaxResult>>;
184185
}

vortex-scalar/src/primitive.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ impl<'a> PrimitiveScalar<'a> {
133133
}))
134134
}
135135

136+
/// Returns true if the scalar is nan.
137+
pub fn is_nan(&self) -> bool {
138+
self.pvalue.as_ref().is_some_and(|p| p.is_nan())
139+
}
140+
136141
/// Attempts to extract the primitive value as the given type.
137142
///
138143
/// # Errors

vortex-scalar/src/pvalue.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,16 @@ impl PValue {
196196
}
197197
}
198198

199+
/// Returns true if the value of float type and is NaN.
200+
pub fn is_nan(&self) -> bool {
201+
match self {
202+
PValue::F16(f) => f.is_nan(),
203+
PValue::F32(f) => f.is_nan(),
204+
PValue::F64(f) => f.is_nan(),
205+
_ => false,
206+
}
207+
}
208+
199209
/// Reinterprets the bits of this value as a different primitive type.
200210
///
201211
/// This performs a bitwise cast between types of the same width.

0 commit comments

Comments
 (0)