use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum QueryExecutionState {
#[default]
Pending,
Running,
Completed,
Failed,
Cancelled,
Timeout,
}
impl QueryExecutionState {
pub fn is_terminal(&self) -> bool {
matches!(
self,
QueryExecutionState::Completed
| QueryExecutionState::Failed
| QueryExecutionState::Cancelled
| QueryExecutionState::Timeout
)
}
pub fn can_cancel(&self) -> bool {
matches!(
self,
QueryExecutionState::Pending | QueryExecutionState::Running
)
}
pub fn description(&self) -> &'static str {
match self {
QueryExecutionState::Pending => "Pending",
QueryExecutionState::Running => "Running",
QueryExecutionState::Completed => "Completed",
QueryExecutionState::Failed => "Failed",
QueryExecutionState::Cancelled => "Cancelled",
QueryExecutionState::Timeout => "Timeout",
}
}
}
impl fmt::Display for QueryExecutionState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum ExecutorState {
#[default]
Initialized,
Executing,
Completed,
Failed,
Cancelled,
Paused,
}
impl ExecutorState {
pub fn can_transition_to(&self, target: ExecutorState) -> bool {
match (self, target) {
(ExecutorState::Initialized, ExecutorState::Executing) => true,
(ExecutorState::Initialized, ExecutorState::Failed) => true,
(ExecutorState::Initialized, ExecutorState::Cancelled) => true,
(ExecutorState::Executing, ExecutorState::Completed) => true,
(ExecutorState::Executing, ExecutorState::Failed) => true,
(ExecutorState::Executing, ExecutorState::Cancelled) => true,
(ExecutorState::Executing, ExecutorState::Paused) => true,
(ExecutorState::Paused, ExecutorState::Executing) => true,
(ExecutorState::Paused, ExecutorState::Failed) => true,
(ExecutorState::Paused, ExecutorState::Cancelled) => true,
(ExecutorState::Completed, _) => false,
(ExecutorState::Failed, _) => false,
(ExecutorState::Cancelled, _) => false,
_ => false,
}
}
pub fn description(&self) -> &'static str {
match self {
ExecutorState::Initialized => "Initialized",
ExecutorState::Executing => "Executing",
ExecutorState::Completed => "Completed",
ExecutorState::Failed => "Failed",
ExecutorState::Cancelled => "Cancelled",
ExecutorState::Paused => "Paused",
}
}
}
impl fmt::Display for ExecutorState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub enum LoopExecutionState {
#[default]
NotStarted,
Running { iteration: usize },
Finished,
Error(String),
MaxIterationsReached { max: usize },
}
impl LoopExecutionState {
pub fn iteration(&self) -> Option<usize> {
match self {
LoopExecutionState::Running { iteration } => Some(*iteration),
_ => None,
}
}
pub fn is_finished(&self) -> bool {
matches!(
self,
LoopExecutionState::Finished
| LoopExecutionState::Error(_)
| LoopExecutionState::MaxIterationsReached { .. }
)
}
pub fn description(&self) -> String {
match self {
LoopExecutionState::NotStarted => "Not Started".to_string(),
LoopExecutionState::Running { iteration } => {
format!("Running (iteration {})", iteration)
}
LoopExecutionState::Finished => "Finished".to_string(),
LoopExecutionState::Error(msg) => format!("Error: {}", msg),
LoopExecutionState::MaxIterationsReached { max } => {
format!("Max iterations reached ({})", max)
}
}
}
}
impl fmt::Display for LoopExecutionState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum RowStatus {
#[default]
Valid,
Filtered,
Invalid,
TagFiltered,
}
impl RowStatus {
pub fn is_valid(&self) -> bool {
matches!(self, RowStatus::Valid)
}
pub fn to_i32(&self) -> i32 {
match self {
RowStatus::Valid => 0,
RowStatus::Invalid => -1,
RowStatus::Filtered => -2,
RowStatus::TagFiltered => -3,
}
}
}
impl fmt::Display for RowStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RowStatus::Valid => write!(f, "Effective"),
RowStatus::Filtered => write!(f, "Filtered"),
RowStatus::Invalid => write!(f, "Invalid"),
RowStatus::TagFiltered => write!(f, "Tag filtering"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum OptimizationState {
#[default]
NotStarted,
Rewriting,
LogicalOptimizing,
PhysicalOptimizing,
Completed,
Failed,
}
impl OptimizationState {
pub fn description(&self) -> &'static str {
match self {
OptimizationState::NotStarted => "Not Started",
OptimizationState::Rewriting => "Rewriting Phase",
OptimizationState::LogicalOptimizing => "Logical Optimizing",
OptimizationState::PhysicalOptimizing => "Physical Optimizing",
OptimizationState::Completed => "Completed",
OptimizationState::Failed => "Failed",
}
}
pub fn is_optimizing(&self) -> bool {
matches!(
self,
OptimizationState::Rewriting
| OptimizationState::LogicalOptimizing
| OptimizationState::PhysicalOptimizing
)
}
}
impl fmt::Display for OptimizationState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum OptimizationPhase {
Rewrite,
Logical,
Physical,
#[default]
Unknown,
}
impl OptimizationPhase {
pub fn description(&self) -> &'static str {
match self {
OptimizationPhase::Rewrite => "Rewrite Phase",
OptimizationPhase::Logical => "Logical Optimizing",
OptimizationPhase::Physical => "Physical Optimizing",
OptimizationPhase::Unknown => "Unknown Phase",
}
}
pub fn is_logical(&self) -> bool {
matches!(
self,
OptimizationPhase::Rewrite | OptimizationPhase::Logical
)
}
pub fn is_physical(&self) -> bool {
matches!(self, OptimizationPhase::Physical)
}
}
impl fmt::Display for OptimizationPhase {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_query_execution_state_transitions() {
assert!(!QueryExecutionState::Running.is_terminal());
assert!(QueryExecutionState::Completed.is_terminal());
assert!(QueryExecutionState::Pending.can_cancel());
assert!(!QueryExecutionState::Completed.can_cancel());
}
#[test]
fn test_executor_state_transitions() {
assert!(ExecutorState::Initialized.can_transition_to(ExecutorState::Executing));
assert!(!ExecutorState::Completed.can_transition_to(ExecutorState::Executing));
assert!(ExecutorState::Executing.can_transition_to(ExecutorState::Paused));
assert!(ExecutorState::Paused.can_transition_to(ExecutorState::Executing));
}
#[test]
fn test_loop_execution_state() {
let state = LoopExecutionState::Running { iteration: 5 };
assert_eq!(state.iteration(), Some(5));
assert!(!state.is_finished());
let finished = LoopExecutionState::Finished;
assert!(finished.is_finished());
}
#[test]
fn test_row_status_conversion() {
assert_eq!(RowStatus::Valid.to_i32(), 0);
assert_eq!(RowStatus::Invalid.to_i32(), -1);
assert_eq!(RowStatus::Filtered.to_i32(), -2);
assert_eq!(RowStatus::TagFiltered.to_i32(), -3);
}
}