1pub mod access_path;
20pub mod agg_stream_probe;
21pub mod engine;
22pub(crate) mod engine_stats;
23pub mod executor;
24pub mod m2_select_validator;
25pub mod parser;
26pub mod planner;
27pub mod prepared;
28pub mod result;
29pub(crate) mod result_budget;
30pub mod writetime_ttl_validator;
31
32#[cfg(feature = "state_machine")]
34pub mod select_ast;
35#[cfg(feature = "state_machine")]
36pub mod select_executor;
37#[cfg(feature = "state_machine")]
38pub mod select_integration_tests;
39#[cfg(feature = "state_machine")]
40pub mod select_naming;
41#[cfg(feature = "state_machine")]
42pub mod select_optimizer;
43#[cfg(feature = "state_machine")]
44pub mod select_parser;
45
46pub use access_path::{AccessPath, FallbackReason};
47pub use engine::{
48 AnalyzeResult, CacheStats, ExplainResult, QueryEngine as AdvancedQueryEngine, SchemaStatus,
49};
50pub use executor::{
51 QueryExecutor, QueryResult as ExecutorQueryResult, QueryRow as ExecutorQueryRow,
52};
53pub use m2_select_validator::{M2SelectValidator, SelectValidationResult, UnsupportedFeature};
54pub use parser::QueryParser;
55pub use planner::{ExecutionStep, IndexSelection, PlanType, QueryHints, QueryPlan, QueryPlanner};
56pub use prepared::{
57 ExecutionHints, ParameterMetadata, PreparedContext, PreparedQuery, PreparedQueryBuilder,
58 PreparedQueryStats,
59};
60pub use result::{
61 cql_type_to_data_type, ColumnInfo, PerformanceMetrics, QueryMetadata, QueryResult,
62 QueryResultIterator, QueryRow, RowMetadata, StreamingConfig,
63};
64pub use writetime_ttl_validator::{
65 descriptors_from_table_schema, validate_all_writetime_ttl_calls, validate_writetime_ttl_call,
66 ColumnDescriptor as WriteTimeTtlColumnDescriptor, WriteTimeTtlKind,
67};
68
69#[cfg(feature = "state_machine")]
75pub use select_ast::SelectStatement;
76#[cfg(feature = "state_machine")]
77pub use select_executor::{
78 build_row_from_scan, build_row_from_scan_cached, evaluate_leaf, evaluate_predicates,
79 LeafOutcome, PartitionKeyCache, SelectExecutor,
80};
81#[cfg(feature = "state_machine")]
82pub use select_optimizer::{
83 OptimizedQueryPlan, SSTableFilterOp, SSTablePredicate, SelectOptimizer,
84};
85#[cfg(feature = "state_machine")]
86pub use select_parser::{parse_select, SelectParser};
87
88use std::collections::HashMap;
89use std::sync::Arc;
90
91use crate::{
92 memory::MemoryManager, schema::SchemaManager, storage::StorageEngine, Config, Result, TableId,
93 Value,
94};
95
96#[derive(Debug, Clone, Default)]
98pub struct QueryStats {
99 pub total_queries: u64,
101 pub error_queries: u64,
103 pub avg_execution_time_us: u64,
105 pub cache_hit_ratio: f64,
107 pub rows_affected: u64,
109}
110
111#[derive(Debug)]
116pub struct QueryEngine {
117 advanced_engine: AdvancedQueryEngine,
118}
119
120impl QueryEngine {
121 pub fn new(
123 storage: Arc<StorageEngine>,
124 schema: Arc<SchemaManager>,
125 memory: Arc<MemoryManager>,
126 config: &Config,
127 ) -> Result<Self> {
128 Ok(Self {
129 advanced_engine: AdvancedQueryEngine::new(storage, schema, memory, config)?,
130 })
131 }
132
133 pub async fn execute(&self, cql: &str) -> Result<QueryResult> {
135 self.advanced_engine.execute(cql).await
136 }
137
138 pub async fn execute_with_params(&self, cql: &str, params: &[Value]) -> Result<QueryResult> {
140 self.advanced_engine.execute_with_params(cql, params).await
141 }
142
143 pub async fn prepare(&self, cql: &str) -> Result<Arc<PreparedQuery>> {
145 self.advanced_engine.prepare(cql).await
146 }
147
148 pub fn stats(&self) -> QueryStats {
150 self.advanced_engine.stats()
151 }
152
153 pub fn clear_cache(&self) {
155 self.advanced_engine.clear_prepared_cache();
156 }
157
158 pub async fn explain(&self, cql: &str) -> Result<ExplainResult> {
160 self.advanced_engine.explain(cql).await
161 }
162
163 pub async fn analyze(&self, cql: &str) -> Result<AnalyzeResult> {
165 self.advanced_engine.analyze(cql).await
166 }
167
168 #[cfg(feature = "state_machine")]
173 pub async fn execute_streaming(
174 &self,
175 cql: &str,
176 config: StreamingConfig,
177 ) -> Result<QueryResultIterator> {
178 self.advanced_engine.execute_streaming(cql, config).await
179 }
180
181 pub fn cache_stats(&self) -> CacheStats {
183 self.advanced_engine.cache_stats()
184 }
185
186 pub async fn has_schema_for_table(&self, table: &str) -> bool {
188 self.advanced_engine.has_schema_for_table(table).await
189 }
190
191 pub async fn schema_status(&self, table: &str) -> SchemaStatus {
193 self.advanced_engine.schema_status(table).await
194 }
195}
196
197#[derive(Debug, Clone, PartialEq)]
199pub enum QueryType {
200 Select,
202 Insert,
204 Update,
206 Delete,
208 CreateTable,
210 DropTable,
212 CreateIndex,
214 DropIndex,
216 Describe,
218 Use,
220}
221
222#[derive(Debug, Clone)]
224pub struct ParsedQuery {
225 pub query_type: QueryType,
227 pub table: Option<TableId>,
229 pub columns: Vec<String>,
231 pub where_clause: Option<WhereClause>,
233 pub values: Vec<Value>,
235 pub set_clause: HashMap<String, Value>,
237 pub order_by: Vec<OrderByClause>,
239 pub limit: Option<usize>,
241 pub cql: String,
243}
244
245#[derive(Debug, Clone)]
247pub struct WhereClause {
248 pub conditions: Vec<Condition>,
250}
251
252#[derive(Debug, Clone)]
254pub struct Condition {
255 pub column: String,
257 pub operator: ComparisonOperator,
259 pub value: Value,
261}
262
263#[derive(Debug, Clone, PartialEq)]
265pub enum ComparisonOperator {
266 Equal,
268 NotEqual,
270 LessThan,
272 LessThanOrEqual,
274 GreaterThan,
276 GreaterThanOrEqual,
278 In,
280 NotIn,
282 Like,
284 NotLike,
286}
287
288#[derive(Debug, Clone)]
290pub struct OrderByClause {
291 pub column: String,
293 pub direction: SortDirection,
295}
296
297#[derive(Debug, Clone, PartialEq)]
299pub enum SortDirection {
300 Asc,
302 Desc,
304}
305
306#[cfg(all(test, feature = "state_machine"))]
307mod tests {
308 use super::*;
309 use crate::platform::Platform;
310 use tempfile::TempDir;
311
312 #[tokio::test]
313 async fn test_query_engine_creation() {
314 let temp_dir = TempDir::new().unwrap();
315 let config = Config::default();
316 let platform = Arc::new(Platform::new(&config).await.unwrap());
317
318 let storage = Arc::new(
319 StorageEngine::open(
320 temp_dir.path(),
321 &config,
322 platform,
323 #[cfg(feature = "state_machine")]
324 None,
325 )
326 .await
327 .unwrap(),
328 );
329 let schema = Arc::new(SchemaManager::new(temp_dir.path()).await.unwrap());
330 let memory = Arc::new(MemoryManager::new(&config).unwrap());
331
332 let query_engine = QueryEngine::new(storage, schema, memory, &config).unwrap();
333
334 assert_eq!(query_engine.stats().total_queries, 0);
335 }
336}