Skip to content

Commit 060d713

Browse files
authored
Fix: Fuzzer random list scalar generator doesn't introduce nulls into non nullable arrays (#2345)
1 parent 71fbf3e commit 060d713

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

vortex-array/src/array/arbitrary.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ impl<'a> Arbitrary<'a> for Array {
2323
}
2424
}
2525

26+
fn split_number_into_parts(n: usize, parts: usize) -> Vec<usize> {
27+
let reminder = n % parts;
28+
let division = (n - reminder) / parts;
29+
iter::repeat(division)
30+
.take(parts - reminder)
31+
.chain(iter::repeat(division + 1).take(reminder))
32+
.collect()
33+
}
34+
2635
fn random_array(u: &mut Unstructured, dtype: &DType, len: Option<usize>) -> Result<Array> {
2736
let num_chunks = u.int_in_range(1..=3)?;
2837
let chunk_lens = len.map(|l| split_number_into_parts(l, num_chunks));
@@ -86,7 +95,7 @@ fn random_array(u: &mut Unstructured, dtype: &DType, len: Option<usize>) -> Resu
8695
.vortex_unwrap()
8796
.into_array())
8897
}
89-
DType::List(ldt, n) => random_list(u, ldt, n, chunk_len),
98+
DType::List(ldt, n) => random_list(u, ldt, *n, chunk_len),
9099
DType::Extension(..) => {
91100
todo!("Extension arrays are not implemented")
92101
}
@@ -107,7 +116,7 @@ fn random_array(u: &mut Unstructured, dtype: &DType, len: Option<usize>) -> Resu
107116
fn random_list(
108117
u: &mut Unstructured,
109118
ldt: &Arc<DType>,
110-
n: &Nullability,
119+
n: Nullability,
111120
chunk_len: Option<usize>,
112121
) -> Result<Array> {
113122
match u.int_in_range(0..=5)? {
@@ -124,34 +133,33 @@ fn random_list(
124133
fn random_list_offset<O: OffsetPType>(
125134
u: &mut Unstructured,
126135
ldt: &Arc<DType>,
127-
n: &Nullability,
136+
n: Nullability,
128137
chunk_len: Option<usize>,
129138
) -> Result<Array> {
130139
let list_len = chunk_len.unwrap_or(u.int_in_range(0..=20)?);
131-
let mut builder = ListBuilder::<O>::with_capacity(ldt.clone(), *n, 10);
140+
let mut builder = ListBuilder::<O>::with_capacity(ldt.clone(), n, 10);
132141
for _ in 0..list_len {
133-
if matches!(n, Nullability::Nullable) || u.arbitrary::<bool>()? {
134-
let elem_len = u.int_in_range(0..=20)?;
135-
let elem = (0..elem_len)
136-
.map(|_| random_scalar(u, ldt))
137-
.collect::<Result<Vec<_>>>()?;
142+
if n == Nullability::Nullable && u.arbitrary::<bool>()? {
143+
builder.append_null();
144+
} else {
138145
builder
139-
.append_value(Scalar::list(ldt.clone(), elem, *n).as_list())
146+
.append_value(random_list_scalar(u, ldt, n)?.as_list())
140147
.vortex_expect("can append value");
141-
} else {
142-
builder.append_null();
143148
}
144149
}
145150
Ok(builder.finish().vortex_expect("builder cannot error"))
146151
}
147152

148-
fn split_number_into_parts(n: usize, parts: usize) -> Vec<usize> {
149-
let reminder = n % parts;
150-
let division = (n - reminder) / parts;
151-
iter::repeat(division)
152-
.take(parts - reminder)
153-
.chain(iter::repeat(division + 1).take(reminder))
154-
.collect()
153+
fn random_list_scalar(
154+
u: &mut Unstructured,
155+
elem_dtype: &Arc<DType>,
156+
n: Nullability,
157+
) -> Result<Scalar> {
158+
let elem_len = u.int_in_range(0..=20)?;
159+
let elems = (0..elem_len)
160+
.map(|_| random_scalar(u, elem_dtype))
161+
.collect::<Result<Vec<_>>>()?;
162+
Ok(Scalar::list(elem_dtype.clone(), elems, n))
155163
}
156164

157165
fn random_string(

0 commit comments

Comments
 (0)