Skip to content

Commit 692aef6

Browse files
committed
test: cover accumulators and window operator
1 parent 04ac467 commit 692aef6

6 files changed

Lines changed: 185 additions & 4 deletions

File tree

src/execution/dql/aggregate/avg.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,25 @@ mod tests {
108108
assert_ne!(first, second);
109109
accumulator.evaluate()?;
110110
assert_eq!(&second, accumulator.result());
111+
assert_eq!(Box::new(accumulator).result_owned(), second);
112+
Ok(())
113+
}
114+
115+
#[test]
116+
fn empty_and_unsigned_results() -> Result<(), DatabaseError> {
117+
let mut empty = AvgAccumulator::new();
118+
empty.evaluate()?;
119+
assert_eq!(empty.result(), &DataValue::Null);
120+
assert_eq!(Box::new(empty).result_owned(), DataValue::Null);
121+
122+
let mut accumulator = AvgAccumulator::new();
123+
accumulator.update_value(&DataValue::UInt32(2))?;
124+
accumulator.update_value(&DataValue::UInt32(4))?;
125+
accumulator.evaluate()?;
126+
assert_eq!(
127+
Box::new(accumulator).result_owned(),
128+
DataValue::Float64(3.0.into())
129+
);
111130
Ok(())
112131
}
113132
}

src/execution/dql/aggregate/count.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,8 @@ impl DistinctCountAccumulator {
6666

6767
impl Accumulator for DistinctCountAccumulator {
6868
fn update_value(&mut self, value: &DataValue) -> Result<(), DatabaseError> {
69-
if !value.is_null() {
70-
if self.distinct_values.insert(value.clone()) {
71-
self.result = DataValue::Int32(self.distinct_values.len() as i32);
72-
}
69+
if !value.is_null() && self.distinct_values.insert(value.clone()) {
70+
self.result = DataValue::Int32(self.distinct_values.len() as i32);
7371
}
7472

7573
Ok(())
@@ -83,3 +81,32 @@ impl Accumulator for DistinctCountAccumulator {
8381
self.result
8482
}
8583
}
84+
85+
// GRCOV_EXCL_START
86+
#[cfg(all(test, not(target_arch = "wasm32")))]
87+
mod tests {
88+
use super::*;
89+
90+
#[test]
91+
fn count_results() -> Result<(), DatabaseError> {
92+
let mut accumulator = CountAccumulator::new();
93+
for value in [DataValue::Null, 1.into(), 1.into()] {
94+
accumulator.update_value(&value)?;
95+
}
96+
assert_eq!(accumulator.result(), &DataValue::Int32(2));
97+
assert_eq!(Box::new(accumulator).result_owned(), DataValue::Int32(2));
98+
Ok(())
99+
}
100+
101+
#[test]
102+
fn distinct_count_results() -> Result<(), DatabaseError> {
103+
let mut accumulator = DistinctCountAccumulator::new();
104+
for value in [DataValue::Null, 1.into(), 1.into(), 2.into()] {
105+
accumulator.update_value(&value)?;
106+
}
107+
assert_eq!(accumulator.result(), &DataValue::Int32(2));
108+
assert_eq!(Box::new(accumulator).result_owned(), DataValue::Int32(2));
109+
Ok(())
110+
}
111+
}
112+
// GRCOV_EXCL_STOP

src/execution/dql/aggregate/min_max.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,26 @@ impl Accumulator for MinMaxAccumulator {
6666
self.result
6767
}
6868
}
69+
70+
// GRCOV_EXCL_START
71+
#[cfg(all(test, not(target_arch = "wasm32")))]
72+
mod tests {
73+
use super::*;
74+
75+
#[test]
76+
fn min_max_results() -> Result<(), DatabaseError> {
77+
for (is_max, expected) in [(false, 1), (true, 3)] {
78+
let mut accumulator = MinMaxAccumulator::new(is_max);
79+
for value in [DataValue::Null, 3.into(), 1.into(), 2.into()] {
80+
accumulator.update_value(&value)?;
81+
}
82+
assert_eq!(accumulator.result(), &DataValue::Int32(expected));
83+
assert_eq!(
84+
Box::new(accumulator).result_owned(),
85+
DataValue::Int32(expected)
86+
);
87+
}
88+
Ok(())
89+
}
90+
}
91+
// GRCOV_EXCL_STOP

src/execution/dql/aggregate/sum.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,32 @@ impl Accumulator for DistinctSumAccumulator {
9191
self.inner.result
9292
}
9393
}
94+
95+
// GRCOV_EXCL_START
96+
#[cfg(all(test, not(target_arch = "wasm32")))]
97+
mod tests {
98+
use super::*;
99+
100+
#[test]
101+
fn sum_results() -> Result<(), DatabaseError> {
102+
let mut accumulator = SumAccumulator::new(Cow::Borrowed(&LogicalType::Integer))?;
103+
for value in [DataValue::Null, 2.into(), 3.into()] {
104+
accumulator.update_value(&value)?;
105+
}
106+
assert_eq!(accumulator.result(), &DataValue::Int32(5));
107+
assert_eq!(Box::new(accumulator).result_owned(), DataValue::Int32(5));
108+
Ok(())
109+
}
110+
111+
#[test]
112+
fn distinct_sum_results() -> Result<(), DatabaseError> {
113+
let mut accumulator = DistinctSumAccumulator::new(&LogicalType::Integer)?;
114+
for value in [DataValue::Null, 2.into(), 2.into(), 3.into()] {
115+
accumulator.update_value(&value)?;
116+
}
117+
assert_eq!(accumulator.result(), &DataValue::Int32(5));
118+
assert_eq!(Box::new(accumulator).result_owned(), DataValue::Int32(5));
119+
Ok(())
120+
}
121+
}
122+
// GRCOV_EXCL_STOP

src/expression/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,7 @@ mod test {
11161116
use crate::expression::function::table::{
11171117
ArcTableFunctionImpl, TableFunction, TableFunctionCatalog, TableFunctionImpl,
11181118
};
1119+
use crate::expression::window::{WindowCall, WindowFunction, WindowFunctionKind, WindowSpec};
11191120
use crate::expression::TrimWhereField;
11201121
use crate::expression::{AliasType, BinaryOperator, ScalarExpression, UnaryOperator};
11211122
use crate::function::current_date::CurrentDate;
@@ -1599,6 +1600,23 @@ mod test {
15991600
&mut reference_tables,
16001601
&mut plan_arena,
16011602
)?;
1603+
fn_assert(
1604+
&mut cursor,
1605+
ScalarExpression::WindowCall(WindowCall {
1606+
function: WindowFunction {
1607+
kind: WindowFunctionKind::Aggregate(AggKind::Sum),
1608+
args: vec![ScalarExpression::Constant(1.into())],
1609+
ty: LogicalType::Integer,
1610+
},
1611+
spec: WindowSpec {
1612+
partition_by: vec![ScalarExpression::Constant(2.into())],
1613+
order_by: vec![ScalarExpression::Constant(3.into()).desc()],
1614+
},
1615+
}),
1616+
Some(&context),
1617+
&mut reference_tables,
1618+
&mut plan_arena,
1619+
)?;
16021620

16031621
Ok(())
16041622
}

src/planner/operator/window.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,68 @@ impl fmt::Display for WindowOperator {
5858
Ok(())
5959
}
6060
}
61+
62+
// GRCOV_EXCL_START
63+
#[cfg(all(test, not(target_arch = "wasm32")))]
64+
mod tests {
65+
use super::*;
66+
use crate::expression::window::WindowFunctionKind;
67+
use crate::planner::TableArena;
68+
use crate::serdes::{ReferenceSerialization, ReferenceTables};
69+
use crate::storage::rocksdb::RocksTransaction;
70+
use crate::types::LogicalType;
71+
use std::io::{Cursor, Seek, SeekFrom};
72+
73+
fn operator(partition_by: Vec<ScalarExpression>, order_by: Vec<SortField>) -> WindowOperator {
74+
WindowOperator {
75+
partition_by,
76+
order_by,
77+
functions: vec![WindowFunction {
78+
kind: WindowFunctionKind::RowNumber,
79+
args: Vec::new(),
80+
ty: LogicalType::Bigint,
81+
}],
82+
output_columns: Vec::new(),
83+
}
84+
}
85+
86+
#[test]
87+
fn display_window_spec() {
88+
let function = "Window [WindowFunction { kind: RowNumber, args: [], ty: Bigint }]";
89+
assert_eq!(operator(Vec::new(), Vec::new()).to_string(), function);
90+
assert_eq!(
91+
operator(vec![1.into()], Vec::new()).to_string(),
92+
format!("{function} -> Partition By [1]")
93+
);
94+
assert_eq!(
95+
operator(Vec::new(), vec![ScalarExpression::from(2).desc()]).to_string(),
96+
format!("{function} -> Order By [2 Desc Nulls Last]")
97+
);
98+
assert_eq!(
99+
operator(vec![1.into()], vec![ScalarExpression::from(2).desc()]).to_string(),
100+
format!("{function} -> Partition By [1] Order By [2 Desc Nulls Last]")
101+
);
102+
}
103+
104+
#[test]
105+
fn serialization_roundtrip() -> Result<(), crate::errors::DatabaseError> {
106+
let source = operator(vec![1.into()], vec![ScalarExpression::from(2).desc()]);
107+
let mut cursor = Cursor::new(Vec::new());
108+
let mut reference_tables = ReferenceTables::new();
109+
let arena = TableArena::default();
110+
source.encode(&mut cursor, false, &mut reference_tables, &arena)?;
111+
cursor.seek(SeekFrom::Start(0))?;
112+
113+
assert_eq!(
114+
WindowOperator::decode::<RocksTransaction, _, _>(
115+
&mut cursor,
116+
None,
117+
&reference_tables,
118+
&mut TableArena::default(),
119+
)?,
120+
source
121+
);
122+
Ok(())
123+
}
124+
}
125+
// GRCOV_EXCL_STOP

0 commit comments

Comments
 (0)