Skip to main content

citadel_sql/executor/
compile.rs

1use std::sync::Arc;
2
3use citadel::Database;
4use citadel_txn::write_txn::WriteTxn;
5
6use crate::error::Result;
7use crate::parser::Statement;
8use crate::schema::SchemaManager;
9use crate::types::{ExecutionResult, Value};
10
11pub trait CompiledPlan: Send + Sync {
12    fn execute(
13        &self,
14        db: &Database,
15        schema: &SchemaManager,
16        stmt: &Statement,
17        params: &[Value],
18        wtx: Option<&mut WriteTxn<'_>>,
19    ) -> Result<ExecutionResult>;
20
21    /// Attempt to produce a streaming row source. Returns `None` if this plan
22    /// cannot stream the given statement — caller falls back to `execute`.
23    fn try_stream<'db>(
24        &self,
25        _db: &'db Database,
26        _schema: &SchemaManager,
27        _stmt: &Statement,
28        _params: &[Value],
29    ) -> Option<Box<dyn RowSourceIter + 'db>> {
30        None
31    }
32
33    /// `false` when `execute` reads `params` directly without `resolve_scoped_param`,
34    /// letting the caller skip `with_scoped_params`.
35    fn uses_scoped_params(&self) -> bool {
36        true
37    }
38
39    /// `false` when the plan never reads the txn clock (no NOW(),
40    /// CURRENT_TIMESTAMP, etc.). Lets the caller skip the
41    /// `with_txn_clock` thread-local wrapper.
42    fn needs_txn_clock(&self) -> bool {
43        true
44    }
45}
46
47/// Internal trait: object-safe streaming source over decoded rows.
48pub trait RowSourceIter {
49    fn next_row(&mut self) -> Result<Option<Vec<Value>>>;
50    fn columns(&self) -> &[String];
51}
52
53pub fn compile(schema: &SchemaManager, stmt: &Statement) -> Option<Arc<dyn CompiledPlan>> {
54    match stmt {
55        Statement::Select(sq) => super::select::CompiledSelect::try_compile(schema, sq)
56            .map(|c| Arc::new(c) as Arc<dyn CompiledPlan>),
57        Statement::Insert(ins) => super::dml::CompiledInsert::try_compile(schema, ins)
58            .map(|c| Arc::new(c) as Arc<dyn CompiledPlan>),
59        Statement::Update(upd) => super::write::CompiledUpdate::try_compile(schema, upd)
60            .ok()
61            .flatten()
62            .map(|c| Arc::new(c) as Arc<dyn CompiledPlan>),
63        Statement::Delete(del) => super::dml::CompiledDelete::try_compile(schema, del)
64            .map(|c| Arc::new(c) as Arc<dyn CompiledPlan>),
65        _ => None,
66    }
67}