hematite-db 0.1.0

A small embeddable SQL database.
Documentation
//! Query plan structures and access-path descriptions.

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,
}