From ad9b2d819358485ea2e1d862531890b3d727c760 Mon Sep 17 00:00:00 2001 From: Linwei Zhang Date: Wed, 31 Jan 2024 00:17:59 +0800 Subject: [PATCH] Add Display for physical plan --- bustubx/src/execution/mod.rs | 2 +- bustubx/src/expression/mod.rs | 30 ++++++++++--- bustubx/src/planner/logical_planner/mod.rs | 6 +-- ...d_create_table.rs => plan_create_table.rs} | 0 .../{bind_insert.rs => plan_insert.rs} | 0 .../{bind_select.rs => plan_select.rs} | 0 .../src/planner/physical_plan/create_index.rs | 9 ++-- .../src/planner/physical_plan/create_table.rs | 9 ++-- bustubx/src/planner/physical_plan/dummy.rs | 23 ++++++++++ bustubx/src/planner/physical_plan/filter.rs | 7 +++ bustubx/src/planner/physical_plan/insert.rs | 6 +++ bustubx/src/planner/physical_plan/limit.rs | 6 +++ bustubx/src/planner/physical_plan/mod.rs | 43 +++++++++++++------ .../planner/physical_plan/nested_loop_join.rs | 6 +++ bustubx/src/planner/physical_plan/project.rs | 8 ++++ bustubx/src/planner/physical_plan/seq_scan.rs | 8 ++++ bustubx/src/planner/physical_plan/sort.rs | 6 +++ bustubx/src/planner/physical_plan/values.rs | 18 ++++---- .../physical_planner/physical_planner.rs | 4 +- 19 files changed, 152 insertions(+), 39 deletions(-) rename bustubx/src/planner/logical_planner/{bind_create_table.rs => plan_create_table.rs} (100%) rename bustubx/src/planner/logical_planner/{bind_insert.rs => plan_insert.rs} (100%) rename bustubx/src/planner/logical_planner/{bind_select.rs => plan_select.rs} (100%) create mode 100644 bustubx/src/planner/physical_plan/dummy.rs diff --git a/bustubx/src/execution/mod.rs b/bustubx/src/execution/mod.rs index dc938ec..b95a075 100644 --- a/bustubx/src/execution/mod.rs +++ b/bustubx/src/execution/mod.rs @@ -6,7 +6,7 @@ use crate::catalog::SchemaRef; use crate::{catalog::Catalog, planner::physical_plan::PhysicalPlan, storage::Tuple}; pub trait VolcanoExecutor { - fn init(&self, context: &mut ExecutionContext); + fn init(&self, context: &mut ExecutionContext) {} fn next(&self, context: &mut ExecutionContext) -> Option; fn output_schema(&self) -> SchemaRef; } diff --git a/bustubx/src/expression/mod.rs b/bustubx/src/expression/mod.rs index bdfb96b..68f4230 100644 --- a/bustubx/src/expression/mod.rs +++ b/bustubx/src/expression/mod.rs @@ -1,9 +1,3 @@ -use crate::catalog::DataType; -use crate::catalog::Schema; -use crate::common::ScalarValue; -use crate::error::BustubxResult; -use crate::storage::Tuple; - mod alias; mod binary; mod column; @@ -14,6 +8,13 @@ pub use binary::{BinaryExpr, BinaryOp}; pub use column::ColumnExpr; pub use literal::Literal; +use crate::catalog::DataType; +use crate::catalog::Schema; +use crate::common::ScalarValue; +use crate::storage::Tuple; +use crate::BustubxError; +use crate::BustubxResult; + pub trait ExprTrait { /// Get the data type of this expression, given the schema of the input fn data_type(&self, input_schema: &Schema) -> BustubxResult; @@ -53,3 +54,20 @@ impl ExprTrait for Expr { } } } + +impl TryFrom<&sqlparser::ast::Expr> for Expr { + type Error = BustubxError; + + fn try_from(value: &sqlparser::ast::Expr) -> Result { + match value { + sqlparser::ast::Expr::Value(value) => todo!(), + sqlparser::ast::Expr::BinaryOp { left, op, right } => todo!(), + sqlparser::ast::Expr::Identifier(ident) => todo!(), + sqlparser::ast::Expr::CompoundIdentifier(idents) => todo!(), + _ => Err(BustubxError::NotSupport(format!( + "sqlparser expr not supported: {}", + value + ))), + } + } +} diff --git a/bustubx/src/planner/logical_planner/mod.rs b/bustubx/src/planner/logical_planner/mod.rs index 14d034e..1ec1def 100644 --- a/bustubx/src/planner/logical_planner/mod.rs +++ b/bustubx/src/planner/logical_planner/mod.rs @@ -1,7 +1,7 @@ -mod bind_create_table; -mod bind_insert; -mod bind_select; mod logical_planner; mod plan_create_index; +mod plan_create_table; +mod plan_insert; +mod plan_select; pub use logical_planner::{LogicalPlanner, PlannerContext}; diff --git a/bustubx/src/planner/logical_planner/bind_create_table.rs b/bustubx/src/planner/logical_planner/plan_create_table.rs similarity index 100% rename from bustubx/src/planner/logical_planner/bind_create_table.rs rename to bustubx/src/planner/logical_planner/plan_create_table.rs diff --git a/bustubx/src/planner/logical_planner/bind_insert.rs b/bustubx/src/planner/logical_planner/plan_insert.rs similarity index 100% rename from bustubx/src/planner/logical_planner/bind_insert.rs rename to bustubx/src/planner/logical_planner/plan_insert.rs diff --git a/bustubx/src/planner/logical_planner/bind_select.rs b/bustubx/src/planner/logical_planner/plan_select.rs similarity index 100% rename from bustubx/src/planner/logical_planner/bind_select.rs rename to bustubx/src/planner/logical_planner/plan_select.rs diff --git a/bustubx/src/planner/physical_plan/create_index.rs b/bustubx/src/planner/physical_plan/create_index.rs index 3999ec7..4e36412 100644 --- a/bustubx/src/planner/physical_plan/create_index.rs +++ b/bustubx/src/planner/physical_plan/create_index.rs @@ -15,9 +15,6 @@ pub struct PhysicalCreateIndex { } impl VolcanoExecutor for PhysicalCreateIndex { - fn init(&self, context: &mut ExecutionContext) { - println!("init create index executor"); - } fn next(&self, context: &mut ExecutionContext) -> Option { context.catalog.create_index( self.index_name.clone(), @@ -33,3 +30,9 @@ impl VolcanoExecutor for PhysicalCreateIndex { )) } } + +impl std::fmt::Display for PhysicalCreateIndex { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/create_table.rs b/bustubx/src/planner/physical_plan/create_table.rs index 8ae600c..bf1a44b 100644 --- a/bustubx/src/planner/physical_plan/create_table.rs +++ b/bustubx/src/planner/physical_plan/create_table.rs @@ -13,9 +13,6 @@ pub struct PhysicalCreateTable { } impl VolcanoExecutor for PhysicalCreateTable { - fn init(&self, context: &mut ExecutionContext) { - println!("init create table executor"); - } fn next(&self, context: &mut ExecutionContext) -> Option { context .catalog @@ -26,3 +23,9 @@ impl VolcanoExecutor for PhysicalCreateTable { Arc::new(self.schema.clone()) } } + +impl std::fmt::Display for PhysicalCreateTable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/dummy.rs b/bustubx/src/planner/physical_plan/dummy.rs new file mode 100644 index 0000000..4146682 --- /dev/null +++ b/bustubx/src/planner/physical_plan/dummy.rs @@ -0,0 +1,23 @@ +use crate::catalog::{Schema, SchemaRef}; +use crate::execution::{ExecutionContext, VolcanoExecutor}; +use crate::Tuple; +use std::sync::Arc; + +#[derive(Debug)] +pub struct Dummy; + +impl VolcanoExecutor for Dummy { + fn next(&self, context: &mut ExecutionContext) -> Option { + None + } + + fn output_schema(&self) -> SchemaRef { + Arc::new(Schema::empty()) + } +} + +impl std::fmt::Display for Dummy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Dummy") + } +} diff --git a/bustubx/src/planner/physical_plan/filter.rs b/bustubx/src/planner/physical_plan/filter.rs index 11076cc..1ffe3fb 100644 --- a/bustubx/src/planner/physical_plan/filter.rs +++ b/bustubx/src/planner/physical_plan/filter.rs @@ -21,6 +21,7 @@ impl VolcanoExecutor for PhysicalFilter { println!("init filter executor"); self.input.init(context); } + fn next(&self, context: &mut ExecutionContext) -> Option { loop { let next_tuple = self.input.next(context); @@ -44,3 +45,9 @@ impl VolcanoExecutor for PhysicalFilter { self.input.output_schema() } } + +impl std::fmt::Display for PhysicalFilter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/insert.rs b/bustubx/src/planner/physical_plan/insert.rs index 97b9041..72d9bd5 100644 --- a/bustubx/src/planner/physical_plan/insert.rs +++ b/bustubx/src/planner/physical_plan/insert.rs @@ -79,3 +79,9 @@ impl VolcanoExecutor for PhysicalInsert { )])) } } + +impl std::fmt::Display for PhysicalInsert { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/limit.rs b/bustubx/src/planner/physical_plan/limit.rs index e592e8f..24e13d4 100644 --- a/bustubx/src/planner/physical_plan/limit.rs +++ b/bustubx/src/planner/physical_plan/limit.rs @@ -63,3 +63,9 @@ impl VolcanoExecutor for PhysicalLimit { self.input.output_schema() } } + +impl std::fmt::Display for PhysicalLimit { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/mod.rs b/bustubx/src/planner/physical_plan/mod.rs index 6f76199..da1c477 100644 --- a/bustubx/src/planner/physical_plan/mod.rs +++ b/bustubx/src/planner/physical_plan/mod.rs @@ -1,14 +1,6 @@ -use std::sync::Arc; - -use crate::catalog::SchemaRef; -use crate::{ - catalog::Schema, - execution::{ExecutionContext, VolcanoExecutor}, - storage::Tuple, -}; - mod create_index; mod create_table; +mod dummy; mod filter; mod insert; mod limit; @@ -20,6 +12,7 @@ mod values; pub use create_index::PhysicalCreateIndex; pub use create_table::PhysicalCreateTable; +pub use dummy::Dummy; pub use filter::PhysicalFilter; pub use insert::PhysicalInsert; pub use limit::PhysicalLimit; @@ -29,9 +22,15 @@ pub use seq_scan::PhysicalSeqScan; pub use sort::PhysicalSort; pub use values::PhysicalValues; +use crate::catalog::SchemaRef; +use crate::{ + execution::{ExecutionContext, VolcanoExecutor}, + storage::Tuple, +}; + #[derive(Debug)] pub enum PhysicalPlan { - Dummy, + Dummy(Dummy), CreateTable(PhysicalCreateTable), CreateIndex(PhysicalCreateIndex), Project(PhysicalProject), @@ -47,7 +46,7 @@ pub enum PhysicalPlan { impl VolcanoExecutor for PhysicalPlan { fn init(&self, context: &mut ExecutionContext) { match self { - PhysicalPlan::Dummy => {} + PhysicalPlan::Dummy(op) => op.init(context), PhysicalPlan::CreateTable(op) => op.init(context), PhysicalPlan::CreateIndex(op) => op.init(context), PhysicalPlan::Insert(op) => op.init(context), @@ -63,7 +62,7 @@ impl VolcanoExecutor for PhysicalPlan { fn next(&self, context: &mut ExecutionContext) -> Option { match self { - PhysicalPlan::Dummy => None, + PhysicalPlan::Dummy(op) => op.next(context), PhysicalPlan::CreateTable(op) => op.next(context), PhysicalPlan::CreateIndex(op) => op.next(context), PhysicalPlan::Insert(op) => op.next(context), @@ -79,7 +78,7 @@ impl VolcanoExecutor for PhysicalPlan { fn output_schema(&self) -> SchemaRef { match self { - Self::Dummy => Arc::new(Schema::new(vec![])), + Self::Dummy(op) => op.output_schema(), Self::CreateTable(op) => op.output_schema(), Self::CreateIndex(op) => op.output_schema(), Self::Insert(op) => op.output_schema(), @@ -93,3 +92,21 @@ impl VolcanoExecutor for PhysicalPlan { } } } + +impl std::fmt::Display for PhysicalPlan { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Dummy(op) => write!(f, "{op}"), + Self::CreateTable(op) => write!(f, "{op}"), + Self::CreateIndex(op) => write!(f, "{op}"), + Self::Insert(op) => write!(f, "{op}"), + Self::Values(op) => write!(f, "{op}"), + Self::Project(op) => write!(f, "{op}"), + Self::Filter(op) => write!(f, "{op}"), + Self::TableScan(op) => write!(f, "{op}"), + Self::Limit(op) => write!(f, "{op}"), + Self::NestedLoopJoin(op) => write!(f, "{op}"), + Self::Sort(op) => write!(f, "{op}"), + } + } +} diff --git a/bustubx/src/planner/physical_plan/nested_loop_join.rs b/bustubx/src/planner/physical_plan/nested_loop_join.rs index b218ce9..8788073 100644 --- a/bustubx/src/planner/physical_plan/nested_loop_join.rs +++ b/bustubx/src/planner/physical_plan/nested_loop_join.rs @@ -102,3 +102,9 @@ impl VolcanoExecutor for PhysicalNestedLoopJoin { ) } } + +impl std::fmt::Display for PhysicalNestedLoopJoin { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/project.rs b/bustubx/src/planner/physical_plan/project.rs index c9d0906..f666927 100644 --- a/bustubx/src/planner/physical_plan/project.rs +++ b/bustubx/src/planner/physical_plan/project.rs @@ -15,11 +15,13 @@ pub struct PhysicalProject { pub expressions: Vec, pub input: Arc, } + impl VolcanoExecutor for PhysicalProject { fn init(&self, context: &mut ExecutionContext) { println!("init project executor"); self.input.init(context); } + fn next(&self, context: &mut ExecutionContext) -> Option { let next_tuple = self.input.next(context); if next_tuple.is_none() { @@ -37,3 +39,9 @@ impl VolcanoExecutor for PhysicalProject { self.input.output_schema() } } + +impl std::fmt::Display for PhysicalProject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/seq_scan.rs b/bustubx/src/planner/physical_plan/seq_scan.rs index 2817bf2..6ff914f 100644 --- a/bustubx/src/planner/physical_plan/seq_scan.rs +++ b/bustubx/src/planner/physical_plan/seq_scan.rs @@ -14,6 +14,7 @@ pub struct PhysicalSeqScan { iterator: Mutex, } + impl PhysicalSeqScan { pub fn new(table_oid: TableOid, columns: Vec) -> Self { PhysicalSeqScan { @@ -23,6 +24,7 @@ impl PhysicalSeqScan { } } } + impl VolcanoExecutor for PhysicalSeqScan { fn init(&self, context: &mut ExecutionContext) { println!("init table scan executor"); @@ -50,3 +52,9 @@ impl VolcanoExecutor for PhysicalSeqScan { }) } } + +impl std::fmt::Display for PhysicalSeqScan { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/sort.rs b/bustubx/src/planner/physical_plan/sort.rs index 3cc3dde..f19f017 100644 --- a/bustubx/src/planner/physical_plan/sort.rs +++ b/bustubx/src/planner/physical_plan/sort.rs @@ -84,3 +84,9 @@ impl VolcanoExecutor for PhysicalSort { self.input.output_schema() } } + +impl std::fmt::Display for PhysicalSort { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_plan/values.rs b/bustubx/src/planner/physical_plan/values.rs index ad5628f..1c3c7e1 100644 --- a/bustubx/src/planner/physical_plan/values.rs +++ b/bustubx/src/planner/physical_plan/values.rs @@ -26,20 +26,16 @@ impl PhysicalValues { } } impl VolcanoExecutor for PhysicalValues { - fn init(&self, context: &mut ExecutionContext) { - println!("init values executor"); - self.cursor.store(0, std::sync::atomic::Ordering::SeqCst); - } fn next(&self, context: &mut ExecutionContext) -> Option { let cursor = self .cursor .fetch_add(1, std::sync::atomic::Ordering::SeqCst) as usize; - if cursor < self.tuples.len() { + return if cursor < self.tuples.len() { let values = self.tuples[cursor].clone(); - return Some(Tuple::new(self.output_schema(), values)); + Some(Tuple::new(self.output_schema(), values)) } else { - return None; - } + None + }; } fn output_schema(&self) -> SchemaRef { @@ -48,3 +44,9 @@ impl VolcanoExecutor for PhysicalValues { }) } } + +impl std::fmt::Display for PhysicalValues { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } +} diff --git a/bustubx/src/planner/physical_planner/physical_planner.rs b/bustubx/src/planner/physical_planner/physical_planner.rs index 3da2cb1..af27bec 100644 --- a/bustubx/src/planner/physical_planner/physical_planner.rs +++ b/bustubx/src/planner/physical_planner/physical_planner.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use crate::planner::logical_plan::LogicalPlan; use crate::planner::operator::LogicalOperator; -use crate::planner::physical_plan::PhysicalCreateIndex; use crate::planner::physical_plan::PhysicalCreateTable; use crate::planner::physical_plan::PhysicalFilter; use crate::planner::physical_plan::PhysicalInsert; @@ -14,6 +13,7 @@ use crate::planner::physical_plan::PhysicalProject; use crate::planner::physical_plan::PhysicalSeqScan; use crate::planner::physical_plan::PhysicalSort; use crate::planner::physical_plan::PhysicalValues; +use crate::planner::physical_plan::{Dummy, PhysicalCreateIndex}; pub struct PhysicalPlanner; @@ -30,7 +30,7 @@ impl PhysicalPlanner { pub fn build_plan(logical_plan: Arc) -> PhysicalPlan { let plan = match logical_plan.operator { - LogicalOperator::Dummy => PhysicalPlan::Dummy, + LogicalOperator::Dummy => PhysicalPlan::Dummy(Dummy {}), LogicalOperator::CreateTable(ref logic_create_table) => { PhysicalPlan::CreateTable(PhysicalCreateTable::new( logic_create_table.table_name.clone(),