use crate::parser::ast::AggregateFunction;
use crate::parser::ast::{
AlterStatement, CreateIndexStatement, CreateStatement, DeleteStatement, DropIndexStatement,
DropStatement, InsertStatement, SelectStatement, UpdateStatement,
};
use super::optimizer::SelectOptimizations;
pub struct QueryPlan {
pub node: PlanNode,
pub program: ExecutionProgram,
pub estimated_cost: f64,
pub select_analysis: Option<SelectAnalysis>,
pub optimizations: Option<SelectOptimizations>,
}
impl std::fmt::Debug for QueryPlan {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("QueryPlan")
.field("node", &self.node)
.field("estimated_cost", &self.estimated_cost)
.field("select_analysis", &self.select_analysis)
.field("optimizations", &self.optimizations)
.field("program", &self.program)
.finish()
}
}
#[derive(Debug, Clone)]
pub enum ExecutionProgram {
Select {
statement: SelectStatement,
access_path: SelectAccessPath,
},
Insert {
statement: InsertStatement,
},
Update {
statement: UpdateStatement,
access_path: SelectAccessPath,
},
Delete {
statement: DeleteStatement,
access_path: SelectAccessPath,
},
Create {
statement: CreateStatement,
},
CreateIndex {
statement: CreateIndexStatement,
},
Alter {
statement: AlterStatement,
},
Drop {
statement: DropStatement,
},
DropIndex {
statement: DropIndexStatement,
},
}
#[derive(Debug, Clone)]
pub enum PlanNode {
Select(SelectPlanNode),
Insert(InsertPlanNode),
Update(UpdatePlanNode),
Delete(DeletePlanNode),
Create(CreatePlanNode),
CreateIndex(CreateIndexPlanNode),
Alter(AlterPlanNode),
Drop(DropPlanNode),
DropIndex(DropIndexPlanNode),
}
#[derive(Debug, Clone)]
pub struct SelectPlanNode {
pub table_name: String,
pub source_count: usize,
pub access_path: SelectAccessPath,
pub projection: SelectProjection,
pub distinct: bool,
pub has_filter: bool,
pub order_by_columns: Vec<String>,
pub limit: Option<usize>,
pub offset: Option<usize>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SelectAccessPath {
FullTableScan,
JoinScan,
RowIdLookup,
PrimaryKeyLookup,
SecondaryIndexLookup(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SelectProjection {
Wildcard,
Columns(Vec<String>),
Expressions(usize),
CountAll,
Aggregate {
function: AggregateFunction,
column: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InsertPlanNode {
pub table_name: String,
pub row_count: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UpdatePlanNode {
pub table_name: String,
pub assignment_count: usize,
pub has_filter: bool,
pub access_path: SelectAccessPath,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeletePlanNode {
pub table_name: String,
pub has_filter: bool,
pub access_path: SelectAccessPath,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CreatePlanNode {
pub table_name: String,
pub column_count: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DropPlanNode {
pub table_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AlterPlanNode {
pub table_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CreateIndexPlanNode {
pub table_name: String,
pub index_name: String,
pub column_count: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DropIndexPlanNode {
pub table_name: String,
pub index_name: String,
}
#[derive(Debug, Clone)]
pub struct SelectAnalysis {
pub table_name: String,
pub source_count: usize,
pub has_complex_source: bool,
pub table_id: crate::catalog::TableId,
pub rowid_lookup: Option<u64>,
pub estimated_rows: usize,
pub usable_indexes: Vec<IndexUsage>,
pub accessed_columns: Vec<ColumnAccess>,
}
#[derive(Debug, Clone)]
pub struct IndexUsage {
pub column_id: crate::catalog::ColumnId,
pub index_type: IndexType,
pub index_name: Option<String>,
pub selectivity: f64,
}
#[derive(Debug, Clone)]
pub enum IndexType {
PrimaryKey,
Secondary,
}
#[derive(Debug, Clone)]
pub struct ColumnAccess {
pub column_id: crate::catalog::ColumnId,
pub access_type: ColumnAccessType,
}
#[derive(Debug, Clone)]
pub enum ColumnAccessType {
Read,
Write,
}