pub mod config;
pub mod context;
pub mod statement_executor;
pub use config::ExecutionConfig;
pub use context::ExecutionContext;
pub use statement_executor::{ExecutionResult, ExecutionStats, StatementExecutor};
#[cfg(test)]
mod tests {
use super::*;
use crate::data::datatable::{DataColumn, DataRow, DataTable, DataType, DataValue};
use crate::sql::recursive_parser::Parser;
use std::sync::Arc;
fn create_sample_table() -> DataTable {
let mut table = DataTable::new("sample");
table.add_column(DataColumn::new("id").with_type(DataType::Integer));
table.add_column(DataColumn::new("value").with_type(DataType::Integer));
for i in 1..=10 {
let _ = table.add_row(DataRow {
values: vec![DataValue::Integer(i), DataValue::Integer(i * 10)],
});
}
table
}
#[test]
fn test_module_integration() {
let table = create_sample_table();
let mut context = ExecutionContext::new(Arc::new(table));
let config = ExecutionConfig::new()
.with_case_insensitive(false)
.with_auto_hide_empty(false);
let executor = StatementExecutor::with_config(config);
let mut parser = Parser::new("SELECT id, value FROM sample WHERE id <= 5");
let stmt = parser.parse().unwrap();
let result = executor.execute(stmt, &mut context).unwrap();
assert_eq!(result.dataview.row_count(), 5);
assert_eq!(result.dataview.column_count(), 2);
assert!(result.stats.total_time_ms >= 0.0);
}
#[test]
fn test_temp_table_workflow() {
let base_table = create_sample_table();
let mut context = ExecutionContext::new(Arc::new(base_table));
let executor = StatementExecutor::new();
let mut temp_table = DataTable::new("#filtered");
temp_table.add_column(DataColumn::new("id").with_type(DataType::Integer));
temp_table.add_column(DataColumn::new("value").with_type(DataType::Integer));
for i in 1..=3 {
let _ = temp_table.add_row(DataRow {
values: vec![DataValue::Integer(i), DataValue::Integer(i * 10)],
});
}
context
.store_temp_table("#filtered".to_string(), Arc::new(temp_table))
.unwrap();
let mut parser = Parser::new("SELECT * FROM #filtered");
let stmt = parser.parse().unwrap();
let result = executor.execute(stmt, &mut context).unwrap();
assert_eq!(result.dataview.row_count(), 3);
assert!(context.has_temp_table("#filtered"));
}
#[test]
fn test_dual_table_usage() {
let table = create_sample_table();
let mut context = ExecutionContext::new(Arc::new(table));
let executor = StatementExecutor::new();
let mut parser = Parser::new("SELECT 1+1 as result, 'hello' as greeting");
let stmt = parser.parse().unwrap();
let result = executor.execute(stmt, &mut context).unwrap();
assert_eq!(result.dataview.row_count(), 1);
assert_eq!(result.dataview.column_count(), 2);
assert!(!result.stats.preprocessing_applied); }
#[test]
fn test_configuration_propagation() {
let table = create_sample_table();
let mut context = ExecutionContext::new(Arc::new(table));
let config = ExecutionConfig::new().without_preprocessing();
let executor = StatementExecutor::with_config(config);
let mut parser = Parser::new("SELECT * FROM sample");
let stmt = parser.parse().unwrap();
let result = executor.execute(stmt, &mut context).unwrap();
assert_eq!(result.dataview.row_count(), 10);
}
#[test]
fn test_execution_statistics() {
let table = create_sample_table();
let mut context = ExecutionContext::new(Arc::new(table));
let executor = StatementExecutor::new();
let mut parser = Parser::new("SELECT * FROM sample WHERE value > 50");
let stmt = parser.parse().unwrap();
let result = executor.execute(stmt, &mut context).unwrap();
assert_eq!(result.stats.row_count, 5); assert_eq!(result.stats.column_count, 2);
assert!(result.stats.total_time_ms >= result.stats.preprocessing_time_ms);
assert!(result.stats.total_time_ms >= result.stats.execution_time_ms);
}
}