linkrs_query/optimizer/
error.rs1use thiserror::Error;
10
11use crate::planning::plan::factorization::FactorizationError;
12
13#[derive(Error, Debug, Clone)]
15pub enum OptimizeError {
16 #[error("Unsupported node type: {0}")]
18 UnsupportedNodeType(String),
19
20 #[error("Missing statistics: {0}")]
22 MissingStatistics(String),
23
24 #[error("Calculation error: {0}")]
26 CalculationError(String),
27
28 #[error("Plan optimization error: {0}")]
30 PlanOptimizationError(String),
31
32 #[error("Rule application error: {0}")]
34 RuleApplicationError(String),
35
36 #[error("Statistics error: {0}")]
38 StatisticsError(String),
39
40 #[error("Index selection error: {0}")]
42 IndexSelectionError(String),
43
44 #[error("Join order optimization error: {0}")]
46 JoinOrderError(String),
47
48 #[error("Expression transform error: {0}")]
50 ExpressionTransformError(String),
51
52 #[error("Internal optimization error: {0}")]
54 InternalError(String),
55
56 #[error("Heuristic optimization failed: {0}")]
58 HeuristicFailed(String),
59
60 #[error("Cost-based optimization failed: {0}")]
62 CostBasedFailed(String),
63
64 #[error("Pipeline configuration error: {0}")]
66 ConfigurationError(String),
67
68 #[error("Factorization error: {0}")]
75 FactorizationError(
76 #[from]
77 #[source]
78 FactorizationError,
79 ),
80}
81
82pub type OptimizeResult<T> = Result<T, OptimizeError>;
84
85#[derive(Error, Debug, Clone)]
87pub enum CostError {
88 #[error("Unsupported node type: {0}")]
90 UnsupportedNodeType(String),
91
92 #[error("Missing statistics: {0}")]
94 MissingStatistics(String),
95
96 #[error("Calculation error: {0}")]
98 CalculationError(String),
99}
100
101pub type CostResult<T> = Result<T, CostError>;
103
104impl From<CostError> for OptimizeError {
105 fn from(err: CostError) -> Self {
106 match err {
107 CostError::UnsupportedNodeType(msg) => OptimizeError::UnsupportedNodeType(msg),
108 CostError::MissingStatistics(msg) => OptimizeError::MissingStatistics(msg),
109 CostError::CalculationError(msg) => OptimizeError::CalculationError(msg),
110 }
111 }
112}
113
114#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_optimize_error_display() {
127 let err = OptimizeError::UnsupportedNodeType("UnknownNode".to_string());
128 assert!(err.to_string().contains("Unsupported node type"));
129
130 let err = OptimizeError::MissingStatistics("vertex_count".to_string());
131 assert!(err.to_string().contains("Missing statistics"));
132 }
133
134 #[test]
135 fn test_cost_error_conversion() {
136 let cost_err = CostError::CalculationError("division by zero".to_string());
137 let opt_err: OptimizeError = cost_err.into();
138 assert!(matches!(opt_err, OptimizeError::CalculationError(_)));
139 }
140
141 #[test]
142 fn test_factorization_error_preserves_structure() {
143 let fact_err = FactorizationError::TooManyUnflatGroups(3);
144 let opt_err: OptimizeError = fact_err.clone().into();
145 match &opt_err {
147 OptimizeError::FactorizationError(inner) => {
148 assert_eq!(*inner, fact_err);
149 assert_eq!(
150 inner.to_string(),
151 "at most one unflat group allowed, found 3"
152 );
153 }
154 other => panic!("expected FactorizationError, got {other:?}"),
155 }
156 assert!(opt_err.to_string().contains("found 3"));
158 let src = std::error::Error::source(&opt_err).expect("source wired");
159 assert!(src.downcast_ref::<FactorizationError>().is_some());
160 let _cloned = opt_err.clone();
162 }
163}