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