pub mod dialect;
pub mod parsers;
#[cfg(feature = "perf-baseline")]
pub mod perf_baseline;
#[cfg(feature = "explain-analyzer")]
pub mod regression;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExplainDialect {
MySql,
Postgres,
Sqlite,
Oracle,
Mssql,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "explain-analyzer",
derive(serde::Serialize, serde::Deserialize)
)]
pub enum ScanType {
FullTable,
IndexRange,
IndexLookup,
UniqueLookup,
Other,
}
impl ScanType {
pub fn is_full_table_scan(&self) -> bool {
matches!(self, ScanType::FullTable)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "explain-analyzer",
derive(serde::Serialize, serde::Deserialize)
)]
pub struct ExplainPlan {
pub scan_type: ScanType,
pub table: String,
pub index: Option<String>,
pub rows: u64,
pub extra: Vec<String>,
}
impl ExplainPlan {
pub fn missing_index(&self, row_threshold: u64) -> bool {
self.index.is_none() && (self.scan_type.is_full_table_scan() || self.rows >= row_threshold)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExplainError {
Unparseable { reason: String },
UnsupportedDialect,
}
impl std::fmt::Display for ExplainError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ExplainError::Unparseable { reason } => {
write!(f, "unparseable explain output: {reason}")
}
ExplainError::UnsupportedDialect => {
write!(f, "unsupported dialect for explain parsing")
}
}
}
}
impl std::error::Error for ExplainError {}
pub trait ExplainParser: Send + Sync + std::fmt::Debug {
fn parse(&self, raw: &str) -> Result<ExplainPlan, ExplainError>;
}
pub fn parser_for(dialect: ExplainDialect) -> Result<Box<dyn ExplainParser>, ExplainError> {
match dialect {
ExplainDialect::MySql => Ok(Box::new(parsers::mysql::MySqlParser)),
ExplainDialect::Postgres => Ok(Box::new(parsers::postgres::PostgresParser)),
ExplainDialect::Sqlite => Ok(Box::new(parsers::sqlite::SqliteParser)),
ExplainDialect::Oracle => Ok(Box::new(parsers::oracle::OracleParser)),
ExplainDialect::Mssql => Ok(Box::new(parsers::mssql::MssqlParser)),
}
}