cynos_query/executor/
limit.rs1use crate::executor::Relation;
4
5pub struct LimitExecutor {
7 limit: usize,
8 offset: usize,
9}
10
11impl LimitExecutor {
12 pub fn new(limit: usize, offset: usize) -> Self {
14 Self { limit, offset }
15 }
16
17 pub fn limit_only(limit: usize) -> Self {
19 Self { limit, offset: 0 }
20 }
21
22 pub fn execute(&self, mut input: Relation) -> Relation {
29 let tables = input.tables().to_vec();
30 let table_column_counts = input.table_column_counts().to_vec();
31 let len = input.entries.len();
32 let start = self.offset.min(len);
33 let end = (self.offset + self.limit).min(len);
34
35 input.entries.truncate(end);
37 if start > 0 {
39 input.entries.drain(..start);
40 }
41
42 Relation {
43 entries: input.entries,
44 tables,
45 table_column_counts,
46 }
47 }
48}
49
50#[allow(dead_code)]
52pub fn limit_relation(input: Relation, limit: usize, offset: usize) -> Relation {
53 let tables = input.tables().to_vec();
54 let table_column_counts = input.table_column_counts().to_vec();
55 let entries = input
56 .entries
57 .into_iter()
58 .skip(offset)
59 .take(limit)
60 .collect();
61
62 Relation { entries, tables, table_column_counts }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use alloc::vec;
69 use alloc::vec::Vec;
70 use cynos_core::{Row, Value};
71
72 #[test]
73 fn test_limit_executor() {
74 let rows: Vec<Row> = (0..10)
75 .map(|i| Row::new(i, vec![Value::Int64(i as i64)]))
76 .collect();
77 let input = Relation::from_rows_owned(rows, vec!["t".into()]);
78
79 let executor = LimitExecutor::new(3, 2);
80 let result = executor.execute(input);
81
82 assert_eq!(result.len(), 3);
83 assert_eq!(result.entries[0].get_field(0), Some(&Value::Int64(2)));
84 assert_eq!(result.entries[1].get_field(0), Some(&Value::Int64(3)));
85 assert_eq!(result.entries[2].get_field(0), Some(&Value::Int64(4)));
86 }
87
88 #[test]
89 fn test_limit_only() {
90 let rows: Vec<Row> = (0..10)
91 .map(|i| Row::new(i, vec![Value::Int64(i as i64)]))
92 .collect();
93 let input = Relation::from_rows_owned(rows, vec!["t".into()]);
94
95 let executor = LimitExecutor::limit_only(5);
96 let result = executor.execute(input);
97
98 assert_eq!(result.len(), 5);
99 assert_eq!(result.entries[0].get_field(0), Some(&Value::Int64(0)));
100 }
101
102 #[test]
103 fn test_limit_exceeds_size() {
104 let rows = vec![
105 Row::new(0, vec![Value::Int64(0)]),
106 Row::new(1, vec![Value::Int64(1)]),
107 ];
108 let input = Relation::from_rows_owned(rows, vec!["t".into()]);
109
110 let executor = LimitExecutor::new(100, 0);
111 let result = executor.execute(input);
112
113 assert_eq!(result.len(), 2);
114 }
115
116 #[test]
117 fn test_offset_exceeds_size() {
118 let rows = vec![
119 Row::new(0, vec![Value::Int64(0)]),
120 Row::new(1, vec![Value::Int64(1)]),
121 ];
122 let input = Relation::from_rows_owned(rows, vec!["t".into()]);
123
124 let executor = LimitExecutor::new(10, 100);
125 let result = executor.execute(input);
126
127 assert_eq!(result.len(), 0);
128 }
129}