Skip to content

Commit 2d32a39

Browse files
committed
Scalar arithmetic
Signed-off-by: Nicholas Gates <[email protected]>
1 parent 636cdad commit 2d32a39

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

vortex-compute/src/arithmetic/pscalar.rs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,19 @@
44
use vortex_dtype::NativePType;
55
use vortex_vector::primitive::PScalar;
66

7-
use crate::arithmetic::{Arithmetic, Operator};
7+
use crate::arithmetic::{Arithmetic, CheckedArithmetic, CheckedOperator, Operator};
88

99
impl<Op, T> Arithmetic<Op> for &PScalar<T>
1010
where
1111
T: NativePType,
1212
Op: Operator<T>,
13-
for<'a> &'a T: Arithmetic<Op, &'a T, Output = T>,
1413
{
1514
type Output = PScalar<T>;
1615

1716
fn eval(self, rhs: &PScalar<T>) -> Self::Output {
1817
match (self.value(), rhs.value()) {
1918
(Some(a), Some(b)) => {
20-
let value = Arithmetic::<Op, _>::eval(a, b);
19+
let value = Op::apply(&a, &b);
2120
PScalar::new(Some(value))
2221
}
2322
(..) => {
@@ -27,3 +26,58 @@ where
2726
}
2827
}
2928
}
29+
30+
impl<Op, T> CheckedArithmetic<Op> for &PScalar<T>
31+
where
32+
T: NativePType,
33+
Op: CheckedOperator<T>,
34+
{
35+
type Output = PScalar<T>;
36+
37+
fn checked_eval(self, rhs: Self) -> Option<Self::Output> {
38+
match (self.value(), rhs.value()) {
39+
(Some(a), Some(b)) => {
40+
let value = Op::apply(&a, &b)?;
41+
Some(PScalar::new(Some(value)))
42+
}
43+
(..) => {
44+
// At least one side is null, so result is null
45+
Some(PScalar::new(None))
46+
}
47+
}
48+
}
49+
}
50+
51+
#[cfg(test)]
52+
mod test {
53+
use vortex_vector::primitive::PScalar;
54+
55+
use super::*;
56+
use crate::arithmetic::{Add, CheckedArithmetic, WrappingSub};
57+
58+
#[test]
59+
fn test_add() {
60+
let left = PScalar::new(Some(5u32));
61+
let right = PScalar::new(Some(3u32));
62+
63+
let result = CheckedArithmetic::<Add>::checked_eval(&left, &right).unwrap();
64+
assert_eq!(result.value(), Some(8u32));
65+
66+
let left_null = PScalar::new(None);
67+
let result_null = CheckedArithmetic::<Add>::checked_eval(&left_null, &right).unwrap();
68+
assert_eq!(result_null.value(), None);
69+
}
70+
71+
#[test]
72+
fn test_subtract() {
73+
let left = PScalar::new(Some(10u32));
74+
let right = PScalar::new(Some(4u32));
75+
76+
let result = Arithmetic::<WrappingSub>::eval(&left, &right);
77+
assert_eq!(result.value(), Some(6u32));
78+
79+
let right_null = PScalar::new(None);
80+
let result_null = Arithmetic::<WrappingSub>::eval(&left, &right_null);
81+
assert_eq!(result_null.value(), None);
82+
}
83+
}

vortex-vector/src/primitive/scalar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ impl<T: NativePType> PScalar<T> {
7575
}
7676

7777
/// Returns the value of the primitive scalar, or `None` if it is null.
78-
pub fn value(&self) -> Option<&T> {
79-
self.0.as_ref()
78+
pub fn value(&self) -> Option<T> {
79+
self.0
8080
}
8181
}
8282

0 commit comments

Comments
 (0)