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

vortex-data / vortex / 16473770414

23 Jul 2025 02:38PM UTC coverage: 80.988% (-0.07%) from 81.055%
16473770414

push

github

web-flow
chore[duckdb]: scan log info -> trace (#3989)

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>

1 of 1 new or added line in 1 file covered. (100.0%)

35 existing lines in 7 files now uncovered.

42052 of 51924 relevant lines covered (80.99%)

173623.22 hits per line

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

69.03
/vortex-expr/src/exprs/like.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::{LikeOptions, like};
8
use vortex_array::{ArrayRef, DeserializeMetadata, ProstMetadata};
9
use vortex_dtype::DType;
10
use vortex_error::{VortexResult, vortex_bail};
11
use vortex_proto::expr as pb;
12

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

15
vtable!(Like);
16

17
#[allow(clippy::derived_hash_with_manual_eq)]
18
#[derive(Clone, Debug, Hash)]
19
pub struct LikeExpr {
20
    child: ExprRef,
21
    pattern: ExprRef,
22
    negated: bool,
23
    case_insensitive: bool,
24
}
25

26
impl PartialEq for LikeExpr {
27
    fn eq(&self, other: &Self) -> bool {
323✔
28
        self.child.eq(&other.child)
323✔
29
            && self.pattern.eq(&other.pattern)
323✔
30
            && self.negated == other.negated
323✔
31
            && self.case_insensitive == other.case_insensitive
323✔
32
    }
323✔
33
}
34

35
pub struct LikeExprEncoding;
36

37
impl VTable for LikeVTable {
38
    type Expr = LikeExpr;
39
    type Encoding = LikeExprEncoding;
40
    type Metadata = ProstMetadata<pb::LikeOpts>;
41

42
    fn id(_encoding: &Self::Encoding) -> ExprId {
128✔
43
        ExprId::new_ref("like")
128✔
44
    }
128✔
45

46
    fn encoding(_expr: &Self::Expr) -> ExprEncodingRef {
×
47
        ExprEncodingRef::new_ref(LikeExprEncoding.as_ref())
×
48
    }
×
49

50
    fn metadata(expr: &Self::Expr) -> Option<Self::Metadata> {
×
51
        Some(ProstMetadata(pb::LikeOpts {
×
52
            negated: expr.negated,
×
53
            case_insensitive: expr.case_insensitive,
×
54
        }))
×
55
    }
×
56

57
    fn children(expr: &Self::Expr) -> Vec<&ExprRef> {
1,260✔
58
        vec![&expr.child, &expr.pattern]
1,260✔
59
    }
1,260✔
60

61
    fn with_children(expr: &Self::Expr, children: Vec<ExprRef>) -> VortexResult<Self::Expr> {
105✔
62
        Ok(LikeExpr::new(
105✔
63
            children[0].clone(),
105✔
64
            children[1].clone(),
105✔
65
            expr.negated,
105✔
66
            expr.case_insensitive,
105✔
67
        ))
105✔
68
    }
105✔
69

70
    fn build(
×
71
        _encoding: &Self::Encoding,
×
72
        metadata: &<Self::Metadata as DeserializeMetadata>::Output,
×
73
        children: Vec<ExprRef>,
×
74
    ) -> VortexResult<Self::Expr> {
×
75
        if children.len() != 2 {
×
76
            vortex_bail!(
×
77
                "Like expression must have exactly 2 children, got {}",
×
78
                children.len()
×
79
            );
80
        }
×
81

82
        Ok(LikeExpr::new(
×
83
            children[0].clone(),
×
84
            children[1].clone(),
×
85
            metadata.negated,
×
86
            metadata.case_insensitive,
×
87
        ))
×
88
    }
×
89

90
    fn evaluate(expr: &Self::Expr, scope: &Scope) -> VortexResult<ArrayRef> {
71✔
91
        let child = expr.child().unchecked_evaluate(scope)?;
71✔
92
        let pattern = expr.pattern().unchecked_evaluate(scope)?;
71✔
93
        like(
71✔
94
            &child,
71✔
95
            &pattern,
71✔
96
            LikeOptions {
71✔
97
                negated: expr.negated,
71✔
98
                case_insensitive: expr.case_insensitive,
71✔
99
            },
71✔
100
        )
101
    }
71✔
102

103
    fn return_dtype(expr: &Self::Expr, scope: &DType) -> VortexResult<DType> {
142✔
104
        let input = expr.child().return_dtype(scope)?;
142✔
105
        let pattern = expr.pattern().return_dtype(scope)?;
142✔
106
        Ok(DType::Bool(
107
            (input.is_nullable() || pattern.is_nullable()).into(),
142✔
108
        ))
109
    }
142✔
110
}
111

112
impl LikeExpr {
113
    pub fn new(child: ExprRef, pattern: ExprRef, negated: bool, case_insensitive: bool) -> Self {
141✔
114
        Self {
141✔
115
            child,
141✔
116
            pattern,
141✔
117
            negated,
141✔
118
            case_insensitive,
141✔
119
        }
141✔
120
    }
141✔
121

122
    pub fn new_expr(
23✔
123
        child: ExprRef,
23✔
124
        pattern: ExprRef,
23✔
125
        negated: bool,
23✔
126
        case_insensitive: bool,
23✔
127
    ) -> ExprRef {
23✔
128
        Self::new(child, pattern, negated, case_insensitive).into_expr()
23✔
129
    }
23✔
130

131
    pub fn child(&self) -> &ExprRef {
213✔
132
        &self.child
213✔
133
    }
213✔
134

135
    pub fn pattern(&self) -> &ExprRef {
213✔
136
        &self.pattern
213✔
137
    }
213✔
138

139
    pub fn negated(&self) -> bool {
×
140
        self.negated
×
141
    }
×
142

143
    pub fn case_insensitive(&self) -> bool {
×
144
        self.case_insensitive
×
145
    }
×
146
}
147

148
impl Display for LikeExpr {
UNCOV
149
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
×
UNCOV
150
        write!(f, "{} LIKE {}", self.child(), self.pattern())
×
UNCOV
151
    }
×
152
}
153

154
impl AnalysisExpr for LikeExpr {}
155

156
#[cfg(test)]
157
mod tests {
158
    use vortex_array::ToCanonical;
159
    use vortex_array::arrays::BoolArray;
160
    use vortex_dtype::{DType, Nullability};
161

162
    use crate::{LikeExpr, Scope, lit, not, root};
163

164
    #[test]
165
    fn invert_booleans() {
1✔
166
        let not_expr = not(root());
1✔
167
        let bools = BoolArray::from_iter([false, true, false, false, true, true]);
1✔
168
        assert_eq!(
1✔
169
            not_expr
1✔
170
                .evaluate(&Scope::new(bools.to_array()))
1✔
171
                .unwrap()
1✔
172
                .to_bool()
1✔
173
                .unwrap()
1✔
174
                .boolean_buffer()
1✔
175
                .iter()
1✔
176
                .collect::<Vec<_>>(),
1✔
177
            vec![true, false, true, true, false, false]
1✔
178
        );
179
    }
1✔
180

181
    #[test]
182
    fn dtype() {
1✔
183
        let dtype = DType::Utf8(Nullability::NonNullable);
1✔
184
        let like_expr = LikeExpr::new(root(), lit("%test%"), false, false);
1✔
185
        assert_eq!(
1✔
186
            like_expr.return_dtype(&dtype).unwrap(),
1✔
187
            DType::Bool(Nullability::NonNullable)
188
        );
189
    }
1✔
190
}
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

© 2025 Coveralls, Inc