1use std::collections::BTreeMap;
11use std::sync::LazyLock;
12
13use mz_pgrepr::oid;
14use mz_repr::namespaces::MZ_INTERNAL_SCHEMA;
15use mz_repr::{RelationDesc, ScalarType};
16use mz_sql::catalog::NameReference;
17
18use crate::builtin::{Builtin, BuiltinIndex, BuiltinTable, BuiltinView, MONITOR_SELECT};
19
20use super::{MONITOR_REDACTED_SELECT, SUPPORT_SELECT};
21
22pub static MZ_OPTIMIZER_NOTICES: LazyLock<BuiltinTable> = LazyLock::new(|| {
23 use ScalarType::{List, String, TimestampTz};
24
25 BuiltinTable {
26 name: "mz_optimizer_notices",
27 schema: MZ_INTERNAL_SCHEMA,
28 oid: oid::TABLE_MZ_OPTIMIZER_NOTICES_OID,
29 desc: RelationDesc::builder()
30 .with_column("id", String.nullable(false))
31 .with_column("notice_type", String.nullable(false))
32 .with_column("message", String.nullable(false))
33 .with_column("hint", String.nullable(false))
34 .with_column("action", String.nullable(true))
35 .with_column("redacted_message", String.nullable(true))
36 .with_column("redacted_hint", String.nullable(true))
37 .with_column("redacted_action", String.nullable(true))
38 .with_column("action_type", String.nullable(true))
39 .with_column("object_id", String.nullable(true))
40 .with_column(
41 "dependency_ids",
42 List {
43 element_type: Box::new(String),
44 custom_id: None,
45 }
46 .nullable(false),
47 )
48 .with_column(
49 "created_at",
50 TimestampTz { precision: None }.nullable(false),
51 )
52 .with_key(vec![0])
53 .finish(),
54 column_comments: BTreeMap::new(),
55 is_retained_metrics_object: false,
56 access: vec![MONITOR_SELECT],
57 }
58});
59
60pub static MZ_NOTICES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
69 name: "mz_notices",
70 schema: MZ_INTERNAL_SCHEMA,
71 oid: oid::VIEW_MZ_NOTICES_OID,
72 desc: RelationDesc::builder()
73 .with_column("id", ScalarType::String.nullable(false))
74 .with_column("notice_type", ScalarType::String.nullable(false))
75 .with_column("message", ScalarType::String.nullable(false))
76 .with_column("hint", ScalarType::String.nullable(false))
77 .with_column("action", ScalarType::String.nullable(true))
78 .with_column("redacted_message", ScalarType::String.nullable(true))
79 .with_column("redacted_hint", ScalarType::String.nullable(true))
80 .with_column("redacted_action", ScalarType::String.nullable(true))
81 .with_column("action_type", ScalarType::String.nullable(true))
82 .with_column("object_id", ScalarType::String.nullable(true))
83 .with_column(
84 "created_at",
85 ScalarType::TimestampTz { precision: None }.nullable(false),
86 )
87 .with_key(vec![0])
88 .finish(),
89 column_comments: BTreeMap::from_iter([
90 ("id", "Materialize's unique ID for this notice."),
91 ("notice_type", "The notice type."),
92 (
93 "message",
94 "A brief description of the issue highlighted by this notice.",
95 ),
96 (
97 "hint",
98 "A high-level hint that tells the user what can be improved.",
99 ),
100 ("action", "A concrete action that will resolve the notice."),
101 (
102 "redacted_message",
103 "A redacted version of the `message` column. `NULL` if no redaction is needed.",
104 ),
105 (
106 "redacted_hint",
107 "A redacted version of the `hint` column. `NULL` if no redaction is needed.",
108 ),
109 (
110 "redacted_action",
111 "A redacted version of the `action` column. `NULL` if no redaction is needed.",
112 ),
113 (
114 "action_type",
115 "The type of the `action` string (`sql_statements` for a valid SQL string or `plain_text` for plain text).",
116 ),
117 (
118 "object_id",
119 "The ID of the materialized view or index. Corresponds to `mz_objects.id`. For global notices, this column is `NULL`.",
120 ),
121 (
122 "created_at",
123 "The time at which the notice was created. Note that some notices are re-created on `environmentd` restart.",
124 ),
125 ]),
126 sql: "SELECT
127 n.id,
128 n.notice_type,
129 n.message,
130 n.hint,
131 n.action,
132 n.redacted_message,
133 n.redacted_hint,
134 n.redacted_action,
135 n.action_type,
136 n.object_id,
137 n.created_at
138FROM
139 mz_internal.mz_optimizer_notices n
140",
141 access: vec![MONITOR_SELECT],
142});
143
144pub static MZ_NOTICES_REDACTED: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
148 name: "mz_notices_redacted",
149 schema: MZ_INTERNAL_SCHEMA,
150 oid: oid::VIEW_MZ_NOTICES_REDACTED_OID,
151 desc: RelationDesc::builder()
152 .with_column("id", ScalarType::String.nullable(false))
153 .with_column("notice_type", ScalarType::String.nullable(false))
154 .with_column("message", ScalarType::String.nullable(false))
155 .with_column("hint", ScalarType::String.nullable(false))
156 .with_column("action", ScalarType::String.nullable(true))
157 .with_column("action_type", ScalarType::String.nullable(true))
158 .with_column("object_id", ScalarType::String.nullable(true))
159 .with_column(
160 "created_at",
161 ScalarType::TimestampTz { precision: None }.nullable(false),
162 )
163 .with_key(vec![0])
164 .finish(),
165 column_comments: BTreeMap::from_iter([
166 ("id", "Materialize's unique ID for this notice."),
167 ("notice_type", "The notice type."),
168 (
169 "message",
170 "A redacted brief description of the issue highlighted by this notice.",
171 ),
172 (
173 "hint",
174 "A redacted high-level hint that tells the user what can be improved.",
175 ),
176 (
177 "action",
178 "A redacted concrete action that will resolve the notice.",
179 ),
180 (
181 "action_type",
182 "The type of the `action` string (`sql_statements` for a valid SQL string or `plain_text` for plain text).",
183 ),
184 (
185 "object_id",
186 "The ID of the materialized view or index. Corresponds to `mz_objects.id`. For global notices, this column is `NULL`.",
187 ),
188 (
189 "created_at",
190 "The time at which the notice was created. Note that some notices are re-created on `environmentd` restart.",
191 ),
192 ]),
193 sql: "SELECT
194 id,
195 notice_type,
196 coalesce(redacted_message, message) as message,
197 coalesce(redacted_hint, hint) as hint,
198 coalesce(redacted_action, action) as action,
199 action_type,
200 object_id,
201 created_at
202FROM
203 mz_internal.mz_notices
204",
205 access: vec![SUPPORT_SELECT, MONITOR_REDACTED_SELECT, MONITOR_SELECT],
206});
207
208pub const MZ_NOTICES_IND: BuiltinIndex = BuiltinIndex {
209 name: "mz_notices_ind",
210 schema: MZ_INTERNAL_SCHEMA,
211 oid: oid::INDEX_MZ_NOTICES_IND_OID,
212 sql: "IN CLUSTER mz_catalog_server ON mz_internal.mz_notices(id)",
213 is_retained_metrics_object: false,
214};
215
216pub(super) fn builtins() -> impl Iterator<Item = Builtin<NameReference>> {
220 [
221 Builtin::Table(&MZ_OPTIMIZER_NOTICES),
222 Builtin::View(&MZ_NOTICES),
223 Builtin::View(&MZ_NOTICES_REDACTED),
224 Builtin::Index(&MZ_NOTICES_IND),
225 ]
226 .into_iter()
227}