quill_sql/execution/
mod.rs1pub mod physical_plan;
2use crate::catalog::SchemaRef;
3use crate::error::{QuillSQLError, QuillSQLResult};
4use crate::execution::physical_plan::PhysicalPlan;
5use crate::expression::{Expr, ExprTrait};
6use crate::storage::{
7 engine::{StorageEngine, TableBinding},
8 table_heap::TableHeap,
9 tuple::Tuple,
10};
11use crate::transaction::{Transaction, TransactionManager, TxnContext};
12use crate::utils::scalar::ScalarValue;
13use crate::{catalog::Catalog, utils::table_ref::TableReference};
14use std::sync::Arc;
15
16pub trait VolcanoExecutor {
17 fn init(&self, _context: &mut ExecutionContext) -> QuillSQLResult<()> {
18 Ok(())
19 }
20
21 fn next(&self, context: &mut ExecutionContext) -> QuillSQLResult<Option<Tuple>>;
22
23 fn output_schema(&self) -> SchemaRef;
24}
25
26pub struct ExecutionContext<'a> {
29 pub catalog: &'a mut Catalog,
31 storage: Arc<dyn StorageEngine>,
33 txn: TxnContext<'a>,
35}
36
37impl<'a> ExecutionContext<'a> {
38 pub fn new(
39 catalog: &'a mut Catalog,
40 txn: &'a mut Transaction,
41 txn_mgr: Arc<TransactionManager>,
42 storage: Arc<dyn StorageEngine>,
43 ) -> Self {
44 Self {
45 catalog,
46 storage,
47 txn: TxnContext::new(txn_mgr, txn),
48 }
49 }
50
51 pub fn eval_predicate(&self, expr: &Expr, tuple: &Tuple) -> QuillSQLResult<bool> {
53 match expr.evaluate(tuple)? {
54 ScalarValue::Boolean(Some(v)) => Ok(v),
55 ScalarValue::Boolean(None) => Ok(false),
56 other => Err(QuillSQLError::Execution(format!(
57 "predicate value must be boolean, got {}",
58 other
59 ))),
60 }
61 }
62
63 pub fn eval_expr(&self, expr: &Expr, tuple: &Tuple) -> QuillSQLResult<ScalarValue> {
65 expr.evaluate(tuple)
66 }
67
68 pub fn table(&self, table: &TableReference) -> QuillSQLResult<TableBinding> {
70 self.storage.table(self.catalog, table)
71 }
72
73 pub fn table_heap(&self, table: &TableReference) -> QuillSQLResult<Arc<TableHeap>> {
74 Ok(self.table(table)?.table_heap())
75 }
76
77 pub fn txn_ctx(&self) -> &TxnContext<'a> {
78 &self.txn
79 }
80
81 pub fn txn_ctx_mut(&mut self) -> &mut TxnContext<'a> {
82 &mut self.txn
83 }
84}
85
86pub struct ExecutionEngine<'a> {
87 pub context: ExecutionContext<'a>,
88}
89impl<'a> ExecutionEngine<'a> {
90 pub fn execute(&mut self, plan: Arc<PhysicalPlan>) -> QuillSQLResult<Vec<Tuple>> {
91 plan.init(&mut self.context)?;
92 let mut result = Vec::new();
93 loop {
94 let next_tuple = plan.next(&mut self.context)?;
95 if let Some(tuple) = next_tuple {
96 result.push(tuple);
97 } else {
98 break;
99 }
100 }
101 Ok(result)
102 }
103}