pgevolve_core/plan/
error.rs1use thiserror::Error;
4
5#[derive(Debug, Error, PartialEq, Eq)]
7pub enum PlanError {
8 #[error("unbreakable dependency cycle: {0:?}")]
12 UnbreakableCycle(Vec<String>),
13
14 #[error("unexpected cycle in modify graph after FK extraction: {0:?}")]
18 UnexpectedCycleAfterFkExtraction(Vec<String>),
19
20 #[error("unexpected cycle in drop graph: {0:?}")]
23 UnexpectedDropCycle(Vec<String>),
24
25 #[error("internal error: {0}")]
27 Internal(String),
28
29 #[error("body-derived dependency cycle: {}", format_node_chain(.nodes))]
37 BodyCycle {
38 nodes: Vec<crate::plan::edges::NodeId>,
40 },
41
42 #[error("AST resolution failed during planning: {0}")]
45 AstResolution(String),
46
47 #[error(
55 "view_drop_create_dependents is disabled but the following views would be \
56 force-recreated: {}", .views.iter().map(ToString::to_string).collect::<Vec<_>>().join(", ")
57 )]
58 DependentViewsBlocked {
59 views: Vec<crate::identifier::QualifiedName>,
61 },
62}
63
64fn format_node_chain(nodes: &[crate::plan::edges::NodeId]) -> String {
65 nodes
66 .iter()
67 .map(render_node)
68 .collect::<Vec<_>>()
69 .join(" \u{2192} ")
70}
71
72fn render_node(n: &crate::plan::edges::NodeId) -> String {
73 use crate::plan::edges::NodeId::{
74 Aggregate, Cast, Collation, Constraint, EventTrigger, Extension, Function, Index, Mv,
75 Procedure, Publication, Schema, Sequence, Statistic, Subscription, Table, Trigger,
76 TsConfiguration, TsDictionary, Type, View,
77 };
78 match n {
79 Schema(s) | Extension(s) | Publication(s) | Subscription(s) | EventTrigger(s) => {
80 s.as_str().to_string()
81 }
82 Table(q) | Index(q) | Sequence(q) | View(q) | Mv(q) | Type(q) | Procedure(q)
83 | Statistic(q) | Collation(q) => q.to_string(),
84 Trigger(qname) => format!("trigger {qname}"),
85 Constraint { table, name } => format!("{}.{}", table, name.as_str()),
86 Function(q, args) | Aggregate(q, args) => format!(
87 "{}({})",
88 q,
89 args.types
90 .iter()
91 .map(crate::ir::column_type::ColumnType::render_sql)
92 .collect::<Vec<_>>()
93 .join(",")
94 ),
95 Cast(src, tgt) => format!("cast({src} as {tgt})"),
96 TsDictionary(q) => format!("ts_dictionary:{}", q.render_sql()),
97 TsConfiguration(q) => format!("ts_configuration:{}", q.render_sql()),
98 }
99}