• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vortex-data / vortex / 16276097554

14 Jul 2025 07:33PM UTC coverage: 81.533% (-0.004%) from 81.537%
16276097554

push

github

web-flow
fix: Fuzzer does not generate filter on struct (#3873)

Fix the fuzzer to not try and generate compare ops for struct fields.

Also, changes the fuzzer to generate simpler names for struct fields.
Right now you just end up with annoying random names like `==` or
`========`, reading a large fuzz trace is much easier if you have simple
monotonic names.

---------

Signed-off-by: Andrew Duffy <andrew@a10y.dev>

0 of 7 new or added lines in 1 file covered. (0.0%)

46270 of 56750 relevant lines covered (81.53%)

146757.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/vortex-expr/src/arbitrary.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
use std::cmp::max;
5

6
use arbitrary::{Result as AResult, Unstructured};
7
use vortex_dtype::{DType, FieldName};
8
use vortex_scalar::arbitrary::random_scalar;
9

10
use crate::{BinaryExpr, ExprRef, Operator, and_collect, get_item_scope, lit, pack};
11

12
pub fn projection_expr(u: &mut Unstructured<'_>, dtype: &DType) -> AResult<Option<ExprRef>> {
×
13
    let Some(struct_dtype) = dtype.as_struct() else {
×
14
        return Ok(None);
×
15
    };
16

17
    let column_count = u.int_in_range::<usize>(0..=max(struct_dtype.nfields(), 10))?;
×
18

19
    let cols = (0..column_count)
×
20
        .map(|_| {
×
21
            let get_item = u.choose_iter(struct_dtype.names().iter())?;
×
22
            Ok((get_item.clone(), get_item_scope(get_item.clone())))
×
23
        })
×
24
        .collect::<AResult<Vec<_>>>()?;
×
25

26
    Ok(Some(pack(cols, u.arbitrary()?)))
×
27
}
×
28

29
pub fn filter_expr(u: &mut Unstructured<'_>, dtype: &DType) -> AResult<Option<ExprRef>> {
×
30
    let Some(struct_dtype) = dtype.as_struct() else {
×
31
        return Ok(None);
×
32
    };
33

34
    let filter_count = u.int_in_range::<usize>(0..=max(struct_dtype.nfields(), 10))?;
×
35

36
    let filters = (0..filter_count)
×
NEW
37
        .filter_map(|_| {
×
NEW
38
            match u.choose_iter(struct_dtype.names().iter().zip(struct_dtype.fields())) {
×
NEW
39
                Ok((col, dtype)) => {
×
NEW
40
                    if dtype.is_struct() {
×
NEW
41
                        None
×
42
                    } else {
NEW
43
                        Some(random_comparison(u, col, &dtype))
×
44
                    }
45
                }
NEW
46
                Err(e) => Some(Err(e)),
×
47
            }
48
        })
×
49
        .collect::<AResult<Vec<_>>>()?;
×
50

51
    Ok(and_collect(filters))
×
52
}
×
53

54
fn random_comparison(u: &mut Unstructured<'_>, col: &FieldName, dtype: &DType) -> AResult<ExprRef> {
×
55
    let scalar = random_scalar(u, dtype)?;
×
56
    Ok(BinaryExpr::new_expr(
57
        get_item_scope(col.clone()),
×
58
        arbitrary_comparison_operator(u)?,
×
59
        lit(scalar),
×
60
    ))
61
}
×
62

63
fn arbitrary_comparison_operator(u: &mut Unstructured<'_>) -> AResult<Operator> {
×
64
    Ok(match u.int_in_range(0..=5)? {
×
65
        0 => Operator::Eq,
×
66
        1 => Operator::NotEq,
×
67
        2 => Operator::Gt,
×
68
        3 => Operator::Gte,
×
69
        4 => Operator::Lt,
×
70
        5 => Operator::Lte,
×
71
        _ => unreachable!("range 0..=5"),
×
72
    })
73
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc