kyu_executor/operators/
empty.rs1use kyu_common::KyuResult;
4use crate::context::ExecutionContext;
5use crate::data_chunk::DataChunk;
6
7pub struct EmptyOp {
8 pub num_columns: usize,
9 done: bool,
10}
11
12impl EmptyOp {
13 pub fn new(num_columns: usize) -> Self {
14 Self {
15 num_columns,
16 done: false,
17 }
18 }
19
20 pub fn next(&mut self, _ctx: &ExecutionContext<'_>) -> KyuResult<Option<DataChunk>> {
21 if self.done {
22 return Ok(None);
23 }
24 self.done = true;
25 if self.num_columns == 0 {
27 Ok(Some(DataChunk::new_with_row_count(Vec::new(), 1)))
28 } else {
29 Ok(Some(DataChunk::single_empty_row(self.num_columns)))
30 }
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37 use kyu_types::TypedValue;
38
39 #[test]
40 fn empty_produces_one_row() {
41 let storage = crate::context::MockStorage::new();
42 let ctx = ExecutionContext::new(
43 kyu_catalog::CatalogContent::new(),
44 &storage,
45 );
46 let mut op = EmptyOp::new(2);
47 let chunk = op.next(&ctx).unwrap().unwrap();
48 assert_eq!(chunk.num_rows(), 1);
49 assert_eq!(chunk.get_value(0, 0), TypedValue::Null);
50 assert!(op.next(&ctx).unwrap().is_none());
51 }
52
53 #[test]
54 fn empty_zero_columns() {
55 let storage = crate::context::MockStorage::new();
56 let ctx = ExecutionContext::new(
57 kyu_catalog::CatalogContent::new(),
58 &storage,
59 );
60 let mut op = EmptyOp::new(0);
61 let chunk = op.next(&ctx).unwrap().unwrap();
62 assert_eq!(chunk.num_columns(), 0);
63 assert!(op.next(&ctx).unwrap().is_none());
64 }
65}