1pub mod aggregate;
4pub mod filter;
5pub mod join;
6pub(crate) mod like;
7pub mod scan;
8pub mod sort;
9pub mod spatial_funcs;
10
11pub use spatial_funcs::evaluate_spatial_function;
12
13pub mod window;
14
15pub use window::{OrderKey, WindowFunction, WindowSpec, evaluate_window, evaluate_window_batch};
16
17use crate::error::{QueryError, Result};
18use crate::parser::ast::*;
19use aggregate::{Aggregate, AggregateFunc, AggregateFunction};
20use filter::Filter;
21use join::Join;
22use scan::{DataSource, RecordBatch, TableScan};
23use sort::Sort;
24use std::collections::HashMap;
25use std::sync::Arc;
26
27pub struct Executor {
29 data_sources: HashMap<String, Arc<dyn DataSource>>,
31}
32
33impl Executor {
34 pub fn new() -> Self {
36 Self {
37 data_sources: HashMap::new(),
38 }
39 }
40
41 pub fn register_data_source(&mut self, name: String, source: Arc<dyn DataSource>) {
43 self.data_sources.insert(name, source);
44 }
45
46 pub async fn execute(&self, stmt: &Statement) -> Result<Vec<RecordBatch>> {
48 match stmt {
49 Statement::Select(select) => self.execute_select(select).await,
50 }
51 }
52
53 async fn execute_select(&self, select: &SelectStatement) -> Result<Vec<RecordBatch>> {
55 let mut batches = if let Some(ref table_ref) = select.from {
57 self.execute_table_reference(table_ref).await?
58 } else {
59 return Err(QueryError::semantic("SELECT without FROM not supported"));
60 };
61
62 if let Some(ref selection) = select.selection {
64 batches = self.execute_filter(batches, selection)?;
65 }
66
67 if !select.group_by.is_empty() || self.has_aggregates(&select.projection) {
69 batches = self.execute_aggregate(batches, select)?;
70 }
71
72 if !select.order_by.is_empty() {
74 batches = self.execute_sort(batches, &select.order_by)?;
75 }
76
77 if select.limit.is_some() || select.offset.is_some() {
79 batches = self.execute_limit_offset(batches, select.limit, select.offset)?;
80 }
81
82 Ok(batches)
83 }
84
85 async fn execute_table_reference(
87 &self,
88 table_ref: &TableReference,
89 ) -> Result<Vec<RecordBatch>> {
90 match table_ref {
91 TableReference::Table { name, .. } => {
92 let source = self
93 .data_sources
94 .get(name)
95 .ok_or_else(|| QueryError::TableNotFound(name.clone()))?;
96
97 let scan = TableScan::new(name.clone(), source.clone());
98 scan.execute().await
99 }
100 TableReference::Join {
101 left,
102 right,
103 join_type,
104 on,
105 } => {
106 let left_batches = Box::pin(self.execute_table_reference(left)).await?;
108 let right_batches = Box::pin(self.execute_table_reference(right)).await?;
109
110 let join = Join::new(*join_type, on.clone());
111 let mut result = Vec::new();
112
113 for left_batch in &left_batches {
114 for right_batch in &right_batches {
115 result.push(join.execute(left_batch, right_batch)?);
116 }
117 }
118
119 Ok(result)
120 }
121 TableReference::Subquery { query, .. } => Box::pin(self.execute_select(query)).await,
122 }
123 }
124
125 fn execute_filter(
127 &self,
128 batches: Vec<RecordBatch>,
129 predicate: &Expr,
130 ) -> Result<Vec<RecordBatch>> {
131 let filter = Filter::new(predicate.clone());
132 let mut result = Vec::new();
133
134 for batch in batches {
135 result.push(filter.execute(&batch)?);
136 }
137
138 Ok(result)
139 }
140
141 fn execute_aggregate(
143 &self,
144 batches: Vec<RecordBatch>,
145 select: &SelectStatement,
146 ) -> Result<Vec<RecordBatch>> {
147 let mut agg_funcs = Vec::new();
149
150 for item in &select.projection {
151 if let SelectItem::Expr { expr, alias } = item
152 && let Some(agg_func) = self.extract_aggregate(expr)
153 {
154 let func_alias = alias.clone().or_else(|| Some("agg".to_string()));
155 agg_funcs.push(AggregateFunction {
156 func: agg_func.0,
157 column: agg_func.1,
158 alias: func_alias,
159 });
160 }
161 }
162
163 let aggregate = Aggregate::new(select.group_by.clone(), agg_funcs);
164 let mut result = Vec::new();
165
166 for batch in batches {
167 result.push(aggregate.execute(&batch)?);
168 }
169
170 Ok(result)
171 }
172
173 fn extract_aggregate(&self, expr: &Expr) -> Option<(AggregateFunc, String)> {
175 if let Expr::Function { name, args } = expr {
176 let func = match name.to_uppercase().as_str() {
177 "COUNT" => Some(AggregateFunc::Count),
178 "SUM" => Some(AggregateFunc::Sum),
179 "AVG" => Some(AggregateFunc::Avg),
180 "MIN" => Some(AggregateFunc::Min),
181 "MAX" => Some(AggregateFunc::Max),
182 _ => None,
183 }?;
184
185 if let Some(arg) = args.first() {
186 match arg {
187 Expr::Column { name, .. } => {
188 return Some((func, name.clone()));
189 }
190 Expr::Wildcard => {
191 return Some((func, "*".to_string()));
193 }
194 _ => {}
195 }
196 } else if matches!(func, AggregateFunc::Count) {
197 return Some((func, "*".to_string()));
199 }
200 }
201 None
202 }
203
204 fn has_aggregates(&self, projection: &[SelectItem]) -> bool {
206 for item in projection {
207 if let SelectItem::Expr { expr, .. } = item
208 && self.extract_aggregate(expr).is_some()
209 {
210 return true;
211 }
212 }
213 false
214 }
215
216 fn execute_sort(
218 &self,
219 batches: Vec<RecordBatch>,
220 order_by: &[OrderByExpr],
221 ) -> Result<Vec<RecordBatch>> {
222 let sort = Sort::new(order_by.to_vec());
223 let mut result = Vec::new();
224
225 for batch in batches {
226 result.push(sort.execute(&batch)?);
227 }
228
229 Ok(result)
230 }
231
232 fn execute_limit_offset(
234 &self,
235 batches: Vec<RecordBatch>,
236 limit: Option<usize>,
237 offset: Option<usize>,
238 ) -> Result<Vec<RecordBatch>> {
239 let offset = offset.unwrap_or(0);
240 let mut current_row = 0;
241 let mut result = Vec::new();
242 let mut remaining = limit;
243
244 for batch in batches {
245 if let Some(rem) = remaining
246 && rem == 0
247 {
248 break;
249 }
250
251 let start = if current_row < offset {
252 let skip = (offset - current_row).min(batch.num_rows);
253 current_row += skip;
254 skip
255 } else {
256 0
257 };
258
259 let end = if let Some(rem) = remaining {
260 (start + rem).min(batch.num_rows)
261 } else {
262 batch.num_rows
263 };
264
265 if start < end {
266 let slice_batch = self.slice_batch(&batch, start, end)?;
267 let slice_rows = slice_batch.num_rows;
268 result.push(slice_batch);
269
270 if let Some(rem) = &mut remaining {
271 *rem = rem.saturating_sub(slice_rows);
272 }
273 }
274
275 current_row += batch.num_rows;
276 }
277
278 Ok(result)
279 }
280
281 fn slice_batch(&self, batch: &RecordBatch, start: usize, end: usize) -> Result<RecordBatch> {
283 let mut sliced_columns = Vec::new();
284
285 for column in &batch.columns {
286 sliced_columns.push(self.slice_column(column, start, end));
287 }
288
289 RecordBatch::new(batch.schema.clone(), sliced_columns, end - start)
290 }
291
292 fn slice_column(
294 &self,
295 column: &scan::ColumnData,
296 start: usize,
297 end: usize,
298 ) -> scan::ColumnData {
299 use scan::ColumnData;
300
301 match column {
302 ColumnData::Boolean(data) => ColumnData::Boolean(data[start..end].to_vec()),
303 ColumnData::Int32(data) => ColumnData::Int32(data[start..end].to_vec()),
304 ColumnData::Int64(data) => ColumnData::Int64(data[start..end].to_vec()),
305 ColumnData::Float32(data) => ColumnData::Float32(data[start..end].to_vec()),
306 ColumnData::Float64(data) => ColumnData::Float64(data[start..end].to_vec()),
307 ColumnData::String(data) => ColumnData::String(data[start..end].to_vec()),
308 ColumnData::Binary(data) => ColumnData::Binary(data[start..end].to_vec()),
309 }
310 }
311}
312
313impl Default for Executor {
314 fn default() -> Self {
315 Self::new()
316 }
317}
318
319#[cfg(test)]
320mod tests {
321 use super::*;
322 use crate::executor::scan::{DataType, Field, MemoryDataSource, Schema};
323 use crate::parser::sql::parse_sql;
324
325 #[tokio::test]
326 async fn test_executor_simple_query() -> Result<()> {
327 let schema = Arc::new(Schema::new(vec![
328 Field::new("id".to_string(), DataType::Int64, false),
329 Field::new("value".to_string(), DataType::Int64, false),
330 ]));
331
332 let columns = vec![
333 scan::ColumnData::Int64(vec![Some(1), Some(2), Some(3)]),
334 scan::ColumnData::Int64(vec![Some(10), Some(20), Some(30)]),
335 ];
336
337 let batch = RecordBatch::new(schema.clone(), columns, 3)?;
338 let source = Arc::new(MemoryDataSource::new(schema, vec![batch]));
339
340 let mut executor = Executor::new();
341 executor.register_data_source("test_table".to_string(), source);
342
343 let sql = "SELECT * FROM test_table";
344 let stmt = parse_sql(sql)?;
345
346 let result = executor.execute(&stmt).await?;
347 assert!(!result.is_empty());
348
349 Ok(())
350 }
351}