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

vortex-data / vortex / 16935267080

13 Aug 2025 11:00AM UTC coverage: 24.312% (-63.3%) from 87.658%
16935267080

Pull #4226

github

web-flow
Merge 81b48c7fb into baa6ea202
Pull Request #4226: Support converting TimestampTZ to and from duckdb

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

20666 existing lines in 469 files now uncovered.

8726 of 35892 relevant lines covered (24.31%)

147.74 hits per line

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

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

4
use std::fmt::Display;
5
use std::hash::Hash;
6

7
use vortex_array::compute::invert;
8
use vortex_array::{ArrayRef, DeserializeMetadata, EmptyMetadata};
9
use vortex_dtype::DType;
10
use vortex_error::{VortexResult, vortex_bail};
11

12
use crate::{AnalysisExpr, ExprEncodingRef, ExprId, ExprRef, IntoExpr, Scope, VTable, vtable};
13

14
vtable!(Not);
15

16
#[allow(clippy::derived_hash_with_manual_eq)]
17
#[derive(Clone, Debug, Hash, Eq)]
18
pub struct NotExpr {
19
    child: ExprRef,
20
}
21

22
impl PartialEq for NotExpr {
UNCOV
23
    fn eq(&self, other: &Self) -> bool {
×
UNCOV
24
        self.child.eq(&other.child)
×
UNCOV
25
    }
×
26
}
27

28
pub struct NotExprEncoding;
29

30
impl VTable for NotVTable {
31
    type Expr = NotExpr;
32
    type Encoding = NotExprEncoding;
33
    type Metadata = EmptyMetadata;
34

UNCOV
35
    fn id(_encoding: &Self::Encoding) -> ExprId {
×
UNCOV
36
        ExprId::new_ref("not")
×
UNCOV
37
    }
×
38

UNCOV
39
    fn encoding(_expr: &Self::Expr) -> ExprEncodingRef {
×
UNCOV
40
        ExprEncodingRef::new_ref(NotExprEncoding.as_ref())
×
UNCOV
41
    }
×
42

UNCOV
43
    fn metadata(_expr: &Self::Expr) -> Option<Self::Metadata> {
×
UNCOV
44
        Some(EmptyMetadata)
×
UNCOV
45
    }
×
46

UNCOV
47
    fn children(expr: &Self::Expr) -> Vec<&ExprRef> {
×
UNCOV
48
        vec![&expr.child]
×
UNCOV
49
    }
×
50

51
    fn with_children(_expr: &Self::Expr, children: Vec<ExprRef>) -> VortexResult<Self::Expr> {
×
52
        Ok(NotExpr::new(children[0].clone()))
×
53
    }
×
54

UNCOV
55
    fn build(
×
UNCOV
56
        _encoding: &Self::Encoding,
×
UNCOV
57
        _metadata: &<Self::Metadata as DeserializeMetadata>::Output,
×
UNCOV
58
        children: Vec<ExprRef>,
×
UNCOV
59
    ) -> VortexResult<Self::Expr> {
×
UNCOV
60
        if children.len() != 1 {
×
61
            vortex_bail!(
×
62
                "Not expression expects exactly one child, got {}",
×
63
                children.len()
×
64
            );
UNCOV
65
        }
×
UNCOV
66
        Ok(NotExpr::new(children[0].clone()))
×
UNCOV
67
    }
×
68

UNCOV
69
    fn evaluate(expr: &Self::Expr, scope: &Scope) -> VortexResult<ArrayRef> {
×
UNCOV
70
        let child_result = expr.child.unchecked_evaluate(scope)?;
×
UNCOV
71
        invert(&child_result)
×
UNCOV
72
    }
×
73

UNCOV
74
    fn return_dtype(expr: &Self::Expr, scope: &DType) -> VortexResult<DType> {
×
UNCOV
75
        let child = expr.child.return_dtype(scope)?;
×
UNCOV
76
        if !matches!(child, DType::Bool(_)) {
×
77
            vortex_bail!("Not expression expects a boolean child, got: {}", child);
×
UNCOV
78
        }
×
UNCOV
79
        Ok(child)
×
UNCOV
80
    }
×
81
}
82

83
impl NotExpr {
UNCOV
84
    pub fn new(child: ExprRef) -> Self {
×
UNCOV
85
        Self { child }
×
UNCOV
86
    }
×
87

88
    pub fn new_expr(child: ExprRef) -> ExprRef {
×
89
        Self::new(child).into_expr()
×
90
    }
×
91

92
    pub fn child(&self) -> &ExprRef {
×
93
        &self.child
×
94
    }
×
95
}
96

97
impl Display for NotExpr {
UNCOV
98
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
×
UNCOV
99
        write!(f, "(!{})", self.child)
×
UNCOV
100
    }
×
101
}
102

103
impl AnalysisExpr for NotExpr {}
104

UNCOV
105
pub fn not(operand: ExprRef) -> ExprRef {
×
UNCOV
106
    NotExpr::new(operand).into_expr()
×
UNCOV
107
}
×
108

109
#[cfg(test)]
110
mod tests {
111
    use vortex_array::ToCanonical;
112
    use vortex_array::arrays::BoolArray;
113
    use vortex_dtype::{DType, Nullability};
114

115
    use crate::{Scope, col, get_item, not, root, test_harness};
116

117
    #[test]
118
    fn invert_booleans() {
119
        let not_expr = not(root());
120
        let bools = BoolArray::from_iter([false, true, false, false, true, true]);
121
        assert_eq!(
122
            not_expr
123
                .evaluate(&Scope::new(bools.to_array()))
124
                .unwrap()
125
                .to_bool()
126
                .unwrap()
127
                .boolean_buffer()
128
                .iter()
129
                .collect::<Vec<_>>(),
130
            vec![true, false, true, true, false, false]
131
        );
132
    }
133

134
    #[test]
135
    fn test_display_order_of_operations() {
136
        let a = not(get_item("a", root()));
137
        let b = get_item("a", not(root()));
138
        assert_ne!(a.to_string(), b.to_string());
139
        assert_eq!(a.to_string(), "(!$.a)");
140
        assert_eq!(b.to_string(), "(!$).a");
141
    }
142

143
    #[test]
144
    fn dtype() {
145
        let not_expr = not(root());
146
        let dtype = DType::Bool(Nullability::NonNullable);
147
        assert_eq!(
148
            not_expr.return_dtype(&dtype).unwrap(),
149
            DType::Bool(Nullability::NonNullable)
150
        );
151

152
        let dtype = test_harness::struct_dtype();
153
        assert_eq!(
154
            not(col("bool1")).return_dtype(&dtype).unwrap(),
155
            DType::Bool(Nullability::NonNullable)
156
        );
157
    }
158
}
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