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

vortex-data / vortex / 17073077835

19 Aug 2025 02:40PM UTC coverage: 24.083%. First build
17073077835

Pull #4177

github

web-flow
Merge b42e5758f into 431a8f2b5
Pull Request #4177: feat: ArrayOperations infallible, eager validation + new_unchecked

197 of 1455 new or added lines in 154 files covered. (13.54%)

8646 of 35901 relevant lines covered (24.08%)

142.28 hits per line

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

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

4
use vortex_error::{VortexExpect, VortexResult, vortex_err};
5

6
use crate::traversal::{NodeExt, Transformed};
7
use crate::{DType, ExprRef, MergeVTable, get_item, pack};
8

9
/// Replaces [crate::MergeExpr] with combination of [crate::GetItem] and [crate::Pack] expressions.
10
pub(crate) fn remove_merge(e: ExprRef, ctx: &DType) -> VortexResult<ExprRef> {
14✔
11
    e.transform_up(|node| merge_transform(node, ctx))
48✔
12
        .map(|t| t.into_inner())
14✔
13
}
14✔
14

15
fn merge_transform(node: ExprRef, ctx: &DType) -> VortexResult<Transformed<ExprRef>> {
48✔
16
    match node.as_opt::<MergeVTable>() {
48✔
17
        None => Ok(Transformed::no(node)),
48✔
18
        Some(merge) => {
×
19
            let mut names = Vec::with_capacity(merge.children().len() * 2);
×
20
            let mut children = Vec::with_capacity(merge.children().len() * 2);
×
21
            let mut all_nullable = true;
×
22
            for child in merge.children() {
×
23
                let child_dtype = child.return_dtype(ctx)?;
×
24
                if !child_dtype.is_struct() {
×
25
                    return Err(vortex_err!(
×
26
                        "Merge child must return a non-nullable struct dtype, got {}",
×
27
                        child_dtype
×
28
                    ));
×
29
                }
×
30
                all_nullable = all_nullable && child_dtype.is_nullable();
×
31

NEW
32
                let child_dtype = child_dtype.as_struct_opt().vortex_expect("expected struct");
×
33

34
                for name in child_dtype.names().iter() {
×
35
                    if let Some(idx) = names.iter().position(|n| n == name) {
×
36
                        children[idx] = child.clone();
×
37
                    } else {
×
38
                        names.push(name.clone());
×
39
                        children.push(child.clone());
×
40
                    }
×
41
                }
42
            }
43
            let expr = pack(
×
44
                names
×
45
                    .into_iter()
×
46
                    .zip(children)
×
47
                    .map(|(name, child)| (name.clone(), get_item(name, child))),
×
48
                merge.nullability(),
×
49
            );
50
            Ok(Transformed::yes(expr))
×
51
        }
52
    }
53
}
48✔
54

55
#[cfg(test)]
56
mod tests {
57
    use vortex_dtype::DType;
58
    use vortex_dtype::Nullability::{NonNullable, Nullable};
59
    use vortex_dtype::PType::{I32, I64, U32, U64};
60

61
    use crate::transform::remove_merge::remove_merge;
62
    use crate::{PackVTable, get_item, merge, root};
63

64
    #[test]
65
    fn test_remove_merge() {
66
        let dtype = DType::struct_(
67
            [
68
                ("0", DType::struct_([("a", I32), ("b", I64)], NonNullable)),
69
                ("1", DType::struct_([("b", U32), ("c", U64)], NonNullable)),
70
            ],
71
            NonNullable,
72
        );
73

74
        let e = merge([get_item("0", root()), get_item("1", root())], NonNullable);
75
        let e = remove_merge(e, &dtype).unwrap();
76

77
        assert!(e.is::<PackVTable>());
78
        assert_eq!(
79
            e.return_dtype(&dtype).unwrap(),
80
            DType::struct_([("a", I32), ("b", U32), ("c", U64)], NonNullable)
81
        );
82
    }
83

84
    #[test]
85
    fn test_remove_merge_nullable() {
86
        let dtype = DType::struct_(
87
            [("0", DType::struct_([("a", I32), ("b", I64)], Nullable))],
88
            NonNullable,
89
        );
90

91
        let e = merge([get_item("0", root())], Nullable);
92
        let e = remove_merge(e, &dtype).unwrap();
93

94
        assert!(e.is::<PackVTable>());
95
        assert!(e.return_dtype(&dtype).unwrap().is_nullable());
96
    }
97
}
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