• 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/between.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
use std::fmt::{Debug, Display};
5

6
use vortex_array::compute::{BetweenOptions, StrictComparison, between as between_compute};
7
use vortex_array::{ArrayRef, DeserializeMetadata, ProstMetadata};
8
use vortex_dtype::DType;
9
use vortex_dtype::DType::Bool;
10
use vortex_error::{VortexResult, vortex_bail};
11
use vortex_proto::expr as pb;
12

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

17
vtable!(Between);
18

19
#[allow(clippy::derived_hash_with_manual_eq)]
20
#[derive(Clone, Debug, Hash, Eq)]
21
pub struct BetweenExpr {
22
    arr: ExprRef,
23
    lower: ExprRef,
24
    upper: ExprRef,
25
    options: BetweenOptions,
26
}
27

28
impl PartialEq for BetweenExpr {
UNCOV
29
    fn eq(&self, other: &Self) -> bool {
×
UNCOV
30
        self.arr.eq(&other.arr)
×
UNCOV
31
            && self.lower.eq(&other.lower)
×
UNCOV
32
            && self.upper.eq(&other.upper)
×
UNCOV
33
            && self.options == other.options
×
UNCOV
34
    }
×
35
}
36

37
pub struct BetweenExprEncoding;
38

39
impl VTable for BetweenVTable {
40
    type Expr = BetweenExpr;
41
    type Encoding = BetweenExprEncoding;
42
    type Metadata = ProstMetadata<pb::BetweenOpts>;
43

UNCOV
44
    fn id(_encoding: &Self::Encoding) -> ExprId {
×
UNCOV
45
        ExprId::new_ref("between")
×
UNCOV
46
    }
×
47

UNCOV
48
    fn encoding(_expr: &Self::Expr) -> ExprEncodingRef {
×
UNCOV
49
        ExprEncodingRef::new_ref(BetweenExprEncoding.as_ref())
×
UNCOV
50
    }
×
51

UNCOV
52
    fn metadata(expr: &Self::Expr) -> Option<Self::Metadata> {
×
UNCOV
53
        Some(ProstMetadata(pb::BetweenOpts {
×
UNCOV
54
            lower_strict: expr.options.lower_strict == StrictComparison::Strict,
×
UNCOV
55
            upper_strict: expr.options.upper_strict == StrictComparison::Strict,
×
UNCOV
56
        }))
×
UNCOV
57
    }
×
58

UNCOV
59
    fn children(expr: &Self::Expr) -> Vec<&ExprRef> {
×
UNCOV
60
        vec![&expr.arr, &expr.lower, &expr.upper]
×
UNCOV
61
    }
×
62

UNCOV
63
    fn with_children(expr: &Self::Expr, children: Vec<ExprRef>) -> VortexResult<Self::Expr> {
×
UNCOV
64
        Ok(BetweenExpr::new(
×
UNCOV
65
            children[0].clone(),
×
UNCOV
66
            children[1].clone(),
×
UNCOV
67
            children[2].clone(),
×
UNCOV
68
            expr.options.clone(),
×
UNCOV
69
        ))
×
UNCOV
70
    }
×
71

UNCOV
72
    fn build(
×
UNCOV
73
        _encoding: &Self::Encoding,
×
UNCOV
74
        metadata: &<Self::Metadata as DeserializeMetadata>::Output,
×
UNCOV
75
        children: Vec<ExprRef>,
×
UNCOV
76
    ) -> VortexResult<Self::Expr> {
×
UNCOV
77
        Ok(BetweenExpr::new(
×
UNCOV
78
            children[0].clone(),
×
UNCOV
79
            children[1].clone(),
×
UNCOV
80
            children[2].clone(),
×
81
            BetweenOptions {
UNCOV
82
                lower_strict: if metadata.lower_strict {
×
UNCOV
83
                    StrictComparison::Strict
×
84
                } else {
UNCOV
85
                    StrictComparison::NonStrict
×
86
                },
UNCOV
87
                upper_strict: if metadata.upper_strict {
×
UNCOV
88
                    StrictComparison::Strict
×
89
                } else {
UNCOV
90
                    StrictComparison::NonStrict
×
91
                },
92
            },
93
        ))
UNCOV
94
    }
×
95

UNCOV
96
    fn evaluate(expr: &Self::Expr, scope: &Scope) -> VortexResult<ArrayRef> {
×
UNCOV
97
        let arr_val = expr.arr.unchecked_evaluate(scope)?;
×
UNCOV
98
        let lower_arr_val = expr.lower.unchecked_evaluate(scope)?;
×
UNCOV
99
        let upper_arr_val = expr.upper.unchecked_evaluate(scope)?;
×
100

UNCOV
101
        between_compute(&arr_val, &lower_arr_val, &upper_arr_val, &expr.options)
×
UNCOV
102
    }
×
103

UNCOV
104
    fn return_dtype(expr: &Self::Expr, scope: &DType) -> VortexResult<DType> {
×
UNCOV
105
        let arr_dt = expr.arr.return_dtype(scope)?;
×
UNCOV
106
        let lower_dt = expr.lower.return_dtype(scope)?;
×
UNCOV
107
        let upper_dt = expr.upper.return_dtype(scope)?;
×
108

UNCOV
109
        if !arr_dt.eq_ignore_nullability(&lower_dt) {
×
110
            vortex_bail!(
×
111
                "Array dtype {} does not match lower dtype {}",
×
112
                arr_dt,
113
                lower_dt
114
            );
UNCOV
115
        }
×
UNCOV
116
        if !arr_dt.eq_ignore_nullability(&upper_dt) {
×
117
            vortex_bail!(
×
118
                "Array dtype {} does not match upper dtype {}",
×
119
                arr_dt,
120
                upper_dt
121
            );
UNCOV
122
        }
×
123

UNCOV
124
        Ok(Bool(
×
UNCOV
125
            arr_dt.nullability() | lower_dt.nullability() | upper_dt.nullability(),
×
UNCOV
126
        ))
×
UNCOV
127
    }
×
128
}
129

130
impl BetweenExpr {
UNCOV
131
    pub fn new(arr: ExprRef, lower: ExprRef, upper: ExprRef, options: BetweenOptions) -> Self {
×
UNCOV
132
        Self {
×
UNCOV
133
            arr,
×
UNCOV
134
            lower,
×
UNCOV
135
            upper,
×
UNCOV
136
            options,
×
UNCOV
137
        }
×
UNCOV
138
    }
×
139

UNCOV
140
    pub fn new_expr(
×
UNCOV
141
        arr: ExprRef,
×
UNCOV
142
        lower: ExprRef,
×
UNCOV
143
        upper: ExprRef,
×
UNCOV
144
        options: BetweenOptions,
×
UNCOV
145
    ) -> ExprRef {
×
UNCOV
146
        Self::new(arr, lower, upper, options).into_expr()
×
UNCOV
147
    }
×
148

149
    pub fn to_binary_expr(&self) -> ExprRef {
×
150
        let lhs = BinaryExpr::new(
×
151
            self.lower.clone(),
×
152
            self.options.lower_strict.to_operator().into(),
×
153
            self.arr.clone(),
×
154
        );
155
        let rhs = BinaryExpr::new(
×
156
            self.arr.clone(),
×
157
            self.options.upper_strict.to_operator().into(),
×
158
            self.upper.clone(),
×
159
        );
160
        BinaryExpr::new(lhs.into_expr(), crate::Operator::And, rhs.into_expr()).into_expr()
×
161
    }
×
162
}
163

164
impl Display for BetweenExpr {
165
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
×
166
        write!(
×
167
            f,
×
168
            "({} {} {} {} {})",
×
169
            self.lower,
170
            self.options.lower_strict.to_operator(),
×
171
            self.arr,
172
            self.options.upper_strict.to_operator(),
×
173
            self.upper
174
        )
175
    }
×
176
}
177

178
impl AnalysisExpr for BetweenExpr {}
179

UNCOV
180
pub fn between(arr: ExprRef, lower: ExprRef, upper: ExprRef, options: BetweenOptions) -> ExprRef {
×
UNCOV
181
    BetweenExpr::new(arr, lower, upper, options).into_expr()
×
UNCOV
182
}
×
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