Skip to main content

citadel_sql/executor/
compile.rs

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