mz_transform/notice/
index_already_exists.rs1use std::collections::BTreeSet;
13use std::fmt;
14
15use mz_expr::MirScalarExpr;
16use mz_expr::explain::{HumanizedNotice, HumanizerMode};
17use mz_ore::str::separated;
18use mz_repr::GlobalId;
19use mz_repr::explain::ExprHumanizer;
20
21use crate::notice::{ActionKind, OptimizerNoticeApi};
22
23#[derive(Clone, Debug, Eq, PartialEq, Hash)]
25pub struct IndexAlreadyExists {
26 pub index_id: GlobalId,
28 pub index_key: Vec<MirScalarExpr>,
30 pub index_on_id: GlobalId,
32 pub exported_index_id: GlobalId,
34}
35
36impl OptimizerNoticeApi for IndexAlreadyExists {
37 fn dependencies(&self) -> BTreeSet<GlobalId> {
38 BTreeSet::from([self.index_id, self.index_on_id])
39 }
40
41 fn fmt_message(
42 &self,
43 f: &mut fmt::Formatter<'_>,
44 humanizer: &dyn ExprHumanizer,
45 redacted: bool,
46 ) -> fmt::Result {
47 let exported_index_name = humanizer
48 .humanize_id(self.exported_index_id)
49 .unwrap_or_else(|| self.exported_index_id.to_string());
50 let index_name = humanizer
51 .humanize_id(self.index_id)
52 .unwrap_or_else(|| self.index_id.to_string());
53 let index_on_id_name = humanizer
54 .humanize_id_unqualified(self.index_on_id)
55 .unwrap_or_else(|| self.index_on_id.to_string());
56
57 let mode = HumanizedNotice::new(redacted);
58 let col_names = humanizer.column_names_for_id(self.index_on_id);
59 let col_names = col_names.as_ref();
60 let index_key = separated(", ", mode.seq(&self.index_key, col_names));
61
62 write!(
63 f,
64 "Index {exported_index_name} is identical to {index_name}, which \
65 is also defined on {index_on_id_name}({index_key})."
66 )
67 }
68
69 fn fmt_hint(
70 &self,
71 f: &mut fmt::Formatter<'_>,
72 humanizer: &dyn ExprHumanizer,
73 redacted: bool,
74 ) -> fmt::Result {
75 let index_on_id_name = humanizer
76 .humanize_id_unqualified(self.index_on_id)
77 .unwrap_or_else(|| self.index_on_id.to_string());
78
79 let mode = HumanizedNotice::new(redacted);
80 let col_names = humanizer.column_names_for_id(self.index_on_id);
81 let col_names = col_names.as_ref();
82 let index_key = separated(", ", mode.seq(&self.index_key, col_names));
83
84 write!(
85 f,
86 "Please drop all indexes except the first index created on \
87 {index_on_id_name}({index_key}) and recreate all dependent objects."
88 )
89 }
90
91 fn fmt_action(
92 &self,
93 _f: &mut fmt::Formatter<'_>,
94 _humanizer: &dyn ExprHumanizer,
95 _redacted: bool,
96 ) -> fmt::Result {
97 Ok(())
98 }
99
100 fn action_kind(&self, _humanizer: &dyn ExprHumanizer) -> ActionKind {
101 ActionKind::None
102 }
103}