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