mz_adapter/catalog/builtin_table_updates/
notice.rs1use std::sync::Arc;
11
12use mz_catalog::builtin::BuiltinTable;
13use mz_catalog::builtin::notice::MZ_OPTIMIZER_NOTICES;
14use mz_repr::{Datum, Diff, GlobalId, Row};
15use mz_transform::dataflow::DataflowMetainfo;
16use mz_transform::notice::{
17 Action, ActionKind, OptimizerNotice, OptimizerNoticeApi, OptimizerNoticeKind,
18 RawOptimizerNotice,
19};
20
21use crate::catalog::{BuiltinTableUpdate, Catalog, CatalogState};
22
23impl Catalog {
24 pub fn render_notices(
27 &self,
28 df_meta: DataflowMetainfo<RawOptimizerNotice>,
29 notice_ids: Vec<GlobalId>,
30 item_id: Option<GlobalId>,
31 ) -> DataflowMetainfo<Arc<OptimizerNotice>> {
32 assert_eq!(notice_ids.len(), df_meta.optimizer_notices.len());
34
35 fn some_if_neq<T: Eq>(x: T, y: &T) -> Option<T> {
37 if &x != y { Some(x) } else { None }
38 }
39
40 let conn_catalog = self.for_system_session();
43
44 let optimizer_notices = std::iter::zip(df_meta.optimizer_notices, notice_ids)
45 .map(|(notice, id)| {
46 let message = notice.message(&conn_catalog, false).to_string();
48 let hint = notice.hint(&conn_catalog, false).to_string();
49 let action = match notice.action_kind(&conn_catalog) {
50 ActionKind::SqlStatements => {
51 Action::SqlStatements(notice.action(&conn_catalog, false).to_string())
52 }
53 ActionKind::PlainText => {
54 Action::PlainText(notice.action(&conn_catalog, false).to_string())
55 }
56 ActionKind::None => {
57 Action::None }
59 };
60 let message_redacted = notice.message(&conn_catalog, true).to_string();
62 let hint_redacted = notice.hint(&conn_catalog, true).to_string();
63 let action_redacted = match notice.action_kind(&conn_catalog) {
64 ActionKind::SqlStatements => {
65 Action::SqlStatements(notice.action(&conn_catalog, true).to_string())
66 }
67 ActionKind::PlainText => {
68 Action::PlainText(notice.action(&conn_catalog, true).to_string())
69 }
70 ActionKind::None => {
71 Action::None }
73 };
74 OptimizerNotice {
76 id,
77 kind: OptimizerNoticeKind::from(¬ice),
78 item_id,
79 dependencies: notice.dependencies(),
80 message_redacted: some_if_neq(message_redacted, &message),
81 hint_redacted: some_if_neq(hint_redacted, &hint),
82 action_redacted: some_if_neq(action_redacted, &action),
83 message,
84 hint,
85 action,
86 created_at: (self.config().now)(),
87 }
88 })
89 .map(From::from) .collect();
91
92 DataflowMetainfo {
93 optimizer_notices,
94 index_usage_types: df_meta.index_usage_types,
95 }
96 }
97}
98
99impl CatalogState {
100 pub(crate) fn pack_optimizer_notices<'a>(
103 &self,
104 updates: &mut Vec<BuiltinTableUpdate>,
105 notices: impl Iterator<Item = &'a Arc<OptimizerNotice>>,
106 diff: Diff,
107 ) {
108 let mut resolved = Vec::new();
109 self.pack_optimizer_notice_updates(&mut resolved, notices, diff);
110 updates.extend(self.resolve_builtin_table_updates(resolved));
111 }
112
113 pub(crate) fn pack_optimizer_notice_updates<'a>(
116 &self,
117 updates: &mut Vec<BuiltinTableUpdate<&'static BuiltinTable>>,
118 notices: impl Iterator<Item = &'a Arc<OptimizerNotice>>,
119 diff: Diff,
120 ) {
121 let mut row = Row::default();
122
123 for notice in notices {
124 let mut packer = row.packer();
125
126 let id = notice.id.to_string();
129 let item_id = notice.item_id.as_ref().map(ToString::to_string);
130 let deps = notice
131 .dependencies
132 .iter()
133 .map(ToString::to_string)
134 .collect::<Vec<_>>();
135 let created_at = mz_ore::now::to_datetime(notice.created_at)
136 .try_into()
137 .expect("must fit");
138
139 packer.push(Datum::String(id.as_str()));
141 packer.push(Datum::String(notice.kind.as_str()));
143 packer.push(Datum::String(¬ice.message));
145 packer.push(Datum::String(¬ice.hint));
147 packer.push(match ¬ice.action {
149 Action::None => Datum::Null,
150 Action::PlainText(text) => Datum::String(text),
151 Action::SqlStatements(text) => Datum::String(text),
152 });
153 packer.push(match notice.message_redacted.as_deref() {
155 Some(message_redacted) => Datum::String(message_redacted),
156 None => Datum::Null,
157 });
158 packer.push(match notice.hint_redacted.as_deref() {
160 Some(hint_redacted) => Datum::String(hint_redacted),
161 None => Datum::Null,
162 });
163 packer.push(match notice.action_redacted.as_ref() {
165 Some(action_redacted) => match action_redacted {
166 Action::None => Datum::Null,
167 Action::PlainText(text) => Datum::String(text),
168 Action::SqlStatements(text) => Datum::String(text),
169 },
170 None => Datum::Null,
171 });
172 packer.push(match ¬ice.action {
174 Action::None => Datum::Null,
175 action => Datum::String(action.kind().as_str()),
176 });
177 packer.push(match item_id.as_ref() {
179 Some(item_id) => Datum::String(item_id),
180 None => Datum::Null,
181 });
182 packer.push_list(deps.iter().map(|d| Datum::String(d)));
184 packer.push(Datum::TimestampTz(created_at));
186
187 updates.push(BuiltinTableUpdate::row(
188 &*MZ_OPTIMIZER_NOTICES,
189 row.clone(),
190 diff,
191 ));
192 }
193 }
194}