1use std::collections::BTreeMap;
13use std::sync::LazyLock;
14
15use mz_pgrepr::oid;
16use mz_repr::adt::mz_acl_item::MzAclItem;
17use mz_repr::namespaces::MZ_INTERNAL_SCHEMA;
18use mz_repr::{RelationDesc, SemanticType, SqlScalarType};
19use mz_sql::catalog::{ObjectType, SystemObjectType};
20use mz_sql::rbac;
21use mz_sql::session::user::{MZ_ANALYTICS_ROLE_ID, MZ_SYSTEM_ROLE_ID};
22use mz_storage_client::controller::IntrospectionType;
23use mz_storage_client::healthcheck::{
24 MZ_AWS_PRIVATELINK_CONNECTION_STATUS_HISTORY_DESC, MZ_PREPARED_STATEMENT_HISTORY_DESC,
25 MZ_SESSION_HISTORY_DESC, MZ_SINK_STATUS_HISTORY_DESC, MZ_SOURCE_STATUS_HISTORY_DESC,
26 MZ_SQL_TEXT_DESC, MZ_STATEMENT_EXECUTION_HISTORY_DESC, REPLICA_METRICS_HISTORY_DESC,
27 REPLICA_STATUS_HISTORY_DESC, WALLCLOCK_GLOBAL_LAG_HISTOGRAM_RAW_DESC,
28 WALLCLOCK_LAG_HISTORY_DESC,
29};
30use mz_storage_client::statistics::{MZ_SINK_STATISTICS_RAW_DESC, MZ_SOURCE_STATISTICS_RAW_DESC};
31
32use crate::memory::objects::DataSourceDesc;
33
34use super::{
35 ANALYTICS_SELECT, BuiltinConnection, BuiltinIndex, BuiltinMaterializedView, BuiltinSource,
36 BuiltinTable, BuiltinView, Cardinality, LinkProperties, MONITOR_REDACTED_SELECT,
37 MONITOR_SELECT, Ontology, OntologyLink, PUBLIC_SELECT, SUPPORT_SELECT,
38};
39
40pub static MZ_CATALOG_RAW: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
41 name: "mz_catalog_raw",
42 schema: MZ_INTERNAL_SCHEMA,
43 oid: oid::SOURCE_MZ_CATALOG_RAW_OID,
44 data_source: DataSourceDesc::Catalog,
45 desc: crate::durable::persist_desc(),
46 column_comments: BTreeMap::new(),
47 is_retained_metrics_object: false,
48 access: vec![],
50 ontology: None,
51});
52pub static MZ_POSTGRES_SOURCES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
53 name: "mz_postgres_sources",
54 schema: MZ_INTERNAL_SCHEMA,
55 oid: oid::TABLE_MZ_POSTGRES_SOURCES_OID,
56 desc: RelationDesc::builder()
57 .with_column("id", SqlScalarType::String.nullable(false))
58 .with_column("replication_slot", SqlScalarType::String.nullable(false))
59 .with_column("timeline_id", SqlScalarType::UInt64.nullable(true))
60 .finish(),
61 column_comments: BTreeMap::from_iter([
62 (
63 "id",
64 "The ID of the source. Corresponds to `mz_catalog.mz_sources.id`.",
65 ),
66 (
67 "replication_slot",
68 "The name of the replication slot in the PostgreSQL database that Materialize will create and stream data from.",
69 ),
70 (
71 "timeline_id",
72 "The PostgreSQL timeline ID determined on source creation.",
73 ),
74 ]),
75 is_retained_metrics_object: false,
76 access: vec![PUBLIC_SELECT],
77 ontology: Some(Ontology {
78 entity_name: "postgres_source",
79 description: "Postgres source-level details",
80 links: &const {
81 [OntologyLink {
82 name: "details_of",
83 target: "source",
84 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
85 }]
86 },
87 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
88 }),
89});
90pub static MZ_POSTGRES_SOURCE_TABLES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
91 name: "mz_postgres_source_tables",
92 schema: MZ_INTERNAL_SCHEMA,
93 oid: oid::TABLE_MZ_POSTGRES_SOURCE_TABLES_OID,
94 desc: RelationDesc::builder()
95 .with_column("id", SqlScalarType::String.nullable(false))
96 .with_column("schema_name", SqlScalarType::String.nullable(false))
97 .with_column("table_name", SqlScalarType::String.nullable(false))
98 .finish(),
99 column_comments: BTreeMap::from_iter([
100 (
101 "id",
102 "The ID of the subsource or table. Corresponds to `mz_catalog.mz_sources.id` or `mz_catalog.mz_tables.id`.",
103 ),
104 (
105 "schema_name",
106 "The schema of the upstream table being ingested.",
107 ),
108 (
109 "table_name",
110 "The name of the upstream table being ingested.",
111 ),
112 ]),
113 is_retained_metrics_object: true,
114 access: vec![PUBLIC_SELECT],
115 ontology: Some(Ontology {
116 entity_name: "postgres_source_table",
117 description: "Postgres source table-level details",
118 links: &const {
119 [OntologyLink {
120 name: "describes_source_table",
121 target: "table",
122 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
123 }]
124 },
125 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
126 }),
127});
128pub static MZ_MYSQL_SOURCE_TABLES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
129 name: "mz_mysql_source_tables",
130 schema: MZ_INTERNAL_SCHEMA,
131 oid: oid::TABLE_MZ_MYSQL_SOURCE_TABLES_OID,
132 desc: RelationDesc::builder()
133 .with_column("id", SqlScalarType::String.nullable(false))
134 .with_column("schema_name", SqlScalarType::String.nullable(false))
135 .with_column("table_name", SqlScalarType::String.nullable(false))
136 .finish(),
137 column_comments: BTreeMap::from_iter([
138 (
139 "id",
140 "The ID of the subsource or table. Corresponds to `mz_catalog.mz_sources.id` or `mz_catalog.mz_tables.id`.",
141 ),
142 (
143 "schema_name",
144 "The schema (or, database) of the upstream table being ingested.",
145 ),
146 (
147 "table_name",
148 "The name of the upstream table being ingested.",
149 ),
150 ]),
151 is_retained_metrics_object: true,
152 access: vec![PUBLIC_SELECT],
153 ontology: Some(Ontology {
154 entity_name: "mysql_source_table",
155 description: "MySQL source table-level details",
156 links: &const {
157 [OntologyLink {
158 name: "describes_source_table",
159 target: "table",
160 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
161 }]
162 },
163 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
164 }),
165});
166pub static MZ_SQL_SERVER_SOURCE_TABLES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
167 name: "mz_sql_server_source_tables",
168 schema: MZ_INTERNAL_SCHEMA,
169 oid: oid::TABLE_MZ_SQL_SERVER_SOURCE_TABLES_OID,
170 desc: RelationDesc::builder()
171 .with_column("id", SqlScalarType::String.nullable(false))
172 .with_column("schema_name", SqlScalarType::String.nullable(false))
173 .with_column("table_name", SqlScalarType::String.nullable(false))
174 .finish(),
175 column_comments: BTreeMap::from_iter([
176 (
177 "id",
178 "The ID of the subsource or table. Corresponds to `mz_catalog.mz_sources.id` or `mz_catalog.mz_tables.id`.",
179 ),
180 (
181 "schema_name",
182 "The schema of the upstream table being ingested.",
183 ),
184 (
185 "table_name",
186 "The name of the upstream table being ingested.",
187 ),
188 ]),
189 is_retained_metrics_object: true,
190 access: vec![PUBLIC_SELECT],
191 ontology: Some(Ontology {
192 entity_name: "sql_server_source_table",
193 description: "SQL Server source table-level details",
194 links: &const {
195 [OntologyLink {
196 name: "describes_source_table",
197 target: "table",
198 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
199 }]
200 },
201 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
202 }),
203});
204pub static MZ_KAFKA_SOURCE_TABLES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
205 name: "mz_kafka_source_tables",
206 schema: MZ_INTERNAL_SCHEMA,
207 oid: oid::TABLE_MZ_KAFKA_SOURCE_TABLES_OID,
208 desc: RelationDesc::builder()
209 .with_column("id", SqlScalarType::String.nullable(false))
210 .with_column("topic", SqlScalarType::String.nullable(false))
211 .with_column("envelope_type", SqlScalarType::String.nullable(true))
212 .with_column("key_format", SqlScalarType::String.nullable(true))
213 .with_column("value_format", SqlScalarType::String.nullable(true))
214 .finish(),
215 column_comments: BTreeMap::from_iter([
216 (
217 "id",
218 "The ID of the table. Corresponds to `mz_catalog.mz_tables.id`.",
219 ),
220 ("topic", "The topic being ingested."),
221 (
222 "envelope_type",
223 "The envelope type: `none`, `upsert`, or `debezium`. `NULL` for other source types.",
224 ),
225 (
226 "key_format",
227 "The format of the Kafka message key: `avro`, `csv`, `regex`, `bytes`, `json`, `text`, or `NULL`.",
228 ),
229 (
230 "value_format",
231 "The format of the Kafka message value: `avro`, `csv`, `regex`, `bytes`, `json`, `text`. `NULL` for other source types.",
232 ),
233 ]),
234 is_retained_metrics_object: true,
235 access: vec![PUBLIC_SELECT],
236 ontology: Some(Ontology {
237 entity_name: "kafka_source_table",
238 description: "Kafka source table-level details",
239 links: &const {
240 [OntologyLink {
241 name: "describes_source_table",
242 target: "table",
243 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
244 }]
245 },
246 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
247 }),
248});
249pub static MZ_OBJECT_DEPENDENCIES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
250 name: "mz_object_dependencies",
251 schema: MZ_INTERNAL_SCHEMA,
252 oid: oid::TABLE_MZ_OBJECT_DEPENDENCIES_OID,
253 desc: RelationDesc::builder()
254 .with_column("object_id", SqlScalarType::String.nullable(false))
255 .with_column(
256 "referenced_object_id",
257 SqlScalarType::String.nullable(false),
258 )
259 .finish(),
260 column_comments: BTreeMap::from_iter([
261 (
262 "object_id",
263 "The ID of the dependent object. Corresponds to `mz_objects.id`.",
264 ),
265 (
266 "referenced_object_id",
267 "The ID of the referenced object. Corresponds to `mz_objects.id`.",
268 ),
269 ]),
270 is_retained_metrics_object: true,
271 access: vec![PUBLIC_SELECT],
272 ontology: Some(Ontology {
273 entity_name: "object_dependency",
274 description: "A dependency edge: one object depends on another",
275 links: &const {
276 [
277 OntologyLink {
278 name: "depends_on",
279 target: "object",
280 properties: LinkProperties::DependsOn {
281 source_column: "object_id",
282 target_column: "id",
283 source_id_type: Some(mz_repr::SemanticType::CatalogItemId),
284 requires_mapping: None,
285 },
286 },
287 OntologyLink {
288 name: "dependency_is",
289 target: "object",
290 properties: LinkProperties::DependsOn {
291 source_column: "referenced_object_id",
292 target_column: "id",
293 source_id_type: Some(mz_repr::SemanticType::CatalogItemId),
294 requires_mapping: None,
295 },
296 },
297 ]
298 },
299 column_semantic_types: &const {
300 [
301 ("object_id", SemanticType::CatalogItemId),
302 ("referenced_object_id", SemanticType::CatalogItemId),
303 ]
304 },
305 }),
306});
307pub static MZ_COMPUTE_DEPENDENCIES: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
308 name: "mz_compute_dependencies",
309 schema: MZ_INTERNAL_SCHEMA,
310 oid: oid::SOURCE_MZ_COMPUTE_DEPENDENCIES_OID,
311 data_source: IntrospectionType::ComputeDependencies.into(),
312 desc: RelationDesc::builder()
313 .with_column("object_id", SqlScalarType::String.nullable(false))
314 .with_column("dependency_id", SqlScalarType::String.nullable(false))
315 .finish(),
316 column_comments: BTreeMap::from_iter([
317 (
318 "object_id",
319 "The ID of a compute object. Corresponds to `mz_catalog.mz_indexes.id`, `mz_catalog.mz_materialized_views.id`, or `mz_internal.mz_subscriptions.id`.",
320 ),
321 (
322 "dependency_id",
323 "The ID of a compute dependency. Corresponds to `mz_catalog.mz_indexes.id`, `mz_catalog.mz_materialized_views.id`, `mz_catalog.mz_sources.id`, or `mz_catalog.mz_tables.id`.",
324 ),
325 ]),
326 is_retained_metrics_object: false,
327 access: vec![PUBLIC_SELECT],
328 ontology: Some(Ontology {
329 entity_name: "compute_dependency",
330 description: "Dependency edge from a compute object (index, materialized view, or subscription) to one of the sources of its data",
331 links: &const {
332 [
333 OntologyLink {
334 name: "depends_on",
335 target: "object",
336 properties: LinkProperties::DependsOn {
337 source_column: "object_id",
338 target_column: "id",
339 source_id_type: Some(mz_repr::SemanticType::GlobalId),
340 requires_mapping: Some("mz_internal.mz_object_global_ids"),
341 },
342 },
343 OntologyLink {
344 name: "dependency_is",
345 target: "object",
346 properties: LinkProperties::DependsOn {
347 source_column: "dependency_id",
348 target_column: "id",
349 source_id_type: Some(mz_repr::SemanticType::GlobalId),
350 requires_mapping: Some("mz_internal.mz_object_global_ids"),
351 },
352 },
353 ]
354 },
355 column_semantic_types: &const {
356 [
357 ("object_id", SemanticType::GlobalId),
358 ("dependency_id", SemanticType::GlobalId),
359 ]
360 },
361 }),
362});
363
364pub static MZ_MATERIALIZED_VIEW_REFRESH_STRATEGIES: LazyLock<BuiltinTable> = LazyLock::new(|| {
365 BuiltinTable {
366 name: "mz_materialized_view_refresh_strategies",
367 schema: MZ_INTERNAL_SCHEMA,
368 oid: oid::TABLE_MZ_MATERIALIZED_VIEW_REFRESH_STRATEGIES_OID,
369 desc: RelationDesc::builder()
370 .with_column(
371 "materialized_view_id",
372 SqlScalarType::String.nullable(false),
373 )
374 .with_column("type", SqlScalarType::String.nullable(false))
375 .with_column("interval", SqlScalarType::Interval.nullable(true))
376 .with_column(
377 "aligned_to",
378 SqlScalarType::TimestampTz { precision: None }.nullable(true),
379 )
380 .with_column(
381 "at",
382 SqlScalarType::TimestampTz { precision: None }.nullable(true),
383 )
384 .finish(),
385 column_comments: BTreeMap::from_iter([
386 (
387 "materialized_view_id",
388 "The ID of the materialized view. Corresponds to `mz_catalog.mz_materialized_views.id`",
389 ),
390 (
391 "type",
392 "`at`, `every`, or `on-commit`. Default: `on-commit`",
393 ),
394 (
395 "interval",
396 "The refresh interval of a `REFRESH EVERY` option, or `NULL` if the `type` is not `every`.",
397 ),
398 (
399 "aligned_to",
400 "The `ALIGNED TO` option of a `REFRESH EVERY` option, or `NULL` if the `type` is not `every`.",
401 ),
402 (
403 "at",
404 "The time of a `REFRESH AT`, or `NULL` if the `type` is not `at`.",
405 ),
406 ]),
407 is_retained_metrics_object: false,
408 access: vec![PUBLIC_SELECT],
409 ontology: None,
410 }
411});
412
413pub static MZ_NETWORK_POLICIES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
414 BuiltinMaterializedView {
415 name: "mz_network_policies",
416 schema: MZ_INTERNAL_SCHEMA,
417 oid: oid::MV_MZ_NETWORK_POLICIES_OID,
418 desc: RelationDesc::builder()
419 .with_column("id", SqlScalarType::String.nullable(false))
420 .with_column("name", SqlScalarType::String.nullable(false))
421 .with_column("owner_id", SqlScalarType::String.nullable(false))
422 .with_column(
423 "privileges",
424 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
425 )
426 .with_column("oid", SqlScalarType::Oid.nullable(false))
427 .with_key(vec![0])
428 .with_key(vec![4])
429 .finish(),
430 column_comments: BTreeMap::from_iter([
431 ("id", "The ID of the network policy."),
432 ("name", "The name of the network policy."),
433 (
434 "owner_id",
435 "The role ID of the owner of the network policy. Corresponds to `mz_catalog.mz_roles.id`.",
436 ),
437 (
438 "privileges",
439 "The privileges belonging to the network policy.",
440 ),
441 ("oid", "A PostgreSQL-compatible OID for the network policy."),
442 ]),
443 sql: "
444IN CLUSTER mz_catalog_server
445WITH (
446 ASSERT NOT NULL id,
447 ASSERT NOT NULL name,
448 ASSERT NOT NULL owner_id,
449 ASSERT NOT NULL privileges,
450 ASSERT NOT NULL oid
451) AS
452SELECT
453 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
454 data->'value'->>'name' AS name,
455 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
456 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
457 (data->'value'->>'oid')::oid AS oid
458FROM mz_internal.mz_catalog_raw
459WHERE data->>'kind' = 'NetworkPolicy'",
460 is_retained_metrics_object: false,
461 access: vec![PUBLIC_SELECT],
462 ontology: Some(Ontology {
463 entity_name: "network_policy",
464 description: "Network access policies",
465 links: &const {
466 [OntologyLink {
467 name: "owned_by",
468 target: "role",
469 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
470 }]
471 },
472 column_semantic_types: &const {
473 [
474 ("id", SemanticType::NetworkPolicyId),
475 ("owner_id", SemanticType::RoleId),
476 ("oid", SemanticType::OID),
477 ]
478 },
479 }),
480 }
481});
482
483pub static MZ_NETWORK_POLICY_RULES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
484 BuiltinMaterializedView {
485 name: "mz_network_policy_rules",
486 schema: MZ_INTERNAL_SCHEMA,
487 oid: oid::MV_MZ_NETWORK_POLICY_RULES_OID,
488 desc: RelationDesc::builder()
489 .with_column("name", SqlScalarType::String.nullable(false))
490 .with_column("policy_id", SqlScalarType::String.nullable(false))
491 .with_column("action", SqlScalarType::String.nullable(false))
492 .with_column("address", SqlScalarType::String.nullable(false))
493 .with_column("direction", SqlScalarType::String.nullable(false))
494 .finish(),
495 column_comments: BTreeMap::from_iter([
496 (
497 "name",
498 "The name of the network policy rule. Can be combined with `policy_id` to form a unique identifier.",
499 ),
500 (
501 "policy_id",
502 "The ID the network policy the rule is part of. Corresponds to `mz_internal.mz_network_policies.id`.",
503 ),
504 (
505 "action",
506 "The action of the rule. `allow` is the only supported action.",
507 ),
508 ("address", "The address the rule will take action on."),
509 (
510 "direction",
511 "The direction of traffic the rule applies to. `ingress` is the only supported direction.",
512 ),
513 ]),
514 sql: "
515IN CLUSTER mz_catalog_server
516WITH (
517 ASSERT NOT NULL name,
518 ASSERT NOT NULL policy_id,
519 ASSERT NOT NULL action,
520 ASSERT NOT NULL address,
521 ASSERT NOT NULL direction
522) AS
523SELECT
524 rule->>'name' AS name,
525 mz_internal.parse_catalog_id(data->'key'->'id') AS policy_id,
526 lower(rule->>'action') AS action,
527 rule->>'address' AS address,
528 lower(rule->>'direction') AS direction
529FROM
530 mz_internal.mz_catalog_raw,
531 jsonb_array_elements(data->'value'->'rules') AS rule
532WHERE data->>'kind' = 'NetworkPolicy'",
533 is_retained_metrics_object: false,
534 access: vec![PUBLIC_SELECT],
535 ontology: Some(Ontology {
536 entity_name: "network_policy_rule",
537 description: "Individual rules within a network policy",
538 links: &const {
539 [OntologyLink {
540 name: "belongs_to_policy",
541 target: "network_policy",
542 properties: LinkProperties::fk("policy_id", "id", Cardinality::ManyToOne),
543 }]
544 },
545 column_semantic_types: &[],
546 }),
547 }
548});
549
550pub static MZ_TYPE_PG_METADATA: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
553 name: "mz_type_pg_metadata",
554 schema: MZ_INTERNAL_SCHEMA,
555 oid: oid::TABLE_MZ_TYPE_PG_METADATA_OID,
556 desc: RelationDesc::builder()
557 .with_column("id", SqlScalarType::String.nullable(false))
558 .with_column("typinput", SqlScalarType::Oid.nullable(false))
559 .with_column("typreceive", SqlScalarType::Oid.nullable(false))
560 .finish(),
561 column_comments: BTreeMap::new(),
562 is_retained_metrics_object: false,
563 access: vec![PUBLIC_SELECT],
564 ontology: None,
565});
566pub static MZ_AGGREGATES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
567 name: "mz_aggregates",
568 schema: MZ_INTERNAL_SCHEMA,
569 oid: oid::TABLE_MZ_AGGREGATES_OID,
570 desc: RelationDesc::builder()
571 .with_column("oid", SqlScalarType::Oid.nullable(false))
572 .with_column("agg_kind", SqlScalarType::String.nullable(false))
573 .with_column("agg_num_direct_args", SqlScalarType::Int16.nullable(false))
574 .finish(),
575 column_comments: BTreeMap::new(),
576 is_retained_metrics_object: false,
577 access: vec![PUBLIC_SELECT],
578 ontology: Some(Ontology {
579 entity_name: "aggregate",
580 description: "Aggregate function metadata",
581 links: &const { [] },
582 column_semantic_types: &[("oid", SemanticType::OID)],
583 }),
584});
585
586pub static MZ_CLUSTER_WORKLOAD_CLASSES: LazyLock<BuiltinMaterializedView> =
587 LazyLock::new(|| BuiltinMaterializedView {
588 name: "mz_cluster_workload_classes",
589 schema: MZ_INTERNAL_SCHEMA,
590 oid: oid::MV_MZ_CLUSTER_WORKLOAD_CLASSES_OID,
591 desc: RelationDesc::builder()
592 .with_column("id", SqlScalarType::String.nullable(false))
593 .with_column("workload_class", SqlScalarType::String.nullable(true))
594 .with_key(vec![0])
595 .finish(),
596 column_comments: BTreeMap::new(),
597 sql: "
598IN CLUSTER mz_catalog_server
599WITH (
600 ASSERT NOT NULL id
601) AS
602SELECT
603 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
604 CASE WHEN data->'value'->'config'->'workload_class' != 'null'
605 THEN data->'value'->'config'->>'workload_class'
606 END AS workload_class
607FROM mz_internal.mz_catalog_raw
608WHERE data->>'kind' = 'Cluster'",
609 is_retained_metrics_object: false,
610 access: vec![PUBLIC_SELECT],
611 ontology: None,
612 });
613
614pub const MZ_CLUSTER_WORKLOAD_CLASSES_IND: BuiltinIndex = BuiltinIndex {
615 name: "mz_cluster_workload_classes_ind",
616 schema: MZ_INTERNAL_SCHEMA,
617 oid: oid::INDEX_MZ_CLUSTER_WORKLOAD_CLASSES_IND_OID,
618 sql: "IN CLUSTER mz_catalog_server
619ON mz_internal.mz_cluster_workload_classes (id)",
620 is_retained_metrics_object: false,
621};
622
623pub static MZ_CLUSTER_SCHEDULES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
624 BuiltinMaterializedView {
625 name: "mz_cluster_schedules",
626 schema: MZ_INTERNAL_SCHEMA,
627 oid: oid::MV_MZ_CLUSTER_SCHEDULES_OID,
628 desc: RelationDesc::builder()
629 .with_column("cluster_id", SqlScalarType::String.nullable(false))
630 .with_column("type", SqlScalarType::String.nullable(false))
631 .with_column(
632 "refresh_hydration_time_estimate",
633 SqlScalarType::Interval.nullable(true),
634 )
635 .with_key(vec![0])
636 .finish(),
637 column_comments: BTreeMap::from_iter([
638 (
639 "cluster_id",
640 "The ID of the cluster. Corresponds to `mz_clusters.id`.",
641 ),
642 ("type", "`on-refresh`, or `manual`. Default: `manual`"),
643 (
644 "refresh_hydration_time_estimate",
645 "The interval given in the `HYDRATION TIME ESTIMATE` option.",
646 ),
647 ]),
648 sql: "
655IN CLUSTER mz_catalog_server
656WITH (
657 ASSERT NOT NULL cluster_id,
658 ASSERT NOT NULL type
659) AS
660SELECT
661 mz_internal.parse_catalog_id(data->'key'->'id') AS cluster_id,
662 CASE
663 WHEN data->'value'->'config'->'variant'->'Managed'->'schedule' = '\"Manual\"'::jsonb
664 THEN 'manual'
665 WHEN data->'value'->'config'->'variant'->'Managed'->'schedule' ? 'Refresh'
666 THEN 'on-refresh'
667 END AS type,
668 CASE
669 WHEN data->'value'->'config'->'variant'->'Managed'->'schedule' ? 'Refresh' THEN
670 (
671 (data->'value'->'config'->'variant'->'Managed'->'schedule'->'Refresh'->'rehydration_time_estimate'->>'secs')
672 || ' seconds '
673 || ((data->'value'->'config'->'variant'->'Managed'->'schedule'->'Refresh'->'rehydration_time_estimate'->>'nanos')::bigint / 1000)::text
674 || ' microseconds'
675 )::interval
676 END AS refresh_hydration_time_estimate
677FROM mz_internal.mz_catalog_raw
678WHERE
679 data->>'kind' = 'Cluster' AND
680 jsonb_typeof(data->'value'->'config'->'variant') = 'object'",
681 is_retained_metrics_object: false,
682 access: vec![PUBLIC_SELECT],
683 ontology: Some(Ontology {
684 entity_name: "cluster_schedule",
685 description: "Cluster scheduling configuration",
686 links: &const {
687 [OntologyLink {
688 name: "belongs_to_cluster",
689 target: "cluster",
690 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
691 }]
692 },
693 column_semantic_types: &[("cluster_id", SemanticType::ClusterId)],
694 }),
695 }
696});
697
698pub static MZ_INTERNAL_CLUSTER_REPLICAS: LazyLock<BuiltinMaterializedView> =
699 LazyLock::new(|| BuiltinMaterializedView {
700 name: "mz_internal_cluster_replicas",
701 schema: MZ_INTERNAL_SCHEMA,
702 oid: oid::MV_MZ_INTERNAL_CLUSTER_REPLICAS_OID,
703 desc: RelationDesc::builder()
704 .with_column("id", SqlScalarType::String.nullable(false))
705 .with_key(vec![0])
706 .finish(),
707 column_comments: BTreeMap::from_iter([(
708 "id",
709 "The ID of a cluster replica. Corresponds to `mz_cluster_replicas.id`.",
710 )]),
711 sql: "
712IN CLUSTER mz_catalog_server
713WITH (
714 ASSERT NOT NULL id
715) AS
716SELECT mz_internal.parse_catalog_id(data->'key'->'id') AS id
717FROM mz_internal.mz_catalog_raw
718WHERE
719 data->>'kind' = 'ClusterReplica' AND
720 (data->'value'->'config'->'location'->'Managed'->>'internal')::bool = true",
721 is_retained_metrics_object: false,
722 access: vec![PUBLIC_SELECT],
723 ontology: None,
724 });
725
726pub static MZ_PENDING_CLUSTER_REPLICAS: LazyLock<BuiltinMaterializedView> =
727 LazyLock::new(|| BuiltinMaterializedView {
728 name: "mz_pending_cluster_replicas",
729 schema: MZ_INTERNAL_SCHEMA,
730 oid: oid::MV_MZ_PENDING_CLUSTER_REPLICAS_OID,
731 desc: RelationDesc::builder()
732 .with_column("id", SqlScalarType::String.nullable(false))
733 .with_key(vec![0])
734 .finish(),
735 column_comments: BTreeMap::from_iter([(
736 "id",
737 "The ID of a cluster replica. Corresponds to `mz_cluster_replicas.id`.",
738 )]),
739 sql: "
740IN CLUSTER mz_catalog_server
741WITH (
742 ASSERT NOT NULL id
743) AS
744SELECT mz_internal.parse_catalog_id(data->'key'->'id') AS id
745FROM mz_internal.mz_catalog_raw
746WHERE
747 data->>'kind' = 'ClusterReplica' AND
748 (data->'value'->'config'->'location'->'Managed'->>'pending')::bool = true",
749 is_retained_metrics_object: false,
750 access: vec![PUBLIC_SELECT],
751 ontology: None,
752 });
753
754pub static MZ_CLUSTER_REPLICA_SIZE_INTERNAL: LazyLock<BuiltinTable> = LazyLock::new(|| {
772 BuiltinTable {
773 name: "mz_cluster_replica_size_internal",
774 schema: MZ_INTERNAL_SCHEMA,
775 oid: oid::TABLE_MZ_CLUSTER_REPLICA_SIZE_INTERNAL_OID,
776 desc: RelationDesc::builder()
777 .with_column("size", SqlScalarType::String.nullable(false))
778 .with_column("swap_enabled", SqlScalarType::Bool.nullable(false))
779 .with_column("disk_bytes", SqlScalarType::UInt64.nullable(false))
780 .with_key(vec![0])
781 .finish(),
782 column_comments: BTreeMap::from_iter([
783 ("size", "The human-readable replica size."),
784 (
785 "swap_enabled",
786 "Whether the replica size's pods are configured to allow swap. Used internally to compute the public `disk` column.",
787 ),
788 (
789 "disk_bytes",
790 "The replica size's disk limit in bytes (0 if explicitly disabled). Used internally to compute the public `disk` column.",
791 ),
792 ]),
793 is_retained_metrics_object: true,
794 access: vec![],
795 ontology: None,
796 }
797});
798
799pub const MZ_CLUSTER_REPLICA_SIZE_INTERNAL_IND: BuiltinIndex = BuiltinIndex {
800 name: "mz_cluster_replica_size_internal_ind",
801 schema: MZ_INTERNAL_SCHEMA,
802 oid: oid::INDEX_MZ_CLUSTER_REPLICA_SIZE_INTERNAL_IND_OID,
803 sql: "IN CLUSTER mz_catalog_server
804ON mz_internal.mz_cluster_replica_size_internal (size)",
805 is_retained_metrics_object: true,
806};
807
808pub static MZ_CLUSTER_REPLICA_STATUS_HISTORY: LazyLock<BuiltinSource> = LazyLock::new(|| {
809 BuiltinSource {
810 name: "mz_cluster_replica_status_history",
811 schema: MZ_INTERNAL_SCHEMA,
812 oid: oid::SOURCE_MZ_CLUSTER_REPLICA_STATUS_HISTORY_OID,
813 data_source: IntrospectionType::ReplicaStatusHistory.into(),
814 desc: REPLICA_STATUS_HISTORY_DESC.clone(),
815 column_comments: BTreeMap::from_iter([
816 ("replica_id", "The ID of a cluster replica."),
817 ("process_id", "The ID of a process within the replica."),
818 (
819 "status",
820 "The status of the cluster replica: `online` or `offline`.",
821 ),
822 (
823 "reason",
824 "If the cluster replica is in an `offline` state, the reason (if available). For example, `oom-killed`.",
825 ),
826 (
827 "occurred_at",
828 "Wall-clock timestamp at which the event occurred.",
829 ),
830 ]),
831 is_retained_metrics_object: false,
832 access: vec![PUBLIC_SELECT],
833 ontology: Some(Ontology {
834 entity_name: "replica_status_event",
835 description: "Historical replica status events (ready, not-ready, etc.)",
836 links: &const {
837 [OntologyLink {
838 name: "status_event_of_replica",
839 target: "replica",
840 properties: LinkProperties::fk_typed(
841 "replica_id",
842 "id",
843 Cardinality::ManyToOne,
844 mz_repr::SemanticType::CatalogItemId,
845 ),
846 }]
847 },
848 column_semantic_types: &[("replica_id", SemanticType::ReplicaId)],
849 }),
850 }
851});
852
853pub static MZ_CLUSTER_REPLICA_STATUSES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
854 name: "mz_cluster_replica_statuses",
855 schema: MZ_INTERNAL_SCHEMA,
856 oid: oid::VIEW_MZ_CLUSTER_REPLICA_STATUSES_OID,
857 desc: RelationDesc::builder()
858 .with_column("replica_id", SqlScalarType::String.nullable(false))
859 .with_column("process_id", SqlScalarType::UInt64.nullable(false))
860 .with_column("status", SqlScalarType::String.nullable(false))
861 .with_column("reason", SqlScalarType::String.nullable(true))
862 .with_column(
863 "updated_at",
864 SqlScalarType::TimestampTz { precision: None }.nullable(false),
865 )
866 .with_key(vec![0, 1])
867 .finish(),
868 column_comments: BTreeMap::from_iter([
869 (
870 "replica_id",
871 "Materialize's unique ID for the cluster replica.",
872 ),
873 (
874 "process_id",
875 "The ID of the process within the cluster replica.",
876 ),
877 (
878 "status",
879 "The status of the cluster replica: `online` or `offline`.",
880 ),
881 (
882 "reason",
883 "If the cluster replica is in a `offline` state, the reason (if available). For example, `oom-killed`.",
884 ),
885 (
886 "updated_at",
887 "The time at which the status was last updated.",
888 ),
889 ]),
890 sql: "
891SELECT
892 DISTINCT ON (replica_id, process_id)
893 replica_id,
894 process_id,
895 status,
896 reason,
897 occurred_at as updated_at
898FROM mz_internal.mz_cluster_replica_status_history
899JOIN mz_cluster_replicas r ON r.id = replica_id
900ORDER BY replica_id, process_id, occurred_at DESC",
901 access: vec![PUBLIC_SELECT],
902 ontology: Some(Ontology {
903 entity_name: "replica_status",
904 description: "Current status of each replica",
905 links: &const {
906 [OntologyLink {
907 name: "status_of_replica",
908 target: "replica",
909 properties: LinkProperties::fk_typed(
910 "replica_id",
911 "id",
912 Cardinality::ManyToOne,
913 mz_repr::SemanticType::ReplicaId,
914 ),
915 }]
916 },
917 column_semantic_types: &const {
918 [
919 ("replica_id", SemanticType::ReplicaId),
920 ("updated_at", SemanticType::WallclockTimestamp),
921 ]
922 },
923 }),
924});
925
926pub static MZ_SOURCE_STATUS_HISTORY: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
927 name: "mz_source_status_history",
928 schema: MZ_INTERNAL_SCHEMA,
929 oid: oid::SOURCE_MZ_SOURCE_STATUS_HISTORY_OID,
930 data_source: IntrospectionType::SourceStatusHistory.into(),
931 desc: MZ_SOURCE_STATUS_HISTORY_DESC.clone(),
932 column_comments: BTreeMap::from_iter([
933 (
934 "occurred_at",
935 "Wall-clock timestamp of the source status change.",
936 ),
937 (
938 "source_id",
939 "The ID of the source. Corresponds to `mz_catalog.mz_sources.id`.",
940 ),
941 (
942 "status",
943 "The status of the source: one of `created`, `starting`, `running`, `paused`, `stalled`, `failed`, or `dropped`.",
944 ),
945 (
946 "error",
947 "If the source is in an error state, the error message.",
948 ),
949 (
950 "details",
951 "Additional metadata provided by the source. In case of error, may contain a `hint` field with helpful suggestions.",
952 ),
953 (
954 "replica_id",
955 "The ID of the replica that an instance of a source is running on.",
956 ),
957 ]),
958 is_retained_metrics_object: false,
959 access: vec![PUBLIC_SELECT],
960 ontology: Some(Ontology {
961 entity_name: "source_status_event",
962 description: "Historical source status events",
963 links: &const {
964 [
965 OntologyLink {
966 name: "status_event_of_source",
967 target: "source",
968 properties: LinkProperties::fk_mapped(
969 "source_id",
970 "id",
971 Cardinality::ManyToOne,
972 mz_repr::SemanticType::GlobalId,
973 "mz_internal.mz_object_global_ids",
974 ),
975 },
976 OntologyLink {
977 name: "on_replica",
978 target: "replica",
979 properties: LinkProperties::fk_nullable(
980 "replica_id",
981 "id",
982 Cardinality::ManyToOne,
983 ),
984 },
985 ]
986 },
987 column_semantic_types: &const {
988 [
989 ("occurred_at", SemanticType::WallclockTimestamp),
990 ("source_id", SemanticType::GlobalId),
991 ("replica_id", SemanticType::ReplicaId),
992 ]
993 },
994 }),
995});
996
997pub static MZ_AWS_PRIVATELINK_CONNECTION_STATUS_HISTORY: LazyLock<BuiltinSource> = LazyLock::new(
998 || BuiltinSource {
999 name: "mz_aws_privatelink_connection_status_history",
1000 schema: MZ_INTERNAL_SCHEMA,
1001 oid: oid::SOURCE_MZ_AWS_PRIVATELINK_CONNECTION_STATUS_HISTORY_OID,
1002 data_source: DataSourceDesc::Introspection(
1003 IntrospectionType::PrivatelinkConnectionStatusHistory,
1004 ),
1005 desc: MZ_AWS_PRIVATELINK_CONNECTION_STATUS_HISTORY_DESC.clone(),
1006 column_comments: BTreeMap::from_iter([
1007 ("occurred_at", "Wall-clock timestamp of the status change."),
1008 (
1009 "connection_id",
1010 "The unique identifier of the AWS PrivateLink connection. Corresponds to `mz_catalog.mz_connections.id`.",
1011 ),
1012 (
1013 "status",
1014 "The status of the connection: one of `pending-service-discovery`, `creating-endpoint`, `recreating-endpoint`, `updating-endpoint`, `available`, `deleted`, `deleting`, `expired`, `failed`, `pending`, `pending-acceptance`, `rejected`, or `unknown`.",
1015 ),
1016 ]),
1017 is_retained_metrics_object: false,
1018 access: vec![PUBLIC_SELECT],
1019 ontology: None,
1020 },
1021);
1022
1023pub static MZ_AWS_PRIVATELINK_CONNECTION_STATUSES: LazyLock<BuiltinView> = LazyLock::new(|| {
1024 BuiltinView {
1025 name: "mz_aws_privatelink_connection_statuses",
1026 schema: MZ_INTERNAL_SCHEMA,
1027 oid: oid::VIEW_MZ_AWS_PRIVATELINK_CONNECTION_STATUSES_OID,
1028 desc: RelationDesc::builder()
1029 .with_column("id", SqlScalarType::String.nullable(false))
1030 .with_column("name", SqlScalarType::String.nullable(false))
1031 .with_column(
1032 "last_status_change_at",
1033 SqlScalarType::TimestampTz { precision: None }.nullable(true),
1034 )
1035 .with_column("status", SqlScalarType::String.nullable(true))
1036 .with_key(vec![0])
1037 .finish(),
1038 column_comments: BTreeMap::from_iter([
1039 (
1040 "id",
1041 "The ID of the connection. Corresponds to `mz_catalog.mz_connections.id`.",
1042 ),
1043 ("name", "The name of the connection."),
1044 (
1045 "last_status_change_at",
1046 "Wall-clock timestamp of the connection status change.",
1047 ),
1048 (
1049 "status",
1050 "The status of the connection: one of `pending-service-discovery`, `creating-endpoint`, `recreating-endpoint`, `updating-endpoint`, `available`, `deleted`, `deleting`, `expired`, `failed`, `pending`, `pending-acceptance`, `rejected`, or `unknown`.",
1051 ),
1052 ]),
1053 sql: "
1054 WITH statuses_w_last_status AS (
1055 SELECT
1056 connection_id,
1057 occurred_at,
1058 status,
1059 lag(status) OVER (PARTITION BY connection_id ORDER BY occurred_at) AS last_status
1060 FROM mz_internal.mz_aws_privatelink_connection_status_history
1061 ),
1062 latest_events AS (
1063 -- Only take the most recent transition for each ID
1064 SELECT DISTINCT ON(connection_id) connection_id, occurred_at, status
1065 FROM statuses_w_last_status
1066 -- Only keep first status transitions
1067 WHERE status <> last_status OR last_status IS NULL
1068 ORDER BY connection_id, occurred_at DESC
1069 )
1070 SELECT
1071 conns.id,
1072 name,
1073 occurred_at as last_status_change_at,
1074 status
1075 FROM latest_events
1076 JOIN mz_catalog.mz_connections AS conns
1077 ON conns.id = latest_events.connection_id",
1078 access: vec![PUBLIC_SELECT],
1079 ontology: Some(Ontology {
1080 entity_name: "privatelink_status",
1081 description: "PrivateLink connection health status",
1082 links: &const {
1083 [OntologyLink {
1084 name: "status_of",
1085 target: "connection",
1086 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
1087 }]
1088 },
1089 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
1090 }),
1091 }
1092});
1093
1094pub static MZ_STATEMENT_EXECUTION_HISTORY: LazyLock<BuiltinSource> =
1095 LazyLock::new(|| BuiltinSource {
1096 name: "mz_statement_execution_history",
1097 schema: MZ_INTERNAL_SCHEMA,
1098 oid: oid::SOURCE_MZ_STATEMENT_EXECUTION_HISTORY_OID,
1099 data_source: IntrospectionType::StatementExecutionHistory.into(),
1100 desc: MZ_STATEMENT_EXECUTION_HISTORY_DESC.clone(),
1101 column_comments: BTreeMap::new(),
1102 is_retained_metrics_object: false,
1103 access: vec![MONITOR_SELECT],
1104 ontology: None,
1105 });
1106
1107pub static MZ_STATEMENT_EXECUTION_HISTORY_REDACTED: LazyLock<BuiltinView> = LazyLock::new(|| {
1108 BuiltinView {
1109 name: "mz_statement_execution_history_redacted",
1110 schema: MZ_INTERNAL_SCHEMA,
1111 oid: oid::VIEW_MZ_STATEMENT_EXECUTION_HISTORY_REDACTED_OID,
1112 desc: RelationDesc::builder()
1114 .with_column("id", SqlScalarType::Uuid.nullable(false))
1115 .with_column("prepared_statement_id", SqlScalarType::Uuid.nullable(false))
1116 .with_column("sample_rate", SqlScalarType::Float64.nullable(false))
1117 .with_column("cluster_id", SqlScalarType::String.nullable(true))
1118 .with_column("application_name", SqlScalarType::String.nullable(false))
1119 .with_column("cluster_name", SqlScalarType::String.nullable(true))
1120 .with_column("database_name", SqlScalarType::String.nullable(false))
1121 .with_column("search_path", SqlScalarType::List { element_type: Box::new(SqlScalarType::String), custom_id: None }.nullable(false))
1122 .with_column("transaction_isolation", SqlScalarType::String.nullable(false))
1123 .with_column("execution_timestamp", SqlScalarType::UInt64.nullable(true))
1124 .with_column("transaction_id", SqlScalarType::UInt64.nullable(false))
1125 .with_column("transient_index_id", SqlScalarType::String.nullable(true))
1126 .with_column("mz_version", SqlScalarType::String.nullable(false))
1127 .with_column("began_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1128 .with_column("finished_at", SqlScalarType::TimestampTz { precision: None }.nullable(true))
1129 .with_column("finished_status", SqlScalarType::String.nullable(true))
1130 .with_column("result_size", SqlScalarType::Int64.nullable(true))
1131 .with_column("rows_returned", SqlScalarType::Int64.nullable(true))
1132 .with_column("execution_strategy", SqlScalarType::String.nullable(true))
1133 .finish(),
1134 column_comments: BTreeMap::new(),
1135 sql: "
1136SELECT id, prepared_statement_id, sample_rate, cluster_id, application_name,
1137cluster_name, database_name, search_path, transaction_isolation, execution_timestamp, transaction_id,
1138transient_index_id, mz_version, began_at, finished_at, finished_status,
1139result_size, rows_returned, execution_strategy
1140FROM mz_internal.mz_statement_execution_history",
1141 access: vec![SUPPORT_SELECT, ANALYTICS_SELECT, MONITOR_REDACTED_SELECT, MONITOR_SELECT],
1142 ontology: None,
1143}
1144});
1145
1146pub static MZ_PREPARED_STATEMENT_HISTORY: LazyLock<BuiltinSource> =
1147 LazyLock::new(|| BuiltinSource {
1148 name: "mz_prepared_statement_history",
1149 schema: MZ_INTERNAL_SCHEMA,
1150 oid: oid::SOURCE_MZ_PREPARED_STATEMENT_HISTORY_OID,
1151 data_source: IntrospectionType::PreparedStatementHistory.into(),
1152 desc: MZ_PREPARED_STATEMENT_HISTORY_DESC.clone(),
1153 column_comments: BTreeMap::new(),
1154 is_retained_metrics_object: false,
1155 access: vec![
1156 SUPPORT_SELECT,
1157 ANALYTICS_SELECT,
1158 MONITOR_REDACTED_SELECT,
1159 MONITOR_SELECT,
1160 ],
1161 ontology: None,
1162 });
1163
1164pub static MZ_SQL_TEXT: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
1165 name: "mz_sql_text",
1166 schema: MZ_INTERNAL_SCHEMA,
1167 oid: oid::SOURCE_MZ_SQL_TEXT_OID,
1168 desc: MZ_SQL_TEXT_DESC.clone(),
1169 data_source: IntrospectionType::SqlText.into(),
1170 column_comments: BTreeMap::new(),
1171 is_retained_metrics_object: false,
1172 access: vec![MONITOR_SELECT],
1173 ontology: Some(Ontology {
1174 entity_name: "sql_text",
1175 description: "Raw SQL text of executed statements",
1176 links: &const { [] },
1177 column_semantic_types: &[],
1178 }),
1179});
1180
1181pub static MZ_SQL_TEXT_REDACTED: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
1182 name: "mz_sql_text_redacted",
1183 schema: MZ_INTERNAL_SCHEMA,
1184 oid: oid::VIEW_MZ_SQL_TEXT_REDACTED_OID,
1185 desc: RelationDesc::builder()
1186 .with_column("sql_hash", SqlScalarType::Bytes.nullable(false))
1187 .with_column("redacted_sql", SqlScalarType::String.nullable(false))
1188 .finish(),
1189 column_comments: BTreeMap::new(),
1190 sql: "SELECT sql_hash, redacted_sql FROM mz_internal.mz_sql_text",
1191 access: vec![
1192 MONITOR_SELECT,
1193 MONITOR_REDACTED_SELECT,
1194 SUPPORT_SELECT,
1195 ANALYTICS_SELECT,
1196 ],
1197 ontology: None,
1198});
1199
1200pub static MZ_RECENT_SQL_TEXT: LazyLock<BuiltinView> = LazyLock::new(|| {
1201 BuiltinView {
1202 name: "mz_recent_sql_text",
1203 schema: MZ_INTERNAL_SCHEMA,
1204 oid: oid::VIEW_MZ_RECENT_SQL_TEXT_OID,
1205 desc: RelationDesc::builder()
1210 .with_column("sql_hash", SqlScalarType::Bytes.nullable(false))
1211 .with_column("sql", SqlScalarType::String.nullable(false))
1212 .with_column("redacted_sql", SqlScalarType::String.nullable(false))
1213 .with_key(vec![0, 1, 2])
1214 .finish(),
1215 column_comments: BTreeMap::new(),
1216 sql: "SELECT DISTINCT sql_hash, sql, redacted_sql FROM mz_internal.mz_sql_text WHERE prepared_day + INTERVAL '4 days' >= mz_now()",
1217 access: vec![MONITOR_SELECT],
1218 ontology: Some(Ontology {
1219 entity_name: "recent_sql_text",
1220 description: "Recent SQL text (indexed, last ~3-4 days)",
1221 links: &const { [] },
1222 column_semantic_types: &[("sql", SemanticType::SqlDefinition)],
1223 }),
1224 }
1225});
1226
1227pub static MZ_RECENT_SQL_TEXT_REDACTED: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
1228 name: "mz_recent_sql_text_redacted",
1229 schema: MZ_INTERNAL_SCHEMA,
1230 oid: oid::VIEW_MZ_RECENT_SQL_TEXT_REDACTED_OID,
1231 desc: RelationDesc::builder()
1232 .with_column("sql_hash", SqlScalarType::Bytes.nullable(false))
1233 .with_column("redacted_sql", SqlScalarType::String.nullable(false))
1234 .finish(),
1235 column_comments: BTreeMap::new(),
1236 sql: "SELECT sql_hash, redacted_sql FROM mz_internal.mz_recent_sql_text",
1237 access: vec![
1238 MONITOR_SELECT,
1239 MONITOR_REDACTED_SELECT,
1240 SUPPORT_SELECT,
1241 ANALYTICS_SELECT,
1242 ],
1243 ontology: None,
1244});
1245
1246pub static MZ_RECENT_SQL_TEXT_IND: LazyLock<BuiltinIndex> = LazyLock::new(|| BuiltinIndex {
1247 name: "mz_recent_sql_text_ind",
1248 schema: MZ_INTERNAL_SCHEMA,
1249 oid: oid::INDEX_MZ_RECENT_SQL_TEXT_IND_OID,
1250 sql: "IN CLUSTER mz_catalog_server ON mz_internal.mz_recent_sql_text (sql_hash)",
1251 is_retained_metrics_object: false,
1252});
1253
1254pub static MZ_SESSION_HISTORY: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
1255 name: "mz_session_history",
1256 schema: MZ_INTERNAL_SCHEMA,
1257 oid: oid::SOURCE_MZ_SESSION_HISTORY_OID,
1258 data_source: IntrospectionType::SessionHistory.into(),
1259 desc: MZ_SESSION_HISTORY_DESC.clone(),
1260 column_comments: BTreeMap::from_iter([
1261 (
1262 "session_id",
1263 "The globally unique ID of the session. Corresponds to `mz_sessions.id`.",
1264 ),
1265 (
1266 "connected_at",
1267 "The time at which the session was established.",
1268 ),
1269 (
1270 "initial_application_name",
1271 "The `application_name` session metadata field.",
1272 ),
1273 (
1274 "authenticated_user",
1275 "The name of the user for which the session was established.",
1276 ),
1277 ]),
1278 is_retained_metrics_object: false,
1279 access: vec![PUBLIC_SELECT],
1280 ontology: Some(Ontology {
1281 entity_name: "session",
1282 description: "Historical session connection events",
1283 links: &const {
1284 [OntologyLink {
1285 name: "active_as",
1286 target: "active_session",
1287 properties: LinkProperties::fk_nullable("session_id", "id", Cardinality::ManyToOne),
1288 }]
1289 },
1290 column_semantic_types: &[("connected_at", SemanticType::WallclockTimestamp)],
1291 }),
1292});
1293
1294pub static MZ_ACTIVITY_LOG_THINNED: LazyLock<BuiltinView> = LazyLock::new(|| {
1295 BuiltinView {
1296 name: "mz_activity_log_thinned",
1297 schema: MZ_INTERNAL_SCHEMA,
1298 oid: oid::VIEW_MZ_ACTIVITY_LOG_THINNED_OID,
1299 desc: RelationDesc::builder()
1300 .with_column("execution_id", SqlScalarType::Uuid.nullable(false))
1301 .with_column("sample_rate", SqlScalarType::Float64.nullable(false))
1302 .with_column("cluster_id", SqlScalarType::String.nullable(true))
1303 .with_column("application_name", SqlScalarType::String.nullable(false))
1304 .with_column("cluster_name", SqlScalarType::String.nullable(true))
1305 .with_column("database_name", SqlScalarType::String.nullable(false))
1306 .with_column("search_path", SqlScalarType::List { element_type: Box::new(SqlScalarType::String), custom_id: None }.nullable(false))
1307 .with_column("transaction_isolation", SqlScalarType::String.nullable(false))
1308 .with_column("execution_timestamp", SqlScalarType::UInt64.nullable(true))
1309 .with_column("transient_index_id", SqlScalarType::String.nullable(true))
1310 .with_column("params", SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false))
1311 .with_column("mz_version", SqlScalarType::String.nullable(false))
1312 .with_column("began_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1313 .with_column("finished_at", SqlScalarType::TimestampTz { precision: None }.nullable(true))
1314 .with_column("finished_status", SqlScalarType::String.nullable(true))
1315 .with_column("error_message", SqlScalarType::String.nullable(true))
1316 .with_column("result_size", SqlScalarType::Int64.nullable(true))
1317 .with_column("rows_returned", SqlScalarType::Int64.nullable(true))
1318 .with_column("execution_strategy", SqlScalarType::String.nullable(true))
1319 .with_column("transaction_id", SqlScalarType::UInt64.nullable(false))
1320 .with_column("prepared_statement_id", SqlScalarType::Uuid.nullable(false))
1321 .with_column("sql_hash", SqlScalarType::Bytes.nullable(false))
1322 .with_column("prepared_statement_name", SqlScalarType::String.nullable(false))
1323 .with_column("session_id", SqlScalarType::Uuid.nullable(false))
1324 .with_column("prepared_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1325 .with_column("statement_type", SqlScalarType::String.nullable(true))
1326 .with_column("throttled_count", SqlScalarType::UInt64.nullable(false))
1327 .with_column("connected_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1328 .with_column("initial_application_name", SqlScalarType::String.nullable(false))
1329 .with_column("authenticated_user", SqlScalarType::String.nullable(false))
1330 .finish(),
1331 column_comments: BTreeMap::new(),
1332 sql: "
1333SELECT mseh.id AS execution_id, sample_rate, cluster_id, application_name, cluster_name, database_name, search_path,
1334transaction_isolation, execution_timestamp, transient_index_id, params, mz_version, began_at, finished_at, finished_status,
1335error_message, result_size, rows_returned, execution_strategy, transaction_id,
1336mpsh.id AS prepared_statement_id, sql_hash, mpsh.name AS prepared_statement_name,
1337mpsh.session_id, prepared_at, statement_type, throttled_count,
1338connected_at, initial_application_name, authenticated_user
1339FROM mz_internal.mz_statement_execution_history mseh,
1340 mz_internal.mz_prepared_statement_history mpsh,
1341 mz_internal.mz_session_history msh
1342WHERE mseh.prepared_statement_id = mpsh.id
1343AND mpsh.session_id = msh.session_id",
1344 access: vec![MONITOR_SELECT],
1345 ontology: None,
1346 }
1347});
1348
1349pub static MZ_RECENT_ACTIVITY_LOG_THINNED: LazyLock<BuiltinView> = LazyLock::new(|| {
1350 BuiltinView {
1351 name: "mz_recent_activity_log_thinned",
1352 schema: MZ_INTERNAL_SCHEMA,
1353 oid: oid::VIEW_MZ_RECENT_ACTIVITY_LOG_THINNED_OID,
1354 desc: RelationDesc::builder()
1355 .with_column("execution_id", SqlScalarType::Uuid.nullable(false))
1356 .with_column("sample_rate", SqlScalarType::Float64.nullable(false))
1357 .with_column("cluster_id", SqlScalarType::String.nullable(true))
1358 .with_column("application_name", SqlScalarType::String.nullable(false))
1359 .with_column("cluster_name", SqlScalarType::String.nullable(true))
1360 .with_column("database_name", SqlScalarType::String.nullable(false))
1361 .with_column("search_path", SqlScalarType::List { element_type: Box::new(SqlScalarType::String), custom_id: None }.nullable(false))
1362 .with_column("transaction_isolation", SqlScalarType::String.nullable(false))
1363 .with_column("execution_timestamp", SqlScalarType::UInt64.nullable(true))
1364 .with_column("transient_index_id", SqlScalarType::String.nullable(true))
1365 .with_column("params", SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false))
1366 .with_column("mz_version", SqlScalarType::String.nullable(false))
1367 .with_column("began_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1368 .with_column("finished_at", SqlScalarType::TimestampTz { precision: None }.nullable(true))
1369 .with_column("finished_status", SqlScalarType::String.nullable(true))
1370 .with_column("error_message", SqlScalarType::String.nullable(true))
1371 .with_column("result_size", SqlScalarType::Int64.nullable(true))
1372 .with_column("rows_returned", SqlScalarType::Int64.nullable(true))
1373 .with_column("execution_strategy", SqlScalarType::String.nullable(true))
1374 .with_column("transaction_id", SqlScalarType::UInt64.nullable(false))
1375 .with_column("prepared_statement_id", SqlScalarType::Uuid.nullable(false))
1376 .with_column("sql_hash", SqlScalarType::Bytes.nullable(false))
1377 .with_column("prepared_statement_name", SqlScalarType::String.nullable(false))
1378 .with_column("session_id", SqlScalarType::Uuid.nullable(false))
1379 .with_column("prepared_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1380 .with_column("statement_type", SqlScalarType::String.nullable(true))
1381 .with_column("throttled_count", SqlScalarType::UInt64.nullable(false))
1382 .with_column("connected_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1383 .with_column("initial_application_name", SqlScalarType::String.nullable(false))
1384 .with_column("authenticated_user", SqlScalarType::String.nullable(false))
1385 .finish(),
1386 column_comments: BTreeMap::new(),
1387 sql:
1390 "SELECT * FROM mz_internal.mz_activity_log_thinned WHERE prepared_at + INTERVAL '1 day' > mz_now()
1391AND began_at + INTERVAL '1 day' > mz_now() AND connected_at + INTERVAL '2 days' > mz_now()",
1392 access: vec![MONITOR_SELECT],
1393 ontology: None,
1394 }
1395});
1396
1397pub static MZ_RECENT_ACTIVITY_LOG: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
1398 name: "mz_recent_activity_log",
1399 schema: MZ_INTERNAL_SCHEMA,
1400 oid: oid::VIEW_MZ_RECENT_ACTIVITY_LOG_OID,
1401 desc: RelationDesc::builder()
1402 .with_column("execution_id", SqlScalarType::Uuid.nullable(false))
1403 .with_column("sample_rate", SqlScalarType::Float64.nullable(false))
1404 .with_column("cluster_id", SqlScalarType::String.nullable(true))
1405 .with_column("application_name", SqlScalarType::String.nullable(false))
1406 .with_column("cluster_name", SqlScalarType::String.nullable(true))
1407 .with_column("database_name", SqlScalarType::String.nullable(false))
1408 .with_column(
1409 "search_path",
1410 SqlScalarType::List {
1411 element_type: Box::new(SqlScalarType::String),
1412 custom_id: None,
1413 }
1414 .nullable(false),
1415 )
1416 .with_column(
1417 "transaction_isolation",
1418 SqlScalarType::String.nullable(false),
1419 )
1420 .with_column("execution_timestamp", SqlScalarType::UInt64.nullable(true))
1421 .with_column("transient_index_id", SqlScalarType::String.nullable(true))
1422 .with_column(
1423 "params",
1424 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
1425 )
1426 .with_column("mz_version", SqlScalarType::String.nullable(false))
1427 .with_column(
1428 "began_at",
1429 SqlScalarType::TimestampTz { precision: None }.nullable(false),
1430 )
1431 .with_column(
1432 "finished_at",
1433 SqlScalarType::TimestampTz { precision: None }.nullable(true),
1434 )
1435 .with_column("finished_status", SqlScalarType::String.nullable(true))
1436 .with_column("error_message", SqlScalarType::String.nullable(true))
1437 .with_column("result_size", SqlScalarType::Int64.nullable(true))
1438 .with_column("rows_returned", SqlScalarType::Int64.nullable(true))
1439 .with_column("execution_strategy", SqlScalarType::String.nullable(true))
1440 .with_column("transaction_id", SqlScalarType::UInt64.nullable(false))
1441 .with_column("prepared_statement_id", SqlScalarType::Uuid.nullable(false))
1442 .with_column("sql_hash", SqlScalarType::Bytes.nullable(false))
1443 .with_column(
1444 "prepared_statement_name",
1445 SqlScalarType::String.nullable(false),
1446 )
1447 .with_column("session_id", SqlScalarType::Uuid.nullable(false))
1448 .with_column(
1449 "prepared_at",
1450 SqlScalarType::TimestampTz { precision: None }.nullable(false),
1451 )
1452 .with_column("statement_type", SqlScalarType::String.nullable(true))
1453 .with_column("throttled_count", SqlScalarType::UInt64.nullable(false))
1454 .with_column(
1455 "connected_at",
1456 SqlScalarType::TimestampTz { precision: None }.nullable(false),
1457 )
1458 .with_column(
1459 "initial_application_name",
1460 SqlScalarType::String.nullable(false),
1461 )
1462 .with_column("authenticated_user", SqlScalarType::String.nullable(false))
1463 .with_column("sql", SqlScalarType::String.nullable(false))
1464 .finish(),
1465 column_comments: BTreeMap::from_iter([
1466 (
1467 "execution_id",
1468 "An ID that is unique for each executed statement.",
1469 ),
1470 (
1471 "sample_rate",
1472 "The actual rate at which the statement was sampled.",
1473 ),
1474 (
1475 "cluster_id",
1476 "The ID of the cluster the statement execution was directed to. Corresponds to mz_clusters.id.",
1477 ),
1478 (
1479 "application_name",
1480 "The value of the `application_name` configuration parameter at execution time.",
1481 ),
1482 (
1483 "cluster_name",
1484 "The name of the cluster with ID `cluster_id` at execution time.",
1485 ),
1486 (
1487 "database_name",
1488 "The value of the `database` configuration parameter at execution time.",
1489 ),
1490 (
1491 "search_path",
1492 "The value of the `search_path` configuration parameter at execution time.",
1493 ),
1494 (
1495 "transaction_isolation",
1496 "The value of the `transaction_isolation` configuration parameter at execution time.",
1497 ),
1498 (
1499 "execution_timestamp",
1500 "The logical timestamp at which execution was scheduled.",
1501 ),
1502 (
1503 "transient_index_id",
1504 "The internal index of the compute dataflow created for the query, if any.",
1505 ),
1506 (
1507 "params",
1508 "The parameters with which the statement was executed.",
1509 ),
1510 (
1511 "mz_version",
1512 "The version of Materialize that was running when the statement was executed.",
1513 ),
1514 (
1515 "began_at",
1516 "The wall-clock time at which the statement began executing.",
1517 ),
1518 (
1519 "finished_at",
1520 "The wall-clock time at which the statement finished executing.",
1521 ),
1522 (
1523 "finished_status",
1524 "The final status of the statement (e.g., `success`, `canceled`, `error`, or `aborted`). \
1525 `aborted` means that the client disconnected before the statement finished executing.",
1526 ),
1527 (
1528 "error_message",
1529 "The error message, if the statement failed.",
1530 ),
1531 (
1532 "result_size",
1533 "The size in bytes of the result, for statements that return rows.",
1534 ),
1535 (
1536 "rows_returned",
1537 "The number of rows returned, for statements that return rows.",
1538 ),
1539 (
1540 "execution_strategy",
1541 "For `SELECT` statements (and similar statement types), the strategy for executing the query. \
1542 `standard` means computed by a temporary dataflow, \
1543 `fast-path` means read by a cluster directly from an in-memory index, \
1544 `persist-fast-path` means read a source, table, or materialized view from blob storage (without an index or dataflow), \
1545 and `constant` means computed in the control plane without the involvement of a cluster. \
1546 (It's `NULL` for statements that errored/canceled/aborted and for non-query-like statement types.)",
1547 ),
1548 (
1549 "transaction_id",
1550 "The ID of the transaction that the statement was part of. Note that transaction IDs are only unique per session.",
1551 ),
1552 (
1553 "prepared_statement_id",
1554 "An ID that is unique for each prepared statement. For example, if a statement is prepared once and then executed multiple times, all executions will have the same value for this column (but different values for `execution_id`).",
1555 ),
1556 (
1557 "sql_hash",
1558 "An opaque value uniquely identifying the text of the query.",
1559 ),
1560 (
1561 "prepared_statement_name",
1562 "The name given by the client library to the prepared statement.",
1563 ),
1564 (
1565 "session_id",
1566 "An ID that is unique for each session. Corresponds to mz_sessions.id.",
1567 ),
1568 (
1569 "prepared_at",
1570 "The time at which the statement was prepared.",
1571 ),
1572 (
1573 "statement_type",
1574 "The _type_ of the statement, e.g. `select` for a `SELECT` query, or `NULL` if the statement was empty.",
1575 ),
1576 (
1577 "throttled_count",
1578 "The number of statement executions dropped due to throttling between the previously logged statement and this one. If you have a very high volume of queries and need to log them without throttling, contact our team.",
1579 ),
1580 (
1581 "connected_at",
1582 "The time at which the session was established.",
1583 ),
1584 (
1585 "initial_application_name",
1586 "The initial value of `application_name` at the beginning of the session.",
1587 ),
1588 (
1589 "authenticated_user",
1590 "The name of the user for which the session was established.",
1591 ),
1592 ("sql", "The SQL text of the statement."),
1593 ]),
1594 sql: "SELECT mralt.*, mrst.sql
1595FROM mz_internal.mz_recent_activity_log_thinned mralt,
1596 mz_internal.mz_recent_sql_text mrst
1597WHERE mralt.sql_hash = mrst.sql_hash",
1598 access: vec![MONITOR_SELECT],
1599 ontology: Some(Ontology {
1600 entity_name: "activity_log",
1601 description: "Recent query activity with execution stats",
1602 links: &const {
1603 [
1604 OntologyLink {
1605 name: "in_session",
1606 target: "session",
1607 properties: LinkProperties::fk("session_id", "id", Cardinality::ManyToOne),
1608 },
1609 OntologyLink {
1610 name: "in_active_session",
1611 target: "active_session",
1612 properties: LinkProperties::fk_nullable(
1613 "session_id",
1614 "id",
1615 Cardinality::ManyToOne,
1616 ),
1617 },
1618 OntologyLink {
1619 name: "ran_on_cluster",
1620 target: "cluster",
1621 properties: LinkProperties::fk_nullable(
1622 "cluster_id",
1623 "id",
1624 Cardinality::ManyToOne,
1625 ),
1626 },
1627 OntologyLink {
1628 name: "used_transient_index",
1629 target: "object",
1630 properties: LinkProperties::ForeignKey {
1631 source_column: "transient_index_id",
1632 target_column: "id",
1633 cardinality: Cardinality::ManyToOne,
1634 source_id_type: Some(mz_repr::SemanticType::GlobalId),
1635 requires_mapping: Some("mz_internal.mz_object_global_ids"),
1636 nullable: true,
1637 note: None,
1638 extra_key_columns: None,
1639 },
1640 },
1641 ]
1642 },
1643 column_semantic_types: &const {
1644 [
1645 ("cluster_id", SemanticType::ClusterId),
1646 ("execution_timestamp", SemanticType::MzTimestamp),
1647 ("transient_index_id", SemanticType::GlobalId),
1648 ("began_at", SemanticType::WallclockTimestamp),
1649 ("finished_at", SemanticType::WallclockTimestamp),
1650 ("prepared_at", SemanticType::WallclockTimestamp),
1651 ("connected_at", SemanticType::WallclockTimestamp),
1652 ("sql", SemanticType::SqlDefinition),
1653 ]
1654 },
1655 }),
1656});
1657
1658pub static MZ_RECENT_ACTIVITY_LOG_REDACTED: LazyLock<BuiltinView> = LazyLock::new(|| {
1659 BuiltinView {
1660 name: "mz_recent_activity_log_redacted",
1661 schema: MZ_INTERNAL_SCHEMA,
1662 oid: oid::VIEW_MZ_RECENT_ACTIVITY_LOG_REDACTED_OID,
1663 desc: RelationDesc::builder()
1665 .with_column("execution_id", SqlScalarType::Uuid.nullable(false))
1666 .with_column("sample_rate", SqlScalarType::Float64.nullable(false))
1667 .with_column("cluster_id", SqlScalarType::String.nullable(true))
1668 .with_column("application_name", SqlScalarType::String.nullable(false))
1669 .with_column("cluster_name", SqlScalarType::String.nullable(true))
1670 .with_column("database_name", SqlScalarType::String.nullable(false))
1671 .with_column("search_path", SqlScalarType::List { element_type: Box::new(SqlScalarType::String), custom_id: None }.nullable(false))
1672 .with_column("transaction_isolation", SqlScalarType::String.nullable(false))
1673 .with_column("execution_timestamp", SqlScalarType::UInt64.nullable(true))
1674 .with_column("transient_index_id", SqlScalarType::String.nullable(true))
1675 .with_column("mz_version", SqlScalarType::String.nullable(false))
1676 .with_column("began_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1677 .with_column("finished_at", SqlScalarType::TimestampTz { precision: None }.nullable(true))
1678 .with_column("finished_status", SqlScalarType::String.nullable(true))
1679 .with_column("result_size", SqlScalarType::Int64.nullable(true))
1680 .with_column("rows_returned", SqlScalarType::Int64.nullable(true))
1681 .with_column("execution_strategy", SqlScalarType::String.nullable(true))
1682 .with_column("transaction_id", SqlScalarType::UInt64.nullable(false))
1683 .with_column("prepared_statement_id", SqlScalarType::Uuid.nullable(false))
1684 .with_column("sql_hash", SqlScalarType::Bytes.nullable(false))
1685 .with_column("prepared_statement_name", SqlScalarType::String.nullable(false))
1686 .with_column("session_id", SqlScalarType::Uuid.nullable(false))
1687 .with_column("prepared_at", SqlScalarType::TimestampTz { precision: None }.nullable(false))
1688 .with_column("statement_type", SqlScalarType::String.nullable(true))
1689 .with_column("throttled_count", SqlScalarType::UInt64.nullable(false))
1690 .with_column("initial_application_name", SqlScalarType::String.nullable(false))
1691 .with_column("authenticated_user", SqlScalarType::String.nullable(false))
1692 .with_column("redacted_sql", SqlScalarType::String.nullable(false))
1693 .finish(),
1694 column_comments: BTreeMap::new(),
1695 sql: "SELECT mralt.execution_id, mralt.sample_rate, mralt.cluster_id, mralt.application_name,
1696 mralt.cluster_name, mralt.database_name, mralt.search_path, mralt.transaction_isolation, mralt.execution_timestamp,
1697 mralt.transient_index_id, mralt.mz_version, mralt.began_at, mralt.finished_at,
1698 mralt.finished_status, mralt.result_size, mralt.rows_returned, mralt.execution_strategy, mralt.transaction_id,
1699 mralt.prepared_statement_id, mralt.sql_hash, mralt.prepared_statement_name, mralt.session_id,
1700 mralt.prepared_at, mralt.statement_type, mralt.throttled_count,
1701 mralt.initial_application_name, mralt.authenticated_user,
1702 mrst.redacted_sql
1703FROM mz_internal.mz_recent_activity_log_thinned mralt,
1704 mz_internal.mz_recent_sql_text mrst
1705WHERE mralt.sql_hash = mrst.sql_hash",
1706 access: vec![MONITOR_SELECT, MONITOR_REDACTED_SELECT, SUPPORT_SELECT, ANALYTICS_SELECT],
1707 ontology: None,
1708}
1709});
1710
1711pub static MZ_STATEMENT_LIFECYCLE_HISTORY: LazyLock<BuiltinSource> = LazyLock::new(|| {
1712 BuiltinSource {
1713 name: "mz_statement_lifecycle_history",
1714 schema: MZ_INTERNAL_SCHEMA,
1715 oid: oid::SOURCE_MZ_STATEMENT_LIFECYCLE_HISTORY_OID,
1716 desc: RelationDesc::builder()
1717 .with_column("statement_id", SqlScalarType::Uuid.nullable(false))
1718 .with_column("event_type", SqlScalarType::String.nullable(false))
1719 .with_column(
1720 "occurred_at",
1721 SqlScalarType::TimestampTz { precision: None }.nullable(false),
1722 )
1723 .finish(),
1724 data_source: IntrospectionType::StatementLifecycleHistory.into(),
1725 column_comments: BTreeMap::from_iter([
1726 (
1727 "statement_id",
1728 "The ID of the execution event. Corresponds to `mz_recent_activity_log.execution_id`",
1729 ),
1730 (
1731 "event_type",
1732 "The type of lifecycle event, e.g. `'execution-began'`, `'storage-dependencies-finished'`, `'compute-dependencies-finished'`, or `'execution-finished'`",
1733 ),
1734 ("occurred_at", "The time at which the event took place."),
1735 ]),
1736 is_retained_metrics_object: false,
1737 access: vec![
1741 SUPPORT_SELECT,
1742 ANALYTICS_SELECT,
1743 MONITOR_REDACTED_SELECT,
1744 MONITOR_SELECT,
1745 ],
1746 ontology: Some(Ontology {
1747 entity_name: "statement_lifecycle_event",
1748 description: "Statement lifecycle events (parse, bind, execute)",
1749 links: &const {
1750 [OntologyLink {
1751 name: "for_execution",
1752 target: "activity_log",
1753 properties: LinkProperties::fk(
1754 "statement_id",
1755 "execution_id",
1756 Cardinality::ManyToOne,
1757 ),
1758 }]
1759 },
1760 column_semantic_types: &[],
1761 }),
1762 }
1763});
1764
1765pub static MZ_SOURCE_STATUSES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
1766 name: "mz_source_statuses",
1767 schema: MZ_INTERNAL_SCHEMA,
1768 oid: oid::VIEW_MZ_SOURCE_STATUSES_OID,
1769 desc: RelationDesc::builder()
1770 .with_column("id", SqlScalarType::String.nullable(false))
1771 .with_column("name", SqlScalarType::String.nullable(false))
1772 .with_column("type", SqlScalarType::String.nullable(false))
1773 .with_column(
1774 "last_status_change_at",
1775 SqlScalarType::TimestampTz { precision: None }.nullable(true),
1776 )
1777 .with_column("status", SqlScalarType::String.nullable(false))
1778 .with_column("error", SqlScalarType::String.nullable(true))
1779 .with_column("details", SqlScalarType::Jsonb.nullable(true))
1780 .finish(),
1781 column_comments: BTreeMap::from_iter([
1782 (
1783 "id",
1784 "The ID of the source. Corresponds to `mz_catalog.mz_sources.id`.",
1785 ),
1786 ("name", "The name of the source."),
1787 ("type", "The type of the source."),
1788 (
1789 "last_status_change_at",
1790 "Wall-clock timestamp of the source status change.",
1791 ),
1792 (
1793 "status",
1794 "The status of the source: one of `created`, `starting`, `running`, `paused`, `stalled`, `failed`, or `dropped`.",
1795 ),
1796 (
1797 "error",
1798 "If the source is in an error state, the error message.",
1799 ),
1800 (
1801 "details",
1802 "Additional metadata provided by the source. In case of error, may contain a `hint` field with helpful suggestions.",
1803 ),
1804 ]),
1805 sql: "
1806 WITH
1807 -- The status history contains per-replica events and source-global events.
1808 -- For the latter, replica_id is NULL. We turn these into '<source>', so that
1809 -- we can treat them uniformly below.
1810 uniform_status_history AS
1811 (
1812 SELECT
1813 s.source_id,
1814 COALESCE(s.replica_id, '<source>') as replica_id,
1815 s.occurred_at,
1816 s.status,
1817 s.error,
1818 s.details
1819 FROM mz_internal.mz_source_status_history s
1820 ),
1821 -- For getting the latest events, we first determine the latest per-replica
1822 -- events here and then apply precedence rules below.
1823 --
1824 -- We ignore per-replica events from replicas that no longer exist. A dropped
1825 -- replica's last reported status is stale: without this filter a defunct
1826 -- replica's lingering 'running' can outrank (see precedence below) a live
1827 -- replica's 'stalled', hiding a genuinely broken source. We always retain
1828 -- source-global events ('<source>' is the sentinel for replica_id NULL)
1829 -- and 'paused' events. A per-replica 'paused' is only written when the
1830 -- replica is dropped, so it is a terminal drop marker, not a stale report.
1831 latest_per_replica_events AS
1832 (
1833 SELECT DISTINCT ON (source_id, replica_id)
1834 occurred_at, source_id, replica_id, status, error, details
1835 FROM uniform_status_history
1836 WHERE replica_id = '<source>'
1837 OR replica_id IN (SELECT id FROM mz_catalog.mz_cluster_replicas)
1838 OR status = 'paused'
1839 ORDER BY source_id, replica_id, occurred_at DESC
1840 ),
1841 -- We have a precedence list that determines the overall status in case
1842 -- there is differing per-replica (including source-global) statuses. If
1843 -- there is no 'dropped' status, and any replica reports 'running', the
1844 -- overall status is 'running' even if there might be some replica that has
1845 -- errors or is paused. Precedence ties are broken by recency, so a dropped
1846 -- replica's 'paused' wins over an older source-global 'paused'.
1847 latest_events AS
1848 (
1849 SELECT DISTINCT ON (source_id)
1850 source_id,
1851 occurred_at,
1852 status,
1853 error,
1854 details
1855 FROM latest_per_replica_events
1856 ORDER BY source_id, CASE status
1857 WHEN 'dropped' THEN 1
1858 WHEN 'running' THEN 2
1859 WHEN 'stalled' THEN 3
1860 WHEN 'starting' THEN 4
1861 WHEN 'paused' THEN 5
1862 WHEN 'ceased' THEN 6
1863 ELSE 7 -- For any other status values
1864 END, occurred_at DESC
1865 ),
1866 -- Determine which sources are subsources and which are parent sources
1867 subsources AS
1868 (
1869 SELECT subsources.id AS self, sources.id AS parent
1870 FROM
1871 mz_catalog.mz_sources AS subsources
1872 JOIN
1873 mz_internal.mz_object_dependencies AS deps
1874 ON subsources.id = deps.object_id
1875 JOIN mz_catalog.mz_sources AS sources ON sources.id = deps.referenced_object_id
1876 ),
1877 -- Determine which sources are source tables
1878 tables AS
1879 (
1880 SELECT tables.id AS self, tables.source_id AS parent, tables.name
1881 FROM mz_catalog.mz_tables AS tables
1882 WHERE tables.source_id IS NOT NULL
1883 ),
1884 -- Determine which collection's ID to use for the status
1885 id_of_status_to_use AS
1886 (
1887 SELECT
1888 self_events.source_id,
1889 -- If self not errored, but parent is, use parent; else self
1890 CASE
1891 WHEN
1892 self_events.status <> 'ceased' AND
1893 parent_events.status = 'stalled'
1894 THEN parent_events.source_id
1895 ELSE self_events.source_id
1896 END AS id_to_use
1897 FROM
1898 latest_events AS self_events
1899 LEFT JOIN subsources ON self_events.source_id = subsources.self
1900 LEFT JOIN tables ON self_events.source_id = tables.self
1901 LEFT JOIN
1902 latest_events AS parent_events
1903 ON parent_events.source_id = COALESCE(subsources.parent, tables.parent)
1904 ),
1905 -- Swap out events for the ID of the event we plan to use instead
1906 latest_events_to_use AS
1907 (
1908 SELECT occurred_at, s.source_id, status, error, details
1909 FROM
1910 id_of_status_to_use AS s
1911 JOIN latest_events AS e ON e.source_id = s.id_to_use
1912 ),
1913 combined AS (
1914 SELECT
1915 mz_sources.id,
1916 mz_sources.name,
1917 mz_sources.type,
1918 occurred_at,
1919 status,
1920 error,
1921 details
1922 FROM
1923 mz_catalog.mz_sources
1924 LEFT JOIN latest_events_to_use AS e ON mz_sources.id = e.source_id
1925 UNION ALL
1926 SELECT
1927 tables.self AS id,
1928 tables.name,
1929 'table' AS type,
1930 occurred_at,
1931 status,
1932 error,
1933 details
1934 FROM
1935 tables
1936 LEFT JOIN latest_events_to_use AS e ON tables.self = e.source_id
1937 )
1938SELECT
1939 id,
1940 name,
1941 type,
1942 occurred_at AS last_status_change_at,
1943 -- TODO(parkmycar): Report status of webhook source once database-issues#5986 is closed.
1944 CASE
1945 WHEN
1946 type = 'webhook' OR
1947 type = 'progress'
1948 THEN 'running'
1949 ELSE COALESCE(status, 'created')
1950 END AS status,
1951 error,
1952 details
1953FROM combined
1954WHERE id NOT LIKE 's%';",
1955 access: vec![PUBLIC_SELECT],
1956 ontology: Some(Ontology {
1957 entity_name: "source_status",
1958 description: "Current source status (running, stalled, etc.)",
1959 links: &const {
1960 [OntologyLink {
1961 name: "status_of_source",
1962 target: "source",
1963 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
1964 }]
1965 },
1966 column_semantic_types: &const {
1967 [
1968 ("id", SemanticType::CatalogItemId),
1969 ("type", SemanticType::SourceType),
1970 ("last_status_change_at", SemanticType::WallclockTimestamp),
1971 ]
1972 },
1973 }),
1974});
1975
1976pub static MZ_SINK_STATUS_HISTORY: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
1977 name: "mz_sink_status_history",
1978 schema: MZ_INTERNAL_SCHEMA,
1979 oid: oid::SOURCE_MZ_SINK_STATUS_HISTORY_OID,
1980 data_source: IntrospectionType::SinkStatusHistory.into(),
1981 desc: MZ_SINK_STATUS_HISTORY_DESC.clone(),
1982 column_comments: BTreeMap::from_iter([
1983 (
1984 "occurred_at",
1985 "Wall-clock timestamp of the sink status change.",
1986 ),
1987 (
1988 "sink_id",
1989 "The ID of the sink. Corresponds to `mz_catalog.mz_sinks.id`.",
1990 ),
1991 (
1992 "status",
1993 "The status of the sink: one of `created`, `starting`, `running`, `stalled`, `failed`, or `dropped`.",
1994 ),
1995 (
1996 "error",
1997 "If the sink is in an error state, the error message.",
1998 ),
1999 (
2000 "details",
2001 "Additional metadata provided by the sink. In case of error, may contain a `hint` field with helpful suggestions.",
2002 ),
2003 (
2004 "replica_id",
2005 "The ID of the replica that an instance of a sink is running on.",
2006 ),
2007 ]),
2008 is_retained_metrics_object: false,
2009 access: vec![PUBLIC_SELECT],
2010 ontology: Some(Ontology {
2011 entity_name: "sink_status_event",
2012 description: "Historical sink status events",
2013 links: &const {
2014 [
2015 OntologyLink {
2016 name: "status_event_of_sink",
2017 target: "sink",
2018 properties: LinkProperties::fk_mapped(
2019 "sink_id",
2020 "id",
2021 Cardinality::ManyToOne,
2022 mz_repr::SemanticType::GlobalId,
2023 "mz_internal.mz_object_global_ids",
2024 ),
2025 },
2026 OntologyLink {
2027 name: "on_replica",
2028 target: "replica",
2029 properties: LinkProperties::fk_nullable(
2030 "replica_id",
2031 "id",
2032 Cardinality::ManyToOne,
2033 ),
2034 },
2035 ]
2036 },
2037 column_semantic_types: &const {
2038 [
2039 ("occurred_at", SemanticType::WallclockTimestamp),
2040 ("sink_id", SemanticType::GlobalId),
2041 ("replica_id", SemanticType::ReplicaId),
2042 ]
2043 },
2044 }),
2045});
2046
2047pub static MZ_SINK_STATUSES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2048 name: "mz_sink_statuses",
2049 schema: MZ_INTERNAL_SCHEMA,
2050 oid: oid::VIEW_MZ_SINK_STATUSES_OID,
2051 desc: RelationDesc::builder()
2052 .with_column("id", SqlScalarType::String.nullable(false))
2053 .with_column("name", SqlScalarType::String.nullable(false))
2054 .with_column("type", SqlScalarType::String.nullable(false))
2055 .with_column(
2056 "last_status_change_at",
2057 SqlScalarType::TimestampTz { precision: None }.nullable(true),
2058 )
2059 .with_column("status", SqlScalarType::String.nullable(false))
2060 .with_column("error", SqlScalarType::String.nullable(true))
2061 .with_column("details", SqlScalarType::Jsonb.nullable(true))
2062 .finish(),
2063 column_comments: BTreeMap::from_iter([
2064 (
2065 "id",
2066 "The ID of the sink. Corresponds to `mz_catalog.mz_sinks.id`.",
2067 ),
2068 ("name", "The name of the sink."),
2069 ("type", "The type of the sink."),
2070 (
2071 "last_status_change_at",
2072 "Wall-clock timestamp of the sink status change.",
2073 ),
2074 (
2075 "status",
2076 "The status of the sink: one of `created`, `starting`, `running`, `stalled`, `failed`, or `dropped`.",
2077 ),
2078 (
2079 "error",
2080 "If the sink is in an error state, the error message.",
2081 ),
2082 (
2083 "details",
2084 "Additional metadata provided by the sink. In case of error, may contain a `hint` field with helpful suggestions.",
2085 ),
2086 ]),
2087 sql: "
2088WITH
2089-- The status history contains per-replica events and sink-global events.
2090-- For the latter, replica_id is NULL. We turn these into '<sink>', so that
2091-- we can treat them uniformly below.
2092uniform_status_history AS
2093(
2094 SELECT
2095 s.sink_id,
2096 COALESCE(s.replica_id, '<sink>') as replica_id,
2097 s.occurred_at,
2098 s.status,
2099 s.error,
2100 s.details
2101 FROM mz_internal.mz_sink_status_history s
2102),
2103-- For getting the latest events, we first determine the latest per-replica
2104-- events here and then apply precedence rules below.
2105--
2106-- We ignore per-replica events from replicas that no longer exist. A dropped
2107-- replica's last reported status is stale: without this filter a defunct
2108-- replica's lingering 'running' can outrank (see precedence below) a live
2109-- replica's 'stalled', hiding a genuinely broken sink. We always retain
2110-- sink-global events ('<sink>' is the sentinel for replica_id NULL)
2111-- and 'paused' events. A per-replica 'paused' is only written when the
2112-- replica is dropped, so it is a terminal drop marker, not a stale report.
2113latest_per_replica_events AS
2114(
2115 SELECT DISTINCT ON (sink_id, replica_id)
2116 occurred_at, sink_id, replica_id, status, error, details
2117 FROM uniform_status_history
2118 WHERE replica_id = '<sink>'
2119 OR replica_id IN (SELECT id FROM mz_catalog.mz_cluster_replicas)
2120 OR status = 'paused'
2121 ORDER BY sink_id, replica_id, occurred_at DESC
2122),
2123-- We have a precedence list that determines the overall status in case
2124-- there is differing per-replica (including sink-global) statuses. If
2125-- there is no 'dropped' status, and any replica reports 'running', the
2126-- overall status is 'running' even if there might be some replica that has
2127-- errors or is paused. Precedence ties are broken by recency, so a dropped
2128-- replica's 'paused' wins over an older sink-global 'paused'.
2129latest_events AS
2130(
2131 SELECT DISTINCT ON (sink_id)
2132 sink_id,
2133 occurred_at,
2134 status,
2135 error,
2136 details
2137 FROM latest_per_replica_events
2138 ORDER BY sink_id, CASE status
2139 WHEN 'dropped' THEN 1
2140 WHEN 'running' THEN 2
2141 WHEN 'stalled' THEN 3
2142 WHEN 'starting' THEN 4
2143 WHEN 'paused' THEN 5
2144 WHEN 'ceased' THEN 6
2145 ELSE 7 -- For any other status values
2146 END, occurred_at DESC
2147)
2148SELECT
2149 mz_sinks.id,
2150 name,
2151 mz_sinks.type,
2152 occurred_at as last_status_change_at,
2153 coalesce(status, 'created') as status,
2154 error,
2155 details
2156FROM mz_catalog.mz_sinks
2157LEFT JOIN latest_events ON mz_sinks.id = latest_events.sink_id
2158WHERE
2159 -- This is a convenient way to filter out system sinks, like the status_history table itself.
2160 mz_sinks.id NOT LIKE 's%'",
2161 access: vec![PUBLIC_SELECT],
2162 ontology: Some(Ontology {
2163 entity_name: "sink_status",
2164 description: "Current sink status",
2165 links: &const {
2166 [OntologyLink {
2167 name: "status_of_sink",
2168 target: "sink",
2169 properties: LinkProperties::fk_typed(
2170 "id",
2171 "id",
2172 Cardinality::OneToOne,
2173 mz_repr::SemanticType::CatalogItemId,
2174 ),
2175 }]
2176 },
2177 column_semantic_types: &const {
2178 [
2179 ("id", SemanticType::CatalogItemId),
2180 ("last_status_change_at", SemanticType::WallclockTimestamp),
2181 ]
2182 },
2183 }),
2184});
2185
2186pub static MZ_STORAGE_USAGE_BY_SHARD: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2187 name: "mz_storage_usage_by_shard",
2188 schema: MZ_INTERNAL_SCHEMA,
2189 oid: oid::TABLE_MZ_STORAGE_USAGE_BY_SHARD_OID,
2190 desc: RelationDesc::builder()
2191 .with_column("id", SqlScalarType::UInt64.nullable(false))
2192 .with_column("shard_id", SqlScalarType::String.nullable(true))
2193 .with_column("size_bytes", SqlScalarType::UInt64.nullable(false))
2194 .with_column(
2195 "collection_timestamp",
2196 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2197 )
2198 .finish(),
2199 column_comments: BTreeMap::new(),
2200 is_retained_metrics_object: false,
2201 access: vec![PUBLIC_SELECT],
2202 ontology: Some(Ontology {
2203 entity_name: "storage_usage_by_shard",
2204 description: "Storage usage broken down by shard",
2205 links: &const { [] },
2206 column_semantic_types: &const {
2207 [
2208 ("shard_id", SemanticType::ShardId),
2209 ("size_bytes", SemanticType::ByteCount),
2210 ("collection_timestamp", SemanticType::WallclockTimestamp),
2211 ]
2212 },
2213 }),
2214});
2215
2216pub static MZ_AWS_CONNECTIONS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2217 name: "mz_aws_connections",
2218 schema: MZ_INTERNAL_SCHEMA,
2219 oid: oid::TABLE_MZ_AWS_CONNECTIONS_OID,
2220 desc: RelationDesc::builder()
2221 .with_column("id", SqlScalarType::String.nullable(false))
2222 .with_column("endpoint", SqlScalarType::String.nullable(true))
2223 .with_column("region", SqlScalarType::String.nullable(true))
2224 .with_column("access_key_id", SqlScalarType::String.nullable(true))
2225 .with_column(
2226 "access_key_id_secret_id",
2227 SqlScalarType::String.nullable(true),
2228 )
2229 .with_column(
2230 "secret_access_key_secret_id",
2231 SqlScalarType::String.nullable(true),
2232 )
2233 .with_column("session_token", SqlScalarType::String.nullable(true))
2234 .with_column(
2235 "session_token_secret_id",
2236 SqlScalarType::String.nullable(true),
2237 )
2238 .with_column("assume_role_arn", SqlScalarType::String.nullable(true))
2239 .with_column(
2240 "assume_role_session_name",
2241 SqlScalarType::String.nullable(true),
2242 )
2243 .with_column("principal", SqlScalarType::String.nullable(true))
2244 .with_column("external_id", SqlScalarType::String.nullable(true))
2245 .with_column("example_trust_policy", SqlScalarType::Jsonb.nullable(true))
2246 .finish(),
2247 column_comments: BTreeMap::from_iter([
2248 ("id", "The ID of the connection."),
2249 ("endpoint", "The value of the `ENDPOINT` option, if set."),
2250 ("region", "The value of the `REGION` option, if set."),
2251 (
2252 "access_key_id",
2253 "The value of the `ACCESS KEY ID` option, if provided in line.",
2254 ),
2255 (
2256 "access_key_id_secret_id",
2257 "The ID of the secret referenced by the `ACCESS KEY ID` option, if provided via a secret.",
2258 ),
2259 (
2260 "secret_access_key_secret_id",
2261 "The ID of the secret referenced by the `SECRET ACCESS KEY` option, if set.",
2262 ),
2263 (
2264 "session_token",
2265 "The value of the `SESSION TOKEN` option, if provided in line.",
2266 ),
2267 (
2268 "session_token_secret_id",
2269 "The ID of the secret referenced by the `SESSION TOKEN` option, if provided via a secret.",
2270 ),
2271 (
2272 "assume_role_arn",
2273 "The value of the `ASSUME ROLE ARN` option, if set.",
2274 ),
2275 (
2276 "assume_role_session_name",
2277 "The value of the `ASSUME ROLE SESSION NAME` option, if set.",
2278 ),
2279 (
2280 "principal",
2281 "The ARN of the AWS principal Materialize will use when assuming the provided role, if the connection is configured to use role assumption.",
2282 ),
2283 (
2284 "external_id",
2285 "The external ID Materialize will use when assuming the provided role, if the connection is configured to use role assumption.",
2286 ),
2287 (
2288 "example_trust_policy",
2289 "An example of an IAM role trust policy that allows this connection's principal and external ID to assume the role.",
2290 ),
2291 ]),
2292 is_retained_metrics_object: false,
2293 access: vec![PUBLIC_SELECT],
2294 ontology: Some(Ontology {
2295 entity_name: "aws_connection",
2296 description: "AWS connection configuration details",
2297 links: &const {
2298 [OntologyLink {
2299 name: "details_of",
2300 target: "connection",
2301 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
2302 }]
2303 },
2304 column_semantic_types: &[],
2305 }),
2306});
2307
2308pub static MZ_CLUSTER_REPLICA_METRICS_HISTORY: LazyLock<BuiltinSource> =
2309 LazyLock::new(|| BuiltinSource {
2310 name: "mz_cluster_replica_metrics_history",
2311 schema: MZ_INTERNAL_SCHEMA,
2312 oid: oid::SOURCE_MZ_CLUSTER_REPLICA_METRICS_HISTORY_OID,
2313 data_source: IntrospectionType::ReplicaMetricsHistory.into(),
2314 desc: REPLICA_METRICS_HISTORY_DESC.clone(),
2315 column_comments: BTreeMap::from_iter([
2316 ("replica_id", "The ID of a cluster replica."),
2317 ("process_id", "The ID of a process within the replica."),
2318 (
2319 "cpu_nano_cores",
2320 "Approximate CPU usage, in billionths of a vCPU core.",
2321 ),
2322 ("memory_bytes", "Approximate memory usage, in bytes."),
2323 ("disk_bytes", "Approximate disk usage, in bytes."),
2324 (
2325 "occurred_at",
2326 "Wall-clock timestamp at which the event occurred.",
2327 ),
2328 (
2329 "heap_bytes",
2330 "Approximate heap (RAM + swap) usage, in bytes.",
2331 ),
2332 ("heap_limit", "Available heap (RAM + swap) space, in bytes."),
2333 ]),
2334 is_retained_metrics_object: false,
2335 access: vec![PUBLIC_SELECT],
2336 ontology: None,
2337 });
2338
2339pub static MZ_CLUSTER_REPLICA_METRICS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2340 name: "mz_cluster_replica_metrics",
2341 schema: MZ_INTERNAL_SCHEMA,
2342 oid: oid::VIEW_MZ_CLUSTER_REPLICA_METRICS_OID,
2343 desc: RelationDesc::builder()
2344 .with_column("replica_id", SqlScalarType::String.nullable(false))
2345 .with_column("process_id", SqlScalarType::UInt64.nullable(false))
2346 .with_column("cpu_nano_cores", SqlScalarType::UInt64.nullable(true))
2347 .with_column("memory_bytes", SqlScalarType::UInt64.nullable(true))
2348 .with_column("disk_bytes", SqlScalarType::UInt64.nullable(true))
2349 .with_column("heap_bytes", SqlScalarType::UInt64.nullable(true))
2350 .with_column("heap_limit", SqlScalarType::UInt64.nullable(true))
2351 .with_key(vec![0, 1])
2352 .finish(),
2353 column_comments: BTreeMap::from_iter([
2354 ("replica_id", "The ID of a cluster replica."),
2355 ("process_id", "The ID of a process within the replica."),
2356 (
2357 "cpu_nano_cores",
2358 "Approximate CPU usage, in billionths of a vCPU core.",
2359 ),
2360 ("memory_bytes", "Approximate RAM usage, in bytes."),
2361 ("disk_bytes", "Approximate disk usage, in bytes."),
2362 (
2363 "heap_bytes",
2364 "Approximate heap (RAM + swap) usage, in bytes.",
2365 ),
2366 ("heap_limit", "Available heap (RAM + swap) space, in bytes."),
2367 ]),
2368 sql: "
2369SELECT
2370 DISTINCT ON (replica_id, process_id)
2371 replica_id,
2372 process_id,
2373 cpu_nano_cores,
2374 memory_bytes,
2375 disk_bytes,
2376 heap_bytes,
2377 heap_limit
2378FROM mz_internal.mz_cluster_replica_metrics_history
2379JOIN mz_cluster_replicas r ON r.id = replica_id
2380ORDER BY replica_id, process_id, occurred_at DESC",
2381 access: vec![PUBLIC_SELECT],
2382 ontology: Some(Ontology {
2383 entity_name: "replica_metrics",
2384 description: "CPU and memory metrics per replica",
2385 links: &const {
2386 [OntologyLink {
2387 name: "metrics_of_replica",
2388 target: "replica",
2389 properties: LinkProperties::fk_typed(
2390 "replica_id",
2391 "id",
2392 Cardinality::OneToOne,
2393 mz_repr::SemanticType::CatalogItemId,
2394 ),
2395 }]
2396 },
2397 column_semantic_types: &const {
2398 [
2399 ("replica_id", SemanticType::ReplicaId),
2400 ("memory_bytes", SemanticType::ByteCount),
2401 ("disk_bytes", SemanticType::ByteCount),
2402 ("heap_bytes", SemanticType::ByteCount),
2403 ("heap_limit", SemanticType::ByteCount),
2404 ]
2405 },
2406 }),
2407});
2408
2409pub static MZ_FRONTIERS: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
2410 name: "mz_frontiers",
2411 schema: MZ_INTERNAL_SCHEMA,
2412 oid: oid::SOURCE_MZ_FRONTIERS_OID,
2413 data_source: IntrospectionType::Frontiers.into(),
2414 desc: RelationDesc::builder()
2415 .with_column("object_id", SqlScalarType::String.nullable(false))
2416 .with_column("read_frontier", SqlScalarType::MzTimestamp.nullable(true))
2417 .with_column("write_frontier", SqlScalarType::MzTimestamp.nullable(true))
2418 .finish(),
2419 column_comments: BTreeMap::from_iter([
2420 (
2421 "object_id",
2422 "The ID of the source, sink, table, index, materialized view, or subscription.",
2423 ),
2424 (
2425 "read_frontier",
2426 "The earliest timestamp at which the output is still readable.",
2427 ),
2428 (
2429 "write_frontier",
2430 "The next timestamp at which the output may change.",
2431 ),
2432 ]),
2433 is_retained_metrics_object: false,
2434 access: vec![PUBLIC_SELECT],
2435 ontology: Some(Ontology {
2436 entity_name: "frontier",
2437 description: "Current read/write frontiers for sources, sinks, tables, materialized views, indexes, and subscriptions",
2438 links: &const {
2439 [OntologyLink {
2440 name: "frontier_of",
2441 target: "object",
2442 properties: LinkProperties::fk_mapped(
2443 "object_id",
2444 "id",
2445 Cardinality::ManyToOne,
2446 mz_repr::SemanticType::GlobalId,
2447 "mz_internal.mz_object_global_ids",
2448 ),
2449 }]
2450 },
2451 column_semantic_types: &const {
2452 [
2453 ("object_id", SemanticType::GlobalId),
2454 ("read_frontier", SemanticType::MzTimestamp),
2455 ("write_frontier", SemanticType::MzTimestamp),
2456 ]
2457 },
2458 }),
2459});
2460
2461pub static MZ_GLOBAL_FRONTIERS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2463 name: "mz_global_frontiers",
2464 schema: MZ_INTERNAL_SCHEMA,
2465 oid: oid::VIEW_MZ_GLOBAL_FRONTIERS_OID,
2466 desc: RelationDesc::builder()
2467 .with_column("object_id", SqlScalarType::String.nullable(false))
2468 .with_column("time", SqlScalarType::MzTimestamp.nullable(false))
2469 .finish(),
2470 column_comments: BTreeMap::new(),
2471 sql: "
2472SELECT object_id, write_frontier AS time
2473FROM mz_internal.mz_frontiers
2474WHERE write_frontier IS NOT NULL",
2475 access: vec![PUBLIC_SELECT],
2476 ontology: None,
2477});
2478
2479pub static MZ_WALLCLOCK_LAG_HISTORY: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
2480 name: "mz_wallclock_lag_history",
2481 schema: MZ_INTERNAL_SCHEMA,
2482 oid: oid::SOURCE_MZ_WALLCLOCK_LAG_HISTORY_OID,
2483 desc: WALLCLOCK_LAG_HISTORY_DESC.clone(),
2484 data_source: IntrospectionType::WallclockLagHistory.into(),
2485 column_comments: BTreeMap::from_iter([
2486 (
2487 "object_id",
2488 "The ID of the table, source, materialized view, index, or sink. Corresponds to `mz_objects.id`.",
2489 ),
2490 (
2491 "replica_id",
2492 "The ID of a replica computing the object, or `NULL` for persistent objects. Corresponds to `mz_cluster_replicas.id`.",
2493 ),
2494 (
2495 "lag",
2496 "The amount of time the object's write frontier lags behind wallclock time.",
2497 ),
2498 (
2499 "occurred_at",
2500 "Wall-clock timestamp at which the event occurred.",
2501 ),
2502 ]),
2503 is_retained_metrics_object: false,
2504 access: vec![PUBLIC_SELECT],
2505 ontology: Some(Ontology {
2506 entity_name: "wallclock_lag_event",
2507 description: "Historical wallclock lag per object",
2508 links: &const {
2509 [
2510 OntologyLink {
2511 name: "measures_lag_of",
2512 target: "object",
2513 properties: LinkProperties::measures_mapped(
2514 "object_id",
2515 "id",
2516 "wallclock_lag",
2517 mz_repr::SemanticType::GlobalId,
2518 "mz_internal.mz_object_global_ids",
2519 ),
2520 },
2521 OntologyLink {
2522 name: "on_replica",
2523 target: "replica",
2524 properties: LinkProperties::fk_nullable(
2525 "replica_id",
2526 "id",
2527 Cardinality::ManyToOne,
2528 ),
2529 },
2530 ]
2531 },
2532 column_semantic_types: &const {
2533 [
2534 ("object_id", SemanticType::GlobalId),
2535 ("replica_id", SemanticType::ReplicaId),
2536 ("occurred_at", SemanticType::WallclockTimestamp),
2537 ]
2538 },
2539 }),
2540});
2541
2542pub static MZ_WALLCLOCK_GLOBAL_LAG_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2543 name: "mz_wallclock_global_lag_history",
2544 schema: MZ_INTERNAL_SCHEMA,
2545 oid: oid::VIEW_MZ_WALLCLOCK_GLOBAL_LAG_HISTORY_OID,
2546 desc: RelationDesc::builder()
2547 .with_column("object_id", SqlScalarType::String.nullable(false))
2548 .with_column("lag", SqlScalarType::Interval.nullable(true))
2549 .with_column(
2550 "occurred_at",
2551 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2552 )
2553 .with_key(vec![0, 2])
2554 .finish(),
2555 column_comments: BTreeMap::from_iter([
2556 (
2557 "object_id",
2558 "The ID of the table, source, materialized view, index, or sink. Corresponds to `mz_objects.id`.",
2559 ),
2560 (
2561 "lag",
2562 "The minimum wallclock lag observed for the object during the minute.",
2563 ),
2564 (
2565 "occurred_at",
2566 "The minute-aligned timestamp of the observation.",
2567 ),
2568 ]),
2569 sql: "
2570WITH times_binned AS (
2571 SELECT
2572 object_id,
2573 lag,
2574 date_trunc('minute', occurred_at) AS occurred_at
2575 FROM mz_internal.mz_wallclock_lag_history
2576)
2577SELECT
2578 object_id,
2579 min(lag) AS lag,
2580 occurred_at
2581FROM times_binned
2582GROUP BY object_id, occurred_at
2583OPTIONS (AGGREGATE INPUT GROUP SIZE = 1)",
2584 access: vec![PUBLIC_SELECT],
2585 ontology: Some(Ontology {
2586 entity_name: "wallclock_global_lag_event",
2587 description: "Historical global wallclock lag",
2588 links: &const {
2589 [OntologyLink {
2590 name: "lag_of",
2591 target: "object_global_id",
2592 properties: LinkProperties::fk("object_id", "global_id", Cardinality::ManyToOne),
2593 }]
2594 },
2595 column_semantic_types: &const {
2596 [
2597 ("object_id", SemanticType::GlobalId),
2598 ("occurred_at", SemanticType::WallclockTimestamp),
2599 ]
2600 },
2601 }),
2602});
2603
2604pub static MZ_WALLCLOCK_GLOBAL_LAG_RECENT_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| {
2605 BuiltinView {
2606 name: "mz_wallclock_global_lag_recent_history",
2607 schema: MZ_INTERNAL_SCHEMA,
2608 oid: oid::VIEW_MZ_WALLCLOCK_GLOBAL_LAG_RECENT_HISTORY_OID,
2609 desc: RelationDesc::builder()
2610 .with_column("object_id", SqlScalarType::String.nullable(false))
2611 .with_column("lag", SqlScalarType::Interval.nullable(true))
2612 .with_column(
2613 "occurred_at",
2614 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2615 )
2616 .with_key(vec![0, 2])
2617 .finish(),
2618 column_comments: BTreeMap::from_iter([
2619 (
2620 "object_id",
2621 "The ID of the table, source, materialized view, index, or sink. Corresponds to `mz_objects.id`.",
2622 ),
2623 (
2624 "lag",
2625 "The minimum wallclock lag observed for the object during the minute.",
2626 ),
2627 (
2628 "occurred_at",
2629 "The minute-aligned timestamp of the observation.",
2630 ),
2631 ]),
2632 sql: "
2633SELECT object_id, lag, occurred_at
2634FROM mz_internal.mz_wallclock_global_lag_history
2635WHERE occurred_at + '1 day' > mz_now()",
2636 access: vec![PUBLIC_SELECT],
2637 ontology: None,
2638 }
2639});
2640
2641pub static MZ_WALLCLOCK_GLOBAL_LAG: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2642 name: "mz_wallclock_global_lag",
2643 schema: MZ_INTERNAL_SCHEMA,
2644 oid: oid::VIEW_MZ_WALLCLOCK_GLOBAL_LAG_OID,
2645 desc: RelationDesc::builder()
2646 .with_column("object_id", SqlScalarType::String.nullable(false))
2647 .with_column("lag", SqlScalarType::Interval.nullable(true))
2648 .with_key(vec![0])
2649 .finish(),
2650 column_comments: BTreeMap::from_iter([
2651 (
2652 "object_id",
2653 "The ID of the table, source, materialized view, index, or sink. Corresponds to `mz_objects.id`.",
2654 ),
2655 (
2656 "lag",
2657 "The amount of time the object's write frontier lags behind wallclock time.",
2658 ),
2659 ]),
2660 sql: "
2661SELECT DISTINCT ON (object_id) object_id, lag
2662FROM mz_internal.mz_wallclock_global_lag_recent_history
2663WHERE occurred_at + '5 minutes' > mz_now()
2664ORDER BY object_id, occurred_at DESC",
2665 access: vec![PUBLIC_SELECT],
2666 ontology: Some(Ontology {
2667 entity_name: "wallclock_global_lag",
2668 description: "Current wallclock lag aggregated across replicas",
2669 links: &const {
2670 [OntologyLink {
2671 name: "measures_global_lag_of",
2672 target: "object",
2673 properties: LinkProperties::measures_mapped(
2674 "object_id",
2675 "id",
2676 "wallclock_lag_global",
2677 mz_repr::SemanticType::GlobalId,
2678 "mz_internal.mz_object_global_ids",
2679 ),
2680 }]
2681 },
2682 column_semantic_types: &[("object_id", SemanticType::GlobalId)],
2683 }),
2684});
2685
2686pub static MZ_WALLCLOCK_GLOBAL_LAG_HISTOGRAM_RAW: LazyLock<BuiltinSource> =
2687 LazyLock::new(|| BuiltinSource {
2688 name: "mz_wallclock_global_lag_histogram_raw",
2689 schema: MZ_INTERNAL_SCHEMA,
2690 oid: oid::SOURCE_MZ_WALLCLOCK_GLOBAL_LAG_HISTOGRAM_RAW_OID,
2691 desc: WALLCLOCK_GLOBAL_LAG_HISTOGRAM_RAW_DESC.clone(),
2692 column_comments: BTreeMap::new(),
2693 data_source: IntrospectionType::WallclockLagHistogram.into(),
2694 is_retained_metrics_object: false,
2695 access: vec![PUBLIC_SELECT],
2696 ontology: None,
2697 });
2698
2699pub static MZ_WALLCLOCK_GLOBAL_LAG_HISTOGRAM: LazyLock<BuiltinView> =
2700 LazyLock::new(|| BuiltinView {
2701 name: "mz_wallclock_global_lag_histogram",
2702 schema: MZ_INTERNAL_SCHEMA,
2703 oid: oid::VIEW_MZ_WALLCLOCK_GLOBAL_LAG_HISTOGRAM_OID,
2704 desc: RelationDesc::builder()
2705 .with_column(
2706 "period_start",
2707 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2708 )
2709 .with_column(
2710 "period_end",
2711 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2712 )
2713 .with_column("object_id", SqlScalarType::String.nullable(false))
2714 .with_column("lag_seconds", SqlScalarType::UInt64.nullable(true))
2715 .with_column("labels", SqlScalarType::Jsonb.nullable(false))
2716 .with_column("count", SqlScalarType::Int64.nullable(false))
2717 .with_key(vec![0, 1, 2, 3, 4])
2718 .finish(),
2719 column_comments: BTreeMap::new(),
2720 sql: "
2721SELECT *, count(*) AS count
2722FROM mz_internal.mz_wallclock_global_lag_histogram_raw
2723GROUP BY period_start, period_end, object_id, lag_seconds, labels",
2724 access: vec![PUBLIC_SELECT],
2725 ontology: None,
2726 });
2727
2728pub static MZ_MATERIALIZED_VIEW_REFRESHES: LazyLock<BuiltinSource> = LazyLock::new(|| {
2729 BuiltinSource {
2730 name: "mz_materialized_view_refreshes",
2731 schema: MZ_INTERNAL_SCHEMA,
2732 oid: oid::SOURCE_MZ_MATERIALIZED_VIEW_REFRESHES_OID,
2733 data_source: DataSourceDesc::Introspection(
2734 IntrospectionType::ComputeMaterializedViewRefreshes,
2735 ),
2736 desc: RelationDesc::builder()
2737 .with_column(
2738 "materialized_view_id",
2739 SqlScalarType::String.nullable(false),
2740 )
2741 .with_column(
2742 "last_completed_refresh",
2743 SqlScalarType::MzTimestamp.nullable(true),
2744 )
2745 .with_column("next_refresh", SqlScalarType::MzTimestamp.nullable(true))
2746 .finish(),
2747 column_comments: BTreeMap::from_iter([
2748 (
2749 "materialized_view_id",
2750 "The ID of the materialized view. Corresponds to `mz_catalog.mz_materialized_views.id`",
2751 ),
2752 (
2753 "last_completed_refresh",
2754 "The time of the last successfully completed refresh. `NULL` if the materialized view hasn't completed any refreshes yet.",
2755 ),
2756 (
2757 "next_refresh",
2758 "The time of the next scheduled refresh. `NULL` if the materialized view has no future scheduled refreshes.",
2759 ),
2760 ]),
2761 is_retained_metrics_object: false,
2762 access: vec![PUBLIC_SELECT],
2763 ontology: None,
2764 }
2765});
2766
2767pub static MZ_SUBSCRIPTIONS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2768 name: "mz_subscriptions",
2769 schema: MZ_INTERNAL_SCHEMA,
2770 oid: oid::TABLE_MZ_SUBSCRIPTIONS_OID,
2771 desc: RelationDesc::builder()
2772 .with_column("id", SqlScalarType::String.nullable(false))
2773 .with_column("session_id", SqlScalarType::Uuid.nullable(false))
2774 .with_column("cluster_id", SqlScalarType::String.nullable(false))
2775 .with_column(
2776 "created_at",
2777 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2778 )
2779 .with_column(
2780 "referenced_object_ids",
2781 SqlScalarType::List {
2782 element_type: Box::new(SqlScalarType::String),
2783 custom_id: None,
2784 }
2785 .nullable(false),
2786 )
2787 .finish(),
2788 column_comments: BTreeMap::from_iter([
2789 ("id", "The ID of the subscription."),
2790 (
2791 "session_id",
2792 "The ID of the session that runs the subscription. Corresponds to `mz_sessions.id`.",
2793 ),
2794 (
2795 "cluster_id",
2796 "The ID of the cluster on which the subscription is running. Corresponds to `mz_clusters.id`.",
2797 ),
2798 (
2799 "created_at",
2800 "The time at which the subscription was created.",
2801 ),
2802 (
2803 "referenced_object_ids",
2804 "The IDs of objects referenced by the subscription. Corresponds to `mz_objects.id`",
2805 ),
2806 ]),
2807 is_retained_metrics_object: false,
2808 access: vec![PUBLIC_SELECT],
2809 ontology: Some(Ontology {
2810 entity_name: "subscription",
2811 description: "Active SUBSCRIBE operations",
2812 links: &const {
2813 [
2814 OntologyLink {
2815 name: "uses_session",
2816 target: "session",
2817 properties: LinkProperties::fk("session_id", "id", Cardinality::ManyToOne),
2818 },
2819 OntologyLink {
2820 name: "in_active_session",
2821 target: "active_session",
2822 properties: LinkProperties::fk_nullable(
2823 "session_id",
2824 "id",
2825 Cardinality::ManyToOne,
2826 ),
2827 },
2828 OntologyLink {
2829 name: "belongs_to_cluster",
2830 target: "cluster",
2831 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
2832 },
2833 ]
2834 },
2835 column_semantic_types: &const {
2836 [
2837 ("id", SemanticType::CatalogItemId),
2838 ("cluster_id", SemanticType::ClusterId),
2839 ]
2840 },
2841 }),
2842});
2843
2844pub static MZ_SESSIONS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2845 name: "mz_sessions",
2846 schema: MZ_INTERNAL_SCHEMA,
2847 oid: oid::TABLE_MZ_SESSIONS_OID,
2848 desc: RelationDesc::builder()
2849 .with_column("id", SqlScalarType::Uuid.nullable(false))
2850 .with_column("connection_id", SqlScalarType::UInt32.nullable(false))
2851 .with_column("role_id", SqlScalarType::String.nullable(false))
2852 .with_column("client_ip", SqlScalarType::String.nullable(true))
2853 .with_column(
2854 "connected_at",
2855 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2856 )
2857 .finish(),
2858 column_comments: BTreeMap::from_iter([
2859 ("id", "The globally unique ID of the session."),
2860 (
2861 "connection_id",
2862 "The connection ID of the session. Unique only for active sessions and can be recycled. Corresponds to `pg_backend_pid()`.",
2863 ),
2864 (
2865 "role_id",
2866 "The role ID of the role that the session is logged in as. Corresponds to `mz_catalog.mz_roles`.",
2867 ),
2868 (
2869 "client_ip",
2870 "The IP address of the client that initiated the session.",
2871 ),
2872 (
2873 "connected_at",
2874 "The time at which the session connected to the system.",
2875 ),
2876 ]),
2877 is_retained_metrics_object: false,
2878 access: vec![PUBLIC_SELECT],
2879 ontology: Some(Ontology {
2880 entity_name: "active_session",
2881 description: "Currently active sessions",
2882 links: &const {
2883 [OntologyLink {
2884 name: "logged_in_as",
2885 target: "role",
2886 properties: LinkProperties::fk("role_id", "id", Cardinality::ManyToOne),
2887 }]
2888 },
2889 column_semantic_types: &[("role_id", SemanticType::RoleId)],
2890 }),
2891});
2892
2893pub static MZ_OVERRIDDEN_SYSTEM_PARAMETERS: LazyLock<BuiltinMaterializedView> =
2894 LazyLock::new(|| BuiltinMaterializedView {
2895 name: "mz_overridden_system_parameters",
2896 schema: MZ_INTERNAL_SCHEMA,
2897 oid: oid::MV_MZ_OVERRIDDEN_SYSTEM_PARAMETERS_OID,
2898 desc: RelationDesc::builder()
2899 .with_column("name", SqlScalarType::String.nullable(false))
2900 .with_column("value", SqlScalarType::String.nullable(false))
2901 .finish(),
2902 column_comments: BTreeMap::from_iter([
2903 ("name", "The name of the system parameter."),
2904 (
2905 "value",
2906 "The environment-wide value of the system parameter.",
2907 ),
2908 ]),
2909 sql: "
2916IN CLUSTER mz_catalog_server
2917WITH (
2918 ASSERT NOT NULL name,
2919 ASSERT NOT NULL value
2920) AS
2921SELECT
2922 data->'key'->>'name' AS name,
2923 data->'value'->>'value' AS value
2924FROM mz_internal.mz_catalog_raw
2925WHERE data->>'kind' = 'ServerConfiguration'",
2926 is_retained_metrics_object: false,
2927 access: vec![PUBLIC_SELECT],
2928 ontology: Some(Ontology {
2929 entity_name: "system_parameter",
2930 description: "Environment-wide system parameter overrides",
2931 links: &const { [] },
2932 column_semantic_types: &[],
2933 }),
2934 });
2935
2936pub static MZ_CLUSTER_SYSTEM_PARAMETERS: LazyLock<BuiltinMaterializedView> =
2937 LazyLock::new(|| BuiltinMaterializedView {
2938 name: "mz_cluster_system_parameters",
2939 schema: MZ_INTERNAL_SCHEMA,
2940 oid: oid::MV_MZ_CLUSTER_SYSTEM_PARAMETERS_OID,
2941 desc: RelationDesc::builder()
2942 .with_column("cluster_id", SqlScalarType::String.nullable(false))
2943 .with_column("name", SqlScalarType::String.nullable(false))
2944 .with_column("value", SqlScalarType::String.nullable(false))
2945 .finish(),
2946 column_comments: BTreeMap::from_iter([
2947 (
2948 "cluster_id",
2949 "The ID of the cluster. Corresponds to `mz_clusters.id`.",
2950 ),
2951 ("name", "The name of the cluster-coherent system parameter."),
2952 ("value", "The cluster-scoped value of the system parameter."),
2953 ]),
2954 sql: "
2958IN CLUSTER mz_catalog_server
2959WITH (
2960 ASSERT NOT NULL cluster_id,
2961 ASSERT NOT NULL name,
2962 ASSERT NOT NULL value
2963) AS
2964SELECT
2965 mz_internal.parse_catalog_id(data->'key'->'cluster_id') AS cluster_id,
2966 data->'key'->>'name' AS name,
2967 data->'value'->>'value' AS value
2968FROM mz_internal.mz_catalog_raw
2969WHERE data->>'kind' = 'ClusterSystemConfiguration'",
2970 is_retained_metrics_object: false,
2971 access: vec![PUBLIC_SELECT],
2972 ontology: Some(Ontology {
2973 entity_name: "cluster_system_parameter",
2974 description: "Cluster-coherent system parameter overrides",
2975 links: &const {
2976 [OntologyLink {
2977 name: "scoped_to_cluster",
2978 target: "cluster",
2979 properties: LinkProperties::fk_typed(
2980 "cluster_id",
2981 "id",
2982 Cardinality::ManyToOne,
2983 mz_repr::SemanticType::ClusterId,
2984 ),
2985 }]
2986 },
2987 column_semantic_types: &[("cluster_id", SemanticType::ClusterId)],
2988 }),
2989 });
2990
2991pub static MZ_REPLICA_SYSTEM_PARAMETERS: LazyLock<BuiltinMaterializedView> =
2992 LazyLock::new(|| BuiltinMaterializedView {
2993 name: "mz_replica_system_parameters",
2994 schema: MZ_INTERNAL_SCHEMA,
2995 oid: oid::MV_MZ_REPLICA_SYSTEM_PARAMETERS_OID,
2996 desc: RelationDesc::builder()
2997 .with_column("replica_id", SqlScalarType::String.nullable(false))
2998 .with_column("name", SqlScalarType::String.nullable(false))
2999 .with_column("value", SqlScalarType::String.nullable(false))
3000 .finish(),
3001 column_comments: BTreeMap::from_iter([
3002 (
3003 "replica_id",
3004 "The ID of the cluster replica. Corresponds to `mz_cluster_replicas.id`.",
3005 ),
3006 ("name", "The name of the replica-local system parameter."),
3007 ("value", "The replica-scoped value of the system parameter."),
3008 ]),
3009 sql: "
3013IN CLUSTER mz_catalog_server
3014WITH (
3015 ASSERT NOT NULL replica_id,
3016 ASSERT NOT NULL name,
3017 ASSERT NOT NULL value
3018) AS
3019SELECT
3020 mz_internal.parse_catalog_id(data->'key'->'replica_id') AS replica_id,
3021 data->'key'->>'name' AS name,
3022 data->'value'->>'value' AS value
3023FROM mz_internal.mz_catalog_raw
3024WHERE data->>'kind' = 'ReplicaSystemConfiguration'",
3025 is_retained_metrics_object: false,
3026 access: vec![PUBLIC_SELECT],
3027 ontology: Some(Ontology {
3028 entity_name: "replica_system_parameter",
3029 description: "Replica-local system parameter overrides",
3030 links: &const {
3031 [OntologyLink {
3032 name: "scoped_to_replica",
3033 target: "replica",
3034 properties: LinkProperties::fk_typed(
3035 "replica_id",
3036 "id",
3037 Cardinality::ManyToOne,
3038 mz_repr::SemanticType::ReplicaId,
3039 ),
3040 }]
3041 },
3042 column_semantic_types: &[("replica_id", SemanticType::ReplicaId)],
3043 }),
3044 });
3045
3046pub static MZ_COMMENTS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
3047 BuiltinMaterializedView {
3048 name: "mz_comments",
3049 schema: MZ_INTERNAL_SCHEMA,
3050 oid: oid::MV_MZ_COMMENTS_OID,
3051 desc: RelationDesc::builder()
3052 .with_column("id", SqlScalarType::String.nullable(false))
3053 .with_column("object_type", SqlScalarType::String.nullable(false))
3054 .with_column("object_sub_id", SqlScalarType::Int32.nullable(true))
3055 .with_column("comment", SqlScalarType::String.nullable(false))
3056 .finish(),
3057 column_comments: BTreeMap::from_iter([
3058 (
3059 "id",
3060 "The ID of the object. Corresponds to `mz_objects.id`.",
3061 ),
3062 (
3063 "object_type",
3064 "The type of object the comment is associated with.",
3065 ),
3066 (
3067 "object_sub_id",
3068 "For a comment on a column of a relation, the column number. `NULL` for other object types.",
3069 ),
3070 ("comment", "The comment itself."),
3071 ]),
3072 sql: "
3085IN CLUSTER mz_catalog_server
3086WITH (
3087 ASSERT NOT NULL id,
3088 ASSERT NOT NULL object_type,
3089 ASSERT NOT NULL comment
3090) AS
3091WITH commented AS (
3092 SELECT data->'key'->'object' AS obj,
3093 data->'key'->'sub_component' AS sub,
3094 data->'value'->>'comment' AS comment
3095 FROM mz_internal.mz_catalog_raw
3096 WHERE data->>'kind' = 'Comment'
3097)
3098SELECT
3099 CASE
3100 WHEN obj ? 'Table' THEN mz_internal.parse_catalog_id(obj->'Table')
3101 WHEN obj ? 'View' THEN mz_internal.parse_catalog_id(obj->'View')
3102 WHEN obj ? 'MaterializedView' THEN mz_internal.parse_catalog_id(obj->'MaterializedView')
3103 WHEN obj ? 'Source' THEN mz_internal.parse_catalog_id(obj->'Source')
3104 WHEN obj ? 'Sink' THEN mz_internal.parse_catalog_id(obj->'Sink')
3105 WHEN obj ? 'Index' THEN mz_internal.parse_catalog_id(obj->'Index')
3106 WHEN obj ? 'Func' THEN mz_internal.parse_catalog_id(obj->'Func')
3107 WHEN obj ? 'Connection' THEN mz_internal.parse_catalog_id(obj->'Connection')
3108 WHEN obj ? 'Type' THEN mz_internal.parse_catalog_id(obj->'Type')
3109 WHEN obj ? 'Secret' THEN mz_internal.parse_catalog_id(obj->'Secret')
3110 WHEN obj ? 'Role' THEN mz_internal.parse_catalog_id(obj->'Role')
3111 WHEN obj ? 'Database' THEN mz_internal.parse_catalog_id(obj->'Database')
3112 WHEN obj ? 'Schema' THEN mz_internal.parse_catalog_id(obj->'Schema'->'schema'->'Id')
3113 WHEN obj ? 'Cluster' THEN mz_internal.parse_catalog_id(obj->'Cluster')
3114 WHEN obj ? 'ClusterReplica' THEN mz_internal.parse_catalog_id(obj->'ClusterReplica'->'replica_id')
3115 WHEN obj ? 'NetworkPolicy' THEN mz_internal.parse_catalog_id(obj->'NetworkPolicy')
3116 END AS id,
3117 CASE
3118 WHEN obj ? 'Table' THEN 'table'
3119 WHEN obj ? 'View' THEN 'view'
3120 WHEN obj ? 'MaterializedView' THEN 'materialized-view'
3121 WHEN obj ? 'Source' THEN 'source'
3122 WHEN obj ? 'Sink' THEN 'sink'
3123 WHEN obj ? 'Index' THEN 'index'
3124 WHEN obj ? 'Func' THEN 'func'
3125 WHEN obj ? 'Connection' THEN 'connection'
3126 WHEN obj ? 'Type' THEN 'type'
3127 WHEN obj ? 'Secret' THEN 'secret'
3128 WHEN obj ? 'Role' THEN 'role'
3129 WHEN obj ? 'Database' THEN 'database'
3130 WHEN obj ? 'Schema' THEN 'schema'
3131 WHEN obj ? 'Cluster' THEN 'cluster'
3132 WHEN obj ? 'ClusterReplica' THEN 'cluster-replica'
3133 WHEN obj ? 'NetworkPolicy' THEN 'network-policy'
3134 END AS object_type,
3135 (sub->'ColumnPos')::int4 AS object_sub_id,
3136 comment
3137FROM commented",
3138 is_retained_metrics_object: false,
3139 access: vec![PUBLIC_SELECT],
3140 ontology: Some(Ontology {
3141 entity_name: "comment",
3142 description: "A COMMENT ON annotation for a catalog object or column",
3143 links: &const {
3144 [OntologyLink {
3145 name: "comment_on",
3146 target: "object",
3147 properties: LinkProperties::fk_typed(
3148 "id",
3149 "id",
3150 Cardinality::ManyToOne,
3151 mz_repr::SemanticType::CatalogItemId,
3152 ),
3153 }]
3154 },
3155 column_semantic_types: &const {
3156 [
3157 ("id", SemanticType::CatalogItemId),
3158 ("object_type", SemanticType::ObjectType),
3159 ]
3160 },
3161 }),
3162 }
3163});
3164
3165pub static MZ_SOURCE_REFERENCES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3166 name: "mz_source_references",
3167 schema: MZ_INTERNAL_SCHEMA,
3168 oid: oid::TABLE_MZ_SOURCE_REFERENCES_OID,
3169 desc: RelationDesc::builder()
3170 .with_column("source_id", SqlScalarType::String.nullable(false))
3171 .with_column("namespace", SqlScalarType::String.nullable(true))
3172 .with_column("name", SqlScalarType::String.nullable(false))
3173 .with_column(
3174 "updated_at",
3175 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3176 )
3177 .with_column(
3178 "columns",
3179 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(true),
3180 )
3181 .finish(),
3182 column_comments: BTreeMap::new(),
3183 is_retained_metrics_object: false,
3184 access: vec![PUBLIC_SELECT],
3185 ontology: Some(Ontology {
3186 entity_name: "source_reference",
3187 description: "External references tracked by sources",
3188 links: &const {
3189 [OntologyLink {
3190 name: "references_source",
3191 target: "source",
3192 properties: LinkProperties::fk("source_id", "id", Cardinality::ManyToOne),
3193 }]
3194 },
3195 column_semantic_types: &[("source_id", SemanticType::CatalogItemId)],
3196 }),
3197});
3198
3199pub static MZ_WEBHOOKS_SOURCES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3200 name: "mz_webhook_sources",
3201 schema: MZ_INTERNAL_SCHEMA,
3202 oid: oid::TABLE_MZ_WEBHOOK_SOURCES_OID,
3203 desc: RelationDesc::builder()
3204 .with_column("id", SqlScalarType::String.nullable(false))
3205 .with_column("name", SqlScalarType::String.nullable(false))
3206 .with_column("url", SqlScalarType::String.nullable(false))
3207 .finish(),
3208 column_comments: BTreeMap::from_iter([
3209 (
3210 "id",
3211 "The ID of the webhook source. Corresponds to `mz_sources.id`.",
3212 ),
3213 ("name", "The name of the webhook source."),
3214 (
3215 "url",
3216 "The URL which can be used to send events to the source.",
3217 ),
3218 ]),
3219 is_retained_metrics_object: false,
3220 access: vec![PUBLIC_SELECT],
3221 ontology: Some(Ontology {
3222 entity_name: "webhook_source",
3223 description: "Webhook source configuration",
3224 links: &const {
3225 [OntologyLink {
3226 name: "details_of",
3227 target: "source",
3228 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
3229 }]
3230 },
3231 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3232 }),
3233});
3234
3235pub static MZ_HISTORY_RETENTION_STRATEGIES: LazyLock<BuiltinTable> = LazyLock::new(|| {
3236 BuiltinTable {
3237 name: "mz_history_retention_strategies",
3238 schema: MZ_INTERNAL_SCHEMA,
3239 oid: oid::TABLE_MZ_HISTORY_RETENTION_STRATEGIES_OID,
3240 desc: RelationDesc::builder()
3241 .with_column("id", SqlScalarType::String.nullable(false))
3242 .with_column("strategy", SqlScalarType::String.nullable(false))
3243 .with_column("value", SqlScalarType::Jsonb.nullable(false))
3244 .finish(),
3245 column_comments: BTreeMap::from_iter([
3246 ("id", "The ID of the object."),
3247 (
3248 "strategy",
3249 "The strategy. `FOR` is the only strategy, and means the object's compaction window is the duration of the `value` field.",
3250 ),
3251 (
3252 "value",
3253 "The value of the strategy. For `FOR`, is a number of milliseconds.",
3254 ),
3255 ]),
3256 is_retained_metrics_object: false,
3257 access: vec![PUBLIC_SELECT],
3258 ontology: Some(Ontology {
3259 entity_name: "history_retention",
3260 description: "History retention strategy for an object",
3261 links: &const { [] },
3262 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3263 }),
3264 }
3265});
3266
3267pub static MZ_LICENSE_KEYS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3268 name: "mz_license_keys",
3269 schema: MZ_INTERNAL_SCHEMA,
3270 oid: oid::TABLE_MZ_LICENSE_KEYS_OID,
3271 desc: RelationDesc::builder()
3272 .with_column("id", SqlScalarType::String.nullable(false))
3273 .with_column("organization", SqlScalarType::String.nullable(false))
3274 .with_column("environment_id", SqlScalarType::String.nullable(false))
3275 .with_column(
3276 "expiration",
3277 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3278 )
3279 .with_column(
3280 "not_before",
3281 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3282 )
3283 .finish(),
3284 column_comments: BTreeMap::from_iter([
3285 ("id", "The identifier of the license key."),
3286 (
3287 "organization",
3288 "The name of the organization that this license key was issued to.",
3289 ),
3290 (
3291 "environment_id",
3292 "The environment ID that this license key was issued for.",
3293 ),
3294 (
3295 "expiration",
3296 "The date and time when this license key expires.",
3297 ),
3298 (
3299 "not_before",
3300 "The start of the validity period for this license key.",
3301 ),
3302 ]),
3303 is_retained_metrics_object: false,
3304 access: vec![PUBLIC_SELECT],
3305 ontology: Some(Ontology {
3306 entity_name: "license_key",
3307 description: "License key metadata",
3308 links: &const { [] },
3309 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3310 }),
3311});
3312
3313pub static MZ_REPLACEMENTS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3314 name: "mz_replacements",
3315 schema: MZ_INTERNAL_SCHEMA,
3316 oid: oid::TABLE_MZ_REPLACEMENTS_OID,
3317 desc: RelationDesc::builder()
3318 .with_column("id", SqlScalarType::String.nullable(false))
3319 .with_column("target_id", SqlScalarType::String.nullable(false))
3320 .finish(),
3321 column_comments: BTreeMap::from_iter([
3322 (
3323 "id",
3324 "The ID of the replacement object. Corresponds to `mz_objects.id`.",
3325 ),
3326 (
3327 "target_id",
3328 "The ID of the replacement target. Corresponds to `mz_objects.id`.",
3329 ),
3330 ]),
3331 is_retained_metrics_object: false,
3332 access: vec![PUBLIC_SELECT],
3333 ontology: Some(Ontology {
3334 entity_name: "replacement",
3335 description: "A record of an object replacement (ALTER ... SWAP)",
3336 links: &const {
3337 [
3338 OntologyLink {
3339 name: "replacement_object",
3340 target: "object",
3341 properties: LinkProperties::fk("id", "id", Cardinality::ManyToOne),
3342 },
3343 OntologyLink {
3344 name: "replacement_target",
3345 target: "object",
3346 properties: LinkProperties::fk("target_id", "id", Cardinality::ManyToOne),
3347 },
3348 ]
3349 },
3350 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3351 }),
3352});
3353
3354pub static MZ_SOURCE_STATISTICS_RAW: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
3357 name: "mz_source_statistics_raw",
3358 schema: MZ_INTERNAL_SCHEMA,
3359 oid: oid::SOURCE_MZ_SOURCE_STATISTICS_RAW_OID,
3360 data_source: IntrospectionType::StorageSourceStatistics.into(),
3361 desc: MZ_SOURCE_STATISTICS_RAW_DESC.clone(),
3362 column_comments: BTreeMap::new(),
3363 is_retained_metrics_object: true,
3364 access: vec![PUBLIC_SELECT],
3365 ontology: None,
3366});
3367pub static MZ_SINK_STATISTICS_RAW: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
3368 name: "mz_sink_statistics_raw",
3369 schema: MZ_INTERNAL_SCHEMA,
3370 oid: oid::SOURCE_MZ_SINK_STATISTICS_RAW_OID,
3371 data_source: IntrospectionType::StorageSinkStatistics.into(),
3372 desc: MZ_SINK_STATISTICS_RAW_DESC.clone(),
3373 column_comments: BTreeMap::new(),
3374 is_retained_metrics_object: true,
3375 access: vec![PUBLIC_SELECT],
3376 ontology: None,
3377});
3378
3379pub static MZ_STORAGE_SHARDS: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
3380 name: "mz_storage_shards",
3381 schema: MZ_INTERNAL_SCHEMA,
3382 oid: oid::SOURCE_MZ_STORAGE_SHARDS_OID,
3383 data_source: IntrospectionType::ShardMapping.into(),
3384 desc: RelationDesc::builder()
3385 .with_column("object_id", SqlScalarType::String.nullable(false))
3386 .with_column("shard_id", SqlScalarType::String.nullable(false))
3387 .finish(),
3388 column_comments: BTreeMap::new(),
3389 is_retained_metrics_object: false,
3390 access: vec![PUBLIC_SELECT],
3391 ontology: Some(Ontology {
3392 entity_name: "storage_shard",
3393 description: "Persist shards used by storage objects",
3394 links: &const {
3395 [OntologyLink {
3396 name: "shard_of",
3397 target: "object",
3398 properties: LinkProperties::fk_mapped(
3399 "object_id",
3400 "id",
3401 Cardinality::ManyToOne,
3402 mz_repr::SemanticType::GlobalId,
3403 "mz_internal.mz_object_global_ids",
3404 ),
3405 }]
3406 },
3407 column_semantic_types: &const {
3408 [
3409 ("object_id", SemanticType::GlobalId),
3410 ("shard_id", SemanticType::ShardId),
3411 ]
3412 },
3413 }),
3414});
3415
3416pub static MZ_OBJECTS_ID_NAMESPACE_TYPES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3417 name: "mz_objects_id_namespace_types",
3418 schema: MZ_INTERNAL_SCHEMA,
3419 oid: oid::VIEW_MZ_OBJECTS_ID_NAMESPACE_TYPES_OID,
3420 desc: RelationDesc::builder()
3421 .with_column("object_type", SqlScalarType::String.nullable(false))
3422 .with_key(vec![0])
3423 .finish(),
3424 column_comments: BTreeMap::new(),
3425 sql: r#"SELECT *
3426 FROM (
3427 VALUES
3428 ('table'),
3429 ('view'),
3430 ('materialized-view'),
3431 ('source'),
3432 ('sink'),
3433 ('index'),
3434 ('connection'),
3435 ('type'),
3436 ('function'),
3437 ('secret')
3438 )
3439 AS _ (object_type)"#,
3440 access: vec![PUBLIC_SELECT],
3441 ontology: None,
3442});
3443
3444pub static MZ_OBJECT_OID_ALIAS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3445 name: "mz_object_oid_alias",
3446 schema: MZ_INTERNAL_SCHEMA,
3447 oid: oid::VIEW_MZ_OBJECT_OID_ALIAS_OID,
3448 desc: RelationDesc::builder()
3449 .with_column("object_type", SqlScalarType::String.nullable(false))
3450 .with_column("oid_alias", SqlScalarType::String.nullable(false))
3451 .with_key(vec![0])
3452 .finish(),
3453 column_comments: BTreeMap::new(),
3454 sql: "SELECT object_type, oid_alias
3455 FROM (
3456 VALUES
3457 (
3458 'table'::pg_catalog.text,
3459 'regclass'::pg_catalog.text
3460 ),
3461 ('source', 'regclass'),
3462 ('view', 'regclass'),
3463 ('materialized-view', 'regclass'),
3464 ('index', 'regclass'),
3465 ('type', 'regtype'),
3466 ('function', 'regproc')
3467 )
3468 AS _ (object_type, oid_alias);",
3469 access: vec![PUBLIC_SELECT],
3470 ontology: None,
3471});
3472
3473pub static MZ_OBJECT_FULLY_QUALIFIED_NAMES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3474 name: "mz_object_fully_qualified_names",
3475 schema: MZ_INTERNAL_SCHEMA,
3476 oid: oid::VIEW_MZ_OBJECT_FULLY_QUALIFIED_NAMES_OID,
3477 desc: RelationDesc::builder()
3478 .with_column("id", SqlScalarType::String.nullable(false))
3479 .with_column("name", SqlScalarType::String.nullable(false))
3480 .with_column("object_type", SqlScalarType::String.nullable(false))
3481 .with_column("schema_id", SqlScalarType::String.nullable(false))
3482 .with_column("schema_name", SqlScalarType::String.nullable(false))
3483 .with_column("database_id", SqlScalarType::String.nullable(true))
3484 .with_column("database_name", SqlScalarType::String.nullable(true))
3485 .with_column("cluster_id", SqlScalarType::String.nullable(true))
3486 .finish(),
3487 column_comments: BTreeMap::from_iter([
3488 ("id", "Materialize's unique ID for the object."),
3489 ("name", "The name of the object."),
3490 (
3491 "object_type",
3492 "The type of the object: one of `table`, `source`, `view`, `materialized-view`, `sink`, `index`, `connection`, `secret`, `type`, or `function`.",
3493 ),
3494 (
3495 "schema_id",
3496 "The ID of the schema to which the object belongs. Corresponds to `mz_schemas.id`.",
3497 ),
3498 (
3499 "schema_name",
3500 "The name of the schema to which the object belongs. Corresponds to `mz_schemas.name`.",
3501 ),
3502 (
3503 "database_id",
3504 "The ID of the database to which the object belongs. Corresponds to `mz_databases.id`.",
3505 ),
3506 (
3507 "database_name",
3508 "The name of the database to which the object belongs. Corresponds to `mz_databases.name`.",
3509 ),
3510 (
3511 "cluster_id",
3512 "The ID of the cluster maintaining the source, materialized view, index, or sink. Corresponds to `mz_clusters.id`. `NULL` for other object types.",
3513 ),
3514 ]),
3515 sql: "
3516 SELECT o.id,
3517 o.name,
3518 o.type as object_type,
3519 sc.id as schema_id,
3520 sc.name as schema_name,
3521 db.id as database_id,
3522 db.name as database_name,
3523 o.cluster_id
3524 FROM mz_catalog.mz_objects o
3525 INNER JOIN mz_catalog.mz_schemas sc ON sc.id = o.schema_id
3526 -- LEFT JOIN accounts for objects in the ambient database.
3527 LEFT JOIN mz_catalog.mz_databases db ON db.id = sc.database_id",
3528 access: vec![PUBLIC_SELECT],
3529 ontology: Some(Ontology {
3530 entity_name: "object_fqn",
3531 description: "Fully qualified name (database.schema.name) for objects",
3532 links: &const {
3533 [
3534 OntologyLink {
3535 name: "details_of",
3536 target: "object",
3537 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
3538 },
3539 OntologyLink {
3540 name: "in_schema",
3541 target: "schema",
3542 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
3543 },
3544 OntologyLink {
3545 name: "in_database",
3546 target: "database",
3547 properties: LinkProperties::fk("database_id", "id", Cardinality::ManyToOne),
3548 },
3549 OntologyLink {
3550 name: "belongs_to_cluster",
3551 target: "cluster",
3552 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
3553 },
3554 ]
3555 },
3556 column_semantic_types: &const {
3557 [
3558 ("id", SemanticType::CatalogItemId),
3559 ("object_type", SemanticType::ObjectType),
3560 ("schema_id", SemanticType::SchemaId),
3561 ("database_id", SemanticType::DatabaseId),
3562 ("cluster_id", SemanticType::ClusterId),
3563 ]
3564 },
3565 }),
3566});
3567
3568pub static MZ_OBJECT_GLOBAL_IDS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3569 name: "mz_object_global_ids",
3570 schema: MZ_INTERNAL_SCHEMA,
3571 oid: oid::VIEW_MZ_OBJECT_GLOBAL_IDS_OID,
3572 desc: RelationDesc::builder()
3573 .with_column("id", SqlScalarType::String.nullable(false))
3574 .with_column("global_id", SqlScalarType::String.nullable(false))
3575 .finish(),
3576 column_comments: BTreeMap::from_iter([
3577 (
3578 "id",
3579 "The ID of the object. Corresponds to `mz_objects.id`.",
3580 ),
3581 ("global_id", "The global ID of the object."),
3582 ]),
3583 is_retained_metrics_object: false,
3584 access: vec![PUBLIC_SELECT],
3585 ontology: Some(Ontology {
3586 entity_name: "object_global_id",
3587 description: "Mapping between CatalogItemId (SQL layer) and GlobalId (runtime layer)",
3588 links: &const {
3589 [OntologyLink {
3590 name: "id_references",
3591 target: "object",
3592 properties: LinkProperties::fk("id", "id", Cardinality::ManyToOne),
3593 }]
3594 },
3595 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3596 }),
3597});
3598
3599pub static MZ_OBJECT_LIFETIMES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3601 name: "mz_object_lifetimes",
3602 schema: MZ_INTERNAL_SCHEMA,
3603 oid: oid::VIEW_MZ_OBJECT_LIFETIMES_OID,
3604 desc: RelationDesc::builder()
3605 .with_column("id", SqlScalarType::String.nullable(true))
3606 .with_column("previous_id", SqlScalarType::String.nullable(true))
3607 .with_column("object_type", SqlScalarType::String.nullable(false))
3608 .with_column("event_type", SqlScalarType::String.nullable(false))
3609 .with_column(
3610 "occurred_at",
3611 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3612 )
3613 .finish(),
3614 column_comments: BTreeMap::from_iter([
3615 ("id", "Materialize's unique ID for the object."),
3616 ("previous_id", "The object's previous ID, if one exists."),
3617 (
3618 "object_type",
3619 "The type of the object: one of `table`, `source`, `view`, `materialized-view`, `sink`, `index`, `connection`, `secret`, `type`, or `function`.",
3620 ),
3621 (
3622 "event_type",
3623 "The lifetime event, either `create` or `drop`.",
3624 ),
3625 (
3626 "occurred_at",
3627 "Wall-clock timestamp of when the event occurred.",
3628 ),
3629 ]),
3630 sql: "
3631 SELECT
3632 CASE
3633 WHEN a.object_type = 'cluster-replica' THEN a.details ->> 'replica_id'
3634 ELSE a.details ->> 'id'
3635 END id,
3636 a.details ->> 'previous_id' as previous_id,
3637 a.object_type,
3638 a.event_type,
3639 a.occurred_at
3640 FROM mz_catalog.mz_audit_events a
3641 WHERE a.event_type = 'create' OR a.event_type = 'drop'",
3642 access: vec![PUBLIC_SELECT],
3643 ontology: Some(Ontology {
3644 entity_name: "object_lifetime_event",
3645 description: "Create or drop lifecycle event for a catalog object",
3646 links: &const {
3647 [OntologyLink {
3648 name: "lifetime_event_of",
3649 target: "object",
3650 properties: LinkProperties::fk_typed(
3651 "id",
3652 "id",
3653 Cardinality::ManyToOne,
3654 mz_repr::SemanticType::CatalogItemId,
3655 ),
3656 }]
3657 },
3658 column_semantic_types: &const {
3659 [
3660 ("id", SemanticType::CatalogItemId),
3661 ("object_type", SemanticType::ObjectType),
3662 ]
3663 },
3664 }),
3665});
3666
3667pub static MZ_OBJECT_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3668 name: "mz_object_history",
3669 schema: MZ_INTERNAL_SCHEMA,
3670 oid: oid::VIEW_MZ_OBJECT_HISTORY_OID,
3671 desc: RelationDesc::builder()
3672 .with_column("id", SqlScalarType::String.nullable(true))
3673 .with_column("cluster_id", SqlScalarType::String.nullable(true))
3674 .with_column("object_type", SqlScalarType::String.nullable(false))
3675 .with_column(
3676 "created_at",
3677 SqlScalarType::TimestampTz { precision: None }.nullable(true),
3678 )
3679 .with_column(
3680 "dropped_at",
3681 SqlScalarType::TimestampTz { precision: None }.nullable(true),
3682 )
3683 .finish(),
3684 column_comments: BTreeMap::from_iter([
3685 ("id", "Materialize's unique ID for the object."),
3686 (
3687 "cluster_id",
3688 "The object's cluster ID. `NULL` if the object has no associated cluster.",
3689 ),
3690 (
3691 "object_type",
3692 "The type of the object: one of `table`, `source`, `view`, `materialized-view`, `sink`, `index`, `connection`, `secret`, `type`, or `function`.",
3693 ),
3694 (
3695 "created_at",
3696 "Wall-clock timestamp of when the object was created. `NULL` for built in system objects.",
3697 ),
3698 (
3699 "dropped_at",
3700 "Wall-clock timestamp of when the object was dropped. `NULL` for built in system objects or if the object hasn't been dropped.",
3701 ),
3702 ]),
3703 sql: r#"
3704 WITH
3705 creates AS
3706 (
3707 SELECT
3708 details ->> 'id' AS id,
3709 -- We need to backfill cluster_id since older object create events don't include the cluster ID in the audit log
3710 COALESCE(details ->> 'cluster_id', objects.cluster_id) AS cluster_id,
3711 object_type,
3712 occurred_at
3713 FROM
3714 mz_catalog.mz_audit_events AS events
3715 LEFT JOIN mz_catalog.mz_objects AS objects ON details ->> 'id' = objects.id
3716 WHERE event_type = 'create' AND object_type IN ( SELECT object_type FROM mz_internal.mz_objects_id_namespace_types )
3717 ),
3718 drops AS
3719 (
3720 SELECT details ->> 'id' AS id, occurred_at
3721 FROM mz_catalog.mz_audit_events
3722 WHERE event_type = 'drop' AND object_type IN ( SELECT object_type FROM mz_internal.mz_objects_id_namespace_types )
3723 ),
3724 user_object_history AS
3725 (
3726 SELECT
3727 creates.id,
3728 creates.cluster_id,
3729 creates.object_type,
3730 creates.occurred_at AS created_at,
3731 drops.occurred_at AS dropped_at
3732 FROM creates LEFT JOIN drops ON creates.id = drops.id
3733 WHERE creates.id LIKE 'u%'
3734 ),
3735 -- We need to union built in objects since they aren't in the audit log
3736 built_in_objects AS
3737 (
3738 -- Functions that accept different arguments have different oids but the same id. We deduplicate in this case.
3739 SELECT DISTINCT ON (objects.id)
3740 objects.id,
3741 objects.cluster_id,
3742 objects.type AS object_type,
3743 NULL::timestamptz AS created_at,
3744 NULL::timestamptz AS dropped_at
3745 FROM mz_catalog.mz_objects AS objects
3746 WHERE objects.id LIKE 's%'
3747 )
3748 SELECT * FROM user_object_history UNION ALL (SELECT * FROM built_in_objects)"#,
3749 access: vec![PUBLIC_SELECT],
3750 ontology: Some(Ontology {
3751 entity_name: "object_history",
3752 description: "Historical record of object creation and drops",
3753 links: &const {
3754 [OntologyLink {
3755 name: "history_of",
3756 target: "object",
3757 properties: LinkProperties::fk("id", "id", Cardinality::ManyToOne),
3758 }]
3759 },
3760 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3761 }),
3762});
3763
3764pub static MZ_OBJECT_TRANSITIVE_DEPENDENCIES: LazyLock<BuiltinView> = LazyLock::new(|| {
3765 BuiltinView {
3766 name: "mz_object_transitive_dependencies",
3767 schema: MZ_INTERNAL_SCHEMA,
3768 oid: oid::VIEW_MZ_OBJECT_TRANSITIVE_DEPENDENCIES_OID,
3769 desc: RelationDesc::builder()
3770 .with_column("object_id", SqlScalarType::String.nullable(false))
3771 .with_column(
3772 "referenced_object_id",
3773 SqlScalarType::String.nullable(false),
3774 )
3775 .with_key(vec![0, 1])
3776 .finish(),
3777 column_comments: BTreeMap::from_iter([
3778 (
3779 "object_id",
3780 "The ID of the dependent object. Corresponds to `mz_objects.id`.",
3781 ),
3782 (
3783 "referenced_object_id",
3784 "The ID of the (possibly transitively) referenced object. Corresponds to `mz_objects.id`.",
3785 ),
3786 ]),
3787 sql: "
3788WITH MUTUALLY RECURSIVE
3789 reach(object_id text, referenced_object_id text) AS (
3790 SELECT object_id, referenced_object_id FROM mz_internal.mz_object_dependencies
3791 UNION
3792 SELECT x, z FROM reach r1(x, y) JOIN reach r2(y, z) USING(y)
3793 )
3794SELECT object_id, referenced_object_id FROM reach;",
3795 access: vec![PUBLIC_SELECT],
3796 ontology: Some(Ontology {
3797 entity_name: "transitive_dependency",
3798 description: "Transitive closure of object dependencies — all direct and indirect dependencies",
3799 links: &const {
3800 [
3801 OntologyLink {
3802 name: "depends_on",
3803 target: "object",
3804 properties: LinkProperties::DependsOn {
3805 source_column: "object_id",
3806 target_column: "id",
3807 source_id_type: Some(mz_repr::SemanticType::CatalogItemId),
3808 requires_mapping: None,
3809 },
3810 },
3811 OntologyLink {
3812 name: "dependency_is",
3813 target: "object",
3814 properties: LinkProperties::DependsOn {
3815 source_column: "referenced_object_id",
3816 target_column: "id",
3817 source_id_type: Some(mz_repr::SemanticType::CatalogItemId),
3818 requires_mapping: None,
3819 },
3820 },
3821 ]
3822 },
3823 column_semantic_types: &const {
3824 [
3825 ("object_id", SemanticType::CatalogItemId),
3826 ("referenced_object_id", SemanticType::CatalogItemId),
3827 ]
3828 },
3829 }),
3830 }
3831});
3832
3833pub static PG_NAMESPACE_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3839 name: "pg_namespace_all_databases",
3840 schema: MZ_INTERNAL_SCHEMA,
3841 oid: oid::VIEW_PG_NAMESPACE_ALL_DATABASES_OID,
3842 desc: RelationDesc::builder()
3843 .with_column("oid", SqlScalarType::Oid.nullable(false))
3844 .with_column("nspname", SqlScalarType::String.nullable(false))
3845 .with_column("nspowner", SqlScalarType::Oid.nullable(false))
3846 .with_column(
3847 "nspacl",
3848 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(true),
3849 )
3850 .with_column("database_name", SqlScalarType::String.nullable(true))
3851 .finish(),
3852 column_comments: BTreeMap::new(),
3853 sql: "
3854SELECT
3855 s.oid AS oid,
3856 s.name AS nspname,
3857 role_owner.oid AS nspowner,
3858 NULL::pg_catalog.text[] AS nspacl,
3859 d.name as database_name
3860FROM mz_catalog.mz_schemas s
3861LEFT JOIN mz_catalog.mz_databases d ON d.id = s.database_id
3862JOIN mz_catalog.mz_roles role_owner ON role_owner.id = s.owner_id",
3863 access: vec![PUBLIC_SELECT],
3864 ontology: None,
3865});
3866
3867pub const PG_NAMESPACE_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
3868 name: "pg_namespace_all_databases_ind",
3869 schema: MZ_INTERNAL_SCHEMA,
3870 oid: oid::INDEX_PG_NAMESPACE_ALL_DATABASES_IND_OID,
3871 sql: "IN CLUSTER mz_catalog_server
3872ON mz_internal.pg_namespace_all_databases (nspname)",
3873 is_retained_metrics_object: false,
3874};
3875
3876pub static PG_CLASS_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| {
3882 BuiltinView {
3883 name: "pg_class_all_databases",
3884 schema: MZ_INTERNAL_SCHEMA,
3885 oid: oid::VIEW_PG_CLASS_ALL_DATABASES_OID,
3886 desc: RelationDesc::builder()
3887 .with_column("oid", SqlScalarType::Oid.nullable(false))
3888 .with_column("relname", SqlScalarType::String.nullable(false))
3889 .with_column("relnamespace", SqlScalarType::Oid.nullable(false))
3890 .with_column("reloftype", SqlScalarType::Oid.nullable(false))
3891 .with_column("relowner", SqlScalarType::Oid.nullable(false))
3892 .with_column("relam", SqlScalarType::Oid.nullable(false))
3893 .with_column("reltablespace", SqlScalarType::Oid.nullable(false))
3894 .with_column("reltuples", SqlScalarType::Float32.nullable(false))
3895 .with_column("reltoastrelid", SqlScalarType::Oid.nullable(false))
3896 .with_column("relhasindex", SqlScalarType::Bool.nullable(false))
3897 .with_column("relpersistence", SqlScalarType::PgLegacyChar.nullable(false))
3898 .with_column("relkind", SqlScalarType::String.nullable(true))
3899 .with_column("relnatts", SqlScalarType::Int16.nullable(false))
3900 .with_column("relchecks", SqlScalarType::Int16.nullable(false))
3901 .with_column("relhasrules", SqlScalarType::Bool.nullable(false))
3902 .with_column("relhastriggers", SqlScalarType::Bool.nullable(false))
3903 .with_column("relhassubclass", SqlScalarType::Bool.nullable(false))
3904 .with_column("relrowsecurity", SqlScalarType::Bool.nullable(false))
3905 .with_column("relforcerowsecurity", SqlScalarType::Bool.nullable(false))
3906 .with_column("relreplident", SqlScalarType::PgLegacyChar.nullable(false))
3907 .with_column("relispartition", SqlScalarType::Bool.nullable(false))
3908 .with_column("relhasoids", SqlScalarType::Bool.nullable(false))
3909 .with_column("reloptions", SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(true))
3910 .with_column("database_name", SqlScalarType::String.nullable(true))
3911 .finish(),
3912 column_comments: BTreeMap::new(),
3913 sql: "
3914SELECT
3915 class_objects.oid,
3916 class_objects.name AS relname,
3917 mz_schemas.oid AS relnamespace,
3918 -- MZ doesn't support typed tables so reloftype is filled with 0
3919 0::pg_catalog.oid AS reloftype,
3920 role_owner.oid AS relowner,
3921 0::pg_catalog.oid AS relam,
3922 -- MZ doesn't have tablespaces so reltablespace is filled in with 0 implying the default tablespace
3923 0::pg_catalog.oid AS reltablespace,
3924 -- MZ doesn't support (estimated) row counts currently.
3925 -- Postgres defines a value of -1 as unknown.
3926 -1::float4 as reltuples,
3927 -- MZ doesn't use TOAST tables so reltoastrelid is filled with 0
3928 0::pg_catalog.oid AS reltoastrelid,
3929 EXISTS (SELECT id, oid, name, on_id, cluster_id FROM mz_catalog.mz_indexes where mz_indexes.on_id = class_objects.id) AS relhasindex,
3930 -- MZ doesn't have unlogged tables and because of (https://github.com/MaterializeInc/database-issues/issues/2689)
3931 -- temporary objects don't show up here, so relpersistence is filled with 'p' for permanent.
3932 -- TODO(jkosh44): update this column when issue is resolved.
3933 'p'::pg_catalog.\"char\" AS relpersistence,
3934 CASE
3935 WHEN class_objects.type = 'table' THEN 'r'
3936 WHEN class_objects.type = 'source' THEN 'r'
3937 WHEN class_objects.type = 'index' THEN 'i'
3938 WHEN class_objects.type = 'view' THEN 'v'
3939 WHEN class_objects.type = 'materialized-view' THEN 'm'
3940 END relkind,
3941 CASE
3942 WHEN class_objects.type = 'index' THEN COALESCE(
3943 (
3944 SELECT count(*)::pg_catalog.int2
3945 FROM mz_catalog.mz_index_columns
3946 WHERE mz_index_columns.index_id = class_objects.id
3947 ),
3948 0::pg_catalog.int2
3949 )
3950 ELSE COALESCE(
3951 (
3952 SELECT count(*)::pg_catalog.int2
3953 FROM mz_catalog.mz_columns
3954 WHERE mz_columns.id = class_objects.id
3955 ),
3956 0::pg_catalog.int2
3957 )
3958 END AS relnatts,
3959 -- MZ doesn't support CHECK constraints so relchecks is filled with 0
3960 0::pg_catalog.int2 AS relchecks,
3961 -- MZ doesn't support creating rules so relhasrules is filled with false
3962 false AS relhasrules,
3963 -- MZ doesn't support creating triggers so relhastriggers is filled with false
3964 false AS relhastriggers,
3965 -- MZ doesn't support table inheritance or partitions so relhassubclass is filled with false
3966 false AS relhassubclass,
3967 -- MZ doesn't have row level security so relrowsecurity and relforcerowsecurity is filled with false
3968 false AS relrowsecurity,
3969 false AS relforcerowsecurity,
3970 -- MZ doesn't support replication so relreplident is filled with 'd' for default
3971 'd'::pg_catalog.\"char\" AS relreplident,
3972 -- MZ doesn't support table partitioning so relispartition is filled with false
3973 false AS relispartition,
3974 -- PG removed relhasoids in v12 so it's filled with false
3975 false AS relhasoids,
3976 -- MZ doesn't support options for relations
3977 NULL::pg_catalog.text[] as reloptions,
3978 d.name as database_name
3979FROM (
3980 -- pg_class catalogs relations and indexes
3981 SELECT id, oid, schema_id, name, type, owner_id FROM mz_catalog.mz_relations
3982 UNION ALL
3983 SELECT mz_indexes.id, mz_indexes.oid, mz_relations.schema_id, mz_indexes.name, 'index' AS type, mz_indexes.owner_id
3984 FROM mz_catalog.mz_indexes
3985 JOIN mz_catalog.mz_relations ON mz_indexes.on_id = mz_relations.id
3986) AS class_objects
3987JOIN mz_catalog.mz_schemas ON mz_schemas.id = class_objects.schema_id
3988LEFT JOIN mz_catalog.mz_databases d ON d.id = mz_schemas.database_id
3989JOIN mz_catalog.mz_roles role_owner ON role_owner.id = class_objects.owner_id",
3990 access: vec![PUBLIC_SELECT],
3991 ontology: None,
3992 }
3993});
3994
3995pub const PG_CLASS_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
3996 name: "pg_class_all_databases_ind",
3997 schema: MZ_INTERNAL_SCHEMA,
3998 oid: oid::INDEX_PG_CLASS_ALL_DATABASES_IND_OID,
3999 sql: "IN CLUSTER mz_catalog_server
4000ON mz_internal.pg_class_all_databases (relname)",
4001 is_retained_metrics_object: false,
4002};
4003
4004pub static PG_DESCRIPTION_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| {
4010 BuiltinView {
4011 name: "pg_description_all_databases",
4012 schema: MZ_INTERNAL_SCHEMA,
4013 oid: oid::VIEW_PG_DESCRIPTION_ALL_DATABASES_OID,
4014 desc: RelationDesc::builder()
4015 .with_column("objoid", SqlScalarType::Oid.nullable(false))
4016 .with_column("classoid", SqlScalarType::Oid.nullable(true))
4017 .with_column("objsubid", SqlScalarType::Int32.nullable(false))
4018 .with_column("description", SqlScalarType::String.nullable(false))
4019 .with_column("oid_database_name", SqlScalarType::String.nullable(true))
4020 .with_column("class_database_name", SqlScalarType::String.nullable(true))
4021 .finish(),
4022 column_comments: BTreeMap::new(),
4023 sql: "
4024(
4025 -- The classoid of a comment is the oid of the pg_catalog system catalog
4026 -- that conceptually stores the commented object: pg_class for relations,
4027 -- pg_type for types, pg_namespace for schemas. We scope the lookup to the
4028 -- pg_catalog schema; otherwise a user-created object named e.g. `pg_class`
4029 -- makes the scalar subqueries below match multiple rows and the whole view
4030 -- errors for everyone. PostgreSQL's pg_description is a real catalog table
4031 -- and is unaffected by such user objects, and so are we.
4032 WITH pg_catalog_class AS (
4033 SELECT oid, relname, database_name
4034 FROM mz_internal.pg_class_all_databases
4035 WHERE relnamespace = (
4036 SELECT oid FROM mz_internal.pg_namespace_all_databases WHERE nspname = 'pg_catalog'
4037 )
4038 ),
4039 -- Gather all of the class oid's for objects that can have comments.
4040 pg_classoids AS (
4041 SELECT oid, database_name as oid_database_name,
4042 (SELECT oid FROM pg_catalog_class WHERE relname = 'pg_class') AS classoid,
4043 (SELECT database_name FROM pg_catalog_class WHERE relname = 'pg_class') AS class_database_name
4044 FROM mz_internal.pg_class_all_databases
4045 UNION ALL
4046 SELECT oid, database_name as oid_database_name,
4047 (SELECT oid FROM pg_catalog_class WHERE relname = 'pg_type') AS classoid,
4048 (SELECT database_name FROM pg_catalog_class WHERE relname = 'pg_type') AS class_database_name
4049 FROM mz_internal.pg_type_all_databases
4050 UNION ALL
4051 SELECT oid, database_name as oid_database_name,
4052 (SELECT oid FROM pg_catalog_class WHERE relname = 'pg_namespace') AS classoid,
4053 (SELECT database_name FROM pg_catalog_class WHERE relname = 'pg_namespace') AS class_database_name
4054 FROM mz_internal.pg_namespace_all_databases
4055 ),
4056
4057 -- Gather all of the MZ ids for objects that can have comments.
4058 mz_objects AS (
4059 SELECT id, oid, type FROM mz_catalog.mz_objects
4060 UNION ALL
4061 SELECT id, oid, 'schema' AS type FROM mz_catalog.mz_schemas
4062 )
4063 SELECT
4064 pg_classoids.oid AS objoid,
4065 pg_classoids.classoid as classoid,
4066 COALESCE(cmt.object_sub_id, 0) AS objsubid,
4067 cmt.comment AS description,
4068 -- Columns added because of the peeling. (Note that there are 2 of these here.)
4069 oid_database_name,
4070 class_database_name
4071 FROM
4072 pg_classoids
4073 JOIN
4074 mz_objects ON pg_classoids.oid = mz_objects.oid
4075 JOIN
4076 mz_internal.mz_comments AS cmt ON mz_objects.id = cmt.id AND lower(mz_objects.type) = lower(cmt.object_type)
4077)",
4078 access: vec![PUBLIC_SELECT],
4079 ontology: None,
4080 }
4081});
4082
4083pub const PG_DESCRIPTION_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4084 name: "pg_description_all_databases_ind",
4085 schema: MZ_INTERNAL_SCHEMA,
4086 oid: oid::INDEX_PG_DESCRIPTION_ALL_DATABASES_IND_OID,
4087 sql: "IN CLUSTER mz_catalog_server
4088ON mz_internal.pg_description_all_databases (objoid, classoid, objsubid, description, oid_database_name, class_database_name)",
4089 is_retained_metrics_object: false,
4090};
4091
4092pub static PG_TYPE_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| {
4098 BuiltinView {
4099 name: "pg_type_all_databases",
4100 schema: MZ_INTERNAL_SCHEMA,
4101 oid: oid::VIEW_PG_TYPE_ALL_DATABASES_OID,
4102 desc: RelationDesc::builder()
4103 .with_column("oid", SqlScalarType::Oid.nullable(false))
4104 .with_column("typname", SqlScalarType::String.nullable(false))
4105 .with_column("typnamespace", SqlScalarType::Oid.nullable(false))
4106 .with_column("typowner", SqlScalarType::Oid.nullable(false))
4107 .with_column("typlen", SqlScalarType::Int16.nullable(true))
4108 .with_column("typtype", SqlScalarType::PgLegacyChar.nullable(false))
4109 .with_column("typcategory", SqlScalarType::PgLegacyChar.nullable(true))
4110 .with_column("typdelim", SqlScalarType::PgLegacyChar.nullable(false))
4111 .with_column("typrelid", SqlScalarType::Oid.nullable(false))
4112 .with_column("typelem", SqlScalarType::Oid.nullable(false))
4113 .with_column("typarray", SqlScalarType::Oid.nullable(false))
4114 .with_column("typinput", SqlScalarType::RegProc.nullable(true))
4115 .with_column("typreceive", SqlScalarType::Oid.nullable(false))
4116 .with_column("typnotnull", SqlScalarType::Bool.nullable(false))
4117 .with_column("typbasetype", SqlScalarType::Oid.nullable(false))
4118 .with_column("typtypmod", SqlScalarType::Int32.nullable(false))
4119 .with_column("typcollation", SqlScalarType::Oid.nullable(false))
4120 .with_column("typdefault", SqlScalarType::String.nullable(true))
4121 .with_column("database_name", SqlScalarType::String.nullable(true))
4122 .finish(),
4123 column_comments: BTreeMap::new(),
4124 sql: "
4125SELECT
4126 mz_types.oid,
4127 mz_types.name AS typname,
4128 mz_schemas.oid AS typnamespace,
4129 role_owner.oid AS typowner,
4130 NULL::pg_catalog.int2 AS typlen,
4131 -- 'a' is used internally to denote an array type, but in postgres they show up
4132 -- as 'b'.
4133 (CASE mztype WHEN 'a' THEN 'b' ELSE mztype END)::pg_catalog.char AS typtype,
4134 (CASE category
4135 WHEN 'array' THEN 'A'
4136 WHEN 'bit-string' THEN 'V'
4137 WHEN 'boolean' THEN 'B'
4138 WHEN 'composite' THEN 'C'
4139 WHEN 'date-time' THEN 'D'
4140 WHEN 'enum' THEN 'E'
4141 WHEN 'geometric' THEN 'G'
4142 WHEN 'list' THEN 'U' -- List types are user-defined from PostgreSQL's perspective.
4143 WHEN 'network-address' THEN 'I'
4144 WHEN 'numeric' THEN 'N'
4145 WHEN 'pseudo' THEN 'P'
4146 WHEN 'string' THEN 'S'
4147 WHEN 'timespan' THEN 'T'
4148 WHEN 'user-defined' THEN 'U'
4149 WHEN 'unknown' THEN 'X'
4150 END)::pg_catalog.char AS typcategory,
4151 -- In pg only the 'box' type is not ','.
4152 ','::pg_catalog.char AS typdelim,
4153 0::pg_catalog.oid AS typrelid,
4154 coalesce(
4155 (
4156 SELECT t.oid
4157 FROM mz_catalog.mz_array_types a
4158 JOIN mz_catalog.mz_types t ON a.element_id = t.id
4159 WHERE a.id = mz_types.id
4160 ),
4161 (
4162 SELECT t.oid
4163 FROM mz_catalog.mz_list_types l
4164 JOIN mz_catalog.mz_types t ON l.element_id = t.id
4165 WHERE l.id = mz_types.id
4166 ),
4167 0
4168 ) AS typelem,
4169 coalesce(
4170 (
4171 SELECT
4172 t.oid
4173 FROM
4174 mz_catalog.mz_array_types AS a
4175 JOIN mz_catalog.mz_types AS t ON a.id = t.id
4176 WHERE
4177 a.element_id = mz_types.id
4178 ),
4179 0
4180 )
4181 AS typarray,
4182 mz_internal.mz_type_pg_metadata.typinput::pg_catalog.regproc AS typinput,
4183 COALESCE(mz_internal.mz_type_pg_metadata.typreceive, 0) AS typreceive,
4184 false::pg_catalog.bool AS typnotnull,
4185 0::pg_catalog.oid AS typbasetype,
4186 -1::pg_catalog.int4 AS typtypmod,
4187 -- MZ doesn't support COLLATE so typcollation is filled with 0
4188 0::pg_catalog.oid AS typcollation,
4189 NULL::pg_catalog.text AS typdefault,
4190 d.name as database_name
4191FROM
4192 mz_catalog.mz_types
4193 LEFT JOIN mz_internal.mz_type_pg_metadata ON mz_catalog.mz_types.id = mz_internal.mz_type_pg_metadata.id
4194 JOIN mz_catalog.mz_schemas ON mz_schemas.id = mz_types.schema_id
4195 JOIN (
4196 -- 'a' is not a supported typtype, but we use it to denote an array. It is
4197 -- converted to the correct value above.
4198 SELECT id, 'a' AS mztype FROM mz_catalog.mz_array_types
4199 UNION ALL SELECT id, 'b' FROM mz_catalog.mz_base_types
4200 UNION ALL SELECT id, 'l' FROM mz_catalog.mz_list_types
4201 UNION ALL SELECT id, 'm' FROM mz_catalog.mz_map_types
4202 UNION ALL SELECT id, 'p' FROM mz_catalog.mz_pseudo_types
4203 )
4204 AS t ON mz_types.id = t.id
4205 LEFT JOIN mz_catalog.mz_databases d ON d.id = mz_schemas.database_id
4206 JOIN mz_catalog.mz_roles role_owner ON role_owner.id = mz_types.owner_id",
4207 access: vec![PUBLIC_SELECT],
4208 ontology: None,
4209 }
4210});
4211
4212pub const PG_TYPE_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4213 name: "pg_type_all_databases_ind",
4214 schema: MZ_INTERNAL_SCHEMA,
4215 oid: oid::INDEX_PG_TYPE_ALL_DATABASES_IND_OID,
4216 sql: "IN CLUSTER mz_catalog_server
4217ON mz_internal.pg_type_all_databases (oid)",
4218 is_retained_metrics_object: false,
4219};
4220
4221pub static PG_ATTRIBUTE_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| {
4227 BuiltinView {
4228 name: "pg_attribute_all_databases",
4229 schema: MZ_INTERNAL_SCHEMA,
4230 oid: oid::VIEW_PG_ATTRIBUTE_ALL_DATABASES_OID,
4231 desc: RelationDesc::builder()
4232 .with_column("attrelid", SqlScalarType::Oid.nullable(false))
4233 .with_column("attname", SqlScalarType::String.nullable(false))
4234 .with_column("atttypid", SqlScalarType::Oid.nullable(false))
4235 .with_column("attlen", SqlScalarType::Int16.nullable(true))
4236 .with_column("attnum", SqlScalarType::Int16.nullable(false))
4237 .with_column("atttypmod", SqlScalarType::Int32.nullable(false))
4238 .with_column("attndims", SqlScalarType::Int16.nullable(false))
4239 .with_column("attnotnull", SqlScalarType::Bool.nullable(false))
4240 .with_column("atthasdef", SqlScalarType::Bool.nullable(false))
4241 .with_column("attidentity", SqlScalarType::PgLegacyChar.nullable(false))
4242 .with_column("attgenerated", SqlScalarType::PgLegacyChar.nullable(false))
4243 .with_column("attisdropped", SqlScalarType::Bool.nullable(false))
4244 .with_column("attcollation", SqlScalarType::Oid.nullable(false))
4245 .with_column("database_name", SqlScalarType::String.nullable(true))
4246 .with_column("pg_type_database_name", SqlScalarType::String.nullable(true))
4247 .finish(),
4248 column_comments: BTreeMap::new(),
4249 sql: "
4250SELECT
4251 class_objects.oid as attrelid,
4252 mz_columns.name as attname,
4253 mz_columns.type_oid AS atttypid,
4254 pg_type_all_databases.typlen AS attlen,
4255 position::int8::int2 as attnum,
4256 mz_columns.type_mod as atttypmod,
4257 -- dummy value, just to make go-jet's workaround work for now. Discussion:
4258 -- https://github.com/MaterializeInc/materialize/pull/34649#issuecomment-3714291409
4259 0::int2 as attndims,
4260 NOT nullable as attnotnull,
4261 mz_columns.default IS NOT NULL as atthasdef,
4262 ''::pg_catalog.\"char\" as attidentity,
4263 -- MZ doesn't support generated columns so attgenerated is filled with ''
4264 ''::pg_catalog.\"char\" as attgenerated,
4265 FALSE as attisdropped,
4266 -- MZ doesn't support COLLATE so attcollation is filled with 0
4267 0::pg_catalog.oid as attcollation,
4268 -- Columns added because of the peeling. (Note that there are 2 of these here.)
4269 d.name as database_name,
4270 pg_type_all_databases.database_name as pg_type_database_name
4271FROM (
4272 -- pg_attribute catalogs columns on relations and indexes
4273 SELECT id, oid, schema_id, name, type FROM mz_catalog.mz_relations
4274 UNION ALL
4275 SELECT mz_indexes.id, mz_indexes.oid, mz_relations.schema_id, mz_indexes.name, 'index' AS type
4276 FROM mz_catalog.mz_indexes
4277 JOIN mz_catalog.mz_relations ON mz_indexes.on_id = mz_relations.id
4278) AS class_objects
4279JOIN mz_catalog.mz_columns ON class_objects.id = mz_columns.id
4280JOIN mz_internal.pg_type_all_databases ON pg_type_all_databases.oid = mz_columns.type_oid
4281JOIN mz_catalog.mz_schemas ON mz_schemas.id = class_objects.schema_id
4282LEFT JOIN mz_catalog.mz_databases d ON d.id = mz_schemas.database_id",
4283 access: vec![PUBLIC_SELECT],
4286 ontology: None,
4287 }
4288});
4289
4290pub const PG_ATTRIBUTE_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4291 name: "pg_attribute_all_databases_ind",
4292 schema: MZ_INTERNAL_SCHEMA,
4293 oid: oid::INDEX_PG_ATTRIBUTE_ALL_DATABASES_IND_OID,
4294 sql: "IN CLUSTER mz_catalog_server
4295ON mz_internal.pg_attribute_all_databases (
4296 attrelid, attname, atttypid, attlen, attnum, atttypmod, attnotnull, atthasdef, attidentity,
4297 attgenerated, attisdropped, attcollation, database_name, pg_type_database_name
4298)",
4299 is_retained_metrics_object: false,
4300};
4301
4302pub static PG_ATTRDEF_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4306 name: "pg_attrdef_all_databases",
4307 schema: MZ_INTERNAL_SCHEMA,
4308 oid: oid::VIEW_PG_ATTRDEF_ALL_DATABASES_OID,
4309 desc: RelationDesc::builder()
4310 .with_column("oid", SqlScalarType::Oid.nullable(true))
4311 .with_column("adrelid", SqlScalarType::Oid.nullable(false))
4312 .with_column("adnum", SqlScalarType::Int64.nullable(false))
4313 .with_column("adbin", SqlScalarType::String.nullable(false))
4314 .with_column("adsrc", SqlScalarType::String.nullable(false))
4315 .finish(),
4316 column_comments: BTreeMap::new(),
4317 sql: "
4318SELECT
4319 NULL::pg_catalog.oid AS oid,
4320 mz_objects.oid AS adrelid,
4321 mz_columns.position::int8 AS adnum,
4322 mz_columns.default AS adbin,
4323 mz_columns.default AS adsrc
4324FROM mz_catalog.mz_columns
4325 JOIN mz_catalog.mz_objects ON mz_columns.id = mz_objects.id
4326WHERE default IS NOT NULL",
4327 access: vec![PUBLIC_SELECT],
4328 ontology: None,
4329});
4330
4331pub const PG_ATTRDEF_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4332 name: "pg_attrdef_all_databases_ind",
4333 schema: MZ_INTERNAL_SCHEMA,
4334 oid: oid::INDEX_PG_ATTRDEF_ALL_DATABASES_IND_OID,
4335 sql: "IN CLUSTER mz_catalog_server
4336ON mz_internal.pg_attrdef_all_databases (oid, adrelid, adnum, adbin, adsrc)",
4337 is_retained_metrics_object: false,
4338};
4339
4340pub static MZ_COMPUTE_ERROR_COUNTS_RAW_UNIFIED: LazyLock<BuiltinSource> =
4341 LazyLock::new(|| BuiltinSource {
4342 name: "mz_compute_error_counts_raw_unified",
4346 schema: MZ_INTERNAL_SCHEMA,
4347 oid: oid::SOURCE_MZ_COMPUTE_ERROR_COUNTS_RAW_UNIFIED_OID,
4348 desc: RelationDesc::builder()
4349 .with_column("replica_id", SqlScalarType::String.nullable(false))
4350 .with_column("object_id", SqlScalarType::String.nullable(false))
4351 .with_column(
4352 "count",
4353 SqlScalarType::Numeric { max_scale: None }.nullable(false),
4354 )
4355 .finish(),
4356 data_source: IntrospectionType::ComputeErrorCounts.into(),
4357 column_comments: BTreeMap::new(),
4358 is_retained_metrics_object: false,
4359 access: vec![PUBLIC_SELECT],
4360 ontology: None,
4361 });
4362
4363pub static MZ_COMPUTE_HYDRATION_TIMES: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
4364 name: "mz_compute_hydration_times",
4365 schema: MZ_INTERNAL_SCHEMA,
4366 oid: oid::SOURCE_MZ_COMPUTE_HYDRATION_TIMES_OID,
4367 desc: RelationDesc::builder()
4368 .with_column("replica_id", SqlScalarType::String.nullable(false))
4369 .with_column("object_id", SqlScalarType::String.nullable(false))
4370 .with_column("time_ns", SqlScalarType::UInt64.nullable(true))
4371 .finish(),
4372 data_source: IntrospectionType::ComputeHydrationTimes.into(),
4373 column_comments: BTreeMap::new(),
4374 is_retained_metrics_object: true,
4375 access: vec![PUBLIC_SELECT],
4376 ontology: Some(Ontology {
4377 entity_name: "compute_hydration_time",
4378 description: "Time to hydrate compute objects",
4379 links: &const { [] },
4380 column_semantic_types: &const {
4381 [
4382 ("replica_id", SemanticType::ReplicaId),
4383 ("object_id", SemanticType::CatalogItemId),
4384 ]
4385 },
4386 }),
4387});
4388
4389pub static MZ_COMPUTE_HYDRATION_TIMES_IND: LazyLock<BuiltinIndex> =
4390 LazyLock::new(|| BuiltinIndex {
4391 name: "mz_compute_hydration_times_ind",
4392 schema: MZ_INTERNAL_SCHEMA,
4393 oid: oid::INDEX_MZ_COMPUTE_HYDRATION_TIMES_IND_OID,
4394 sql: "IN CLUSTER mz_catalog_server
4395 ON mz_internal.mz_compute_hydration_times (replica_id)",
4396 is_retained_metrics_object: true,
4397 });
4398
4399pub static MZ_OBJECT_ARRANGEMENT_SIZES_UNIFIED: LazyLock<BuiltinSource> = LazyLock::new(|| {
4400 BuiltinSource {
4401 name: "mz_object_arrangement_sizes",
4402 schema: MZ_INTERNAL_SCHEMA,
4403 oid: oid::SOURCE_MZ_OBJECT_ARRANGEMENT_SIZES_OID,
4404 desc: RelationDesc::builder()
4405 .with_column("replica_id", SqlScalarType::String.nullable(false))
4406 .with_column("object_id", SqlScalarType::String.nullable(false))
4407 .with_column("size", SqlScalarType::Int64.nullable(true))
4408 .finish(),
4409 data_source: IntrospectionType::ComputeObjectArrangementSizes.into(),
4410 column_comments: BTreeMap::from_iter([
4411 (
4412 "replica_id",
4413 "The ID of the cluster replica. Corresponds to `mz_cluster_replicas.id`.",
4414 ),
4415 (
4416 "object_id",
4417 "The ID of the compute object (index or materialized view). Corresponds to `mz_objects.id`.",
4418 ),
4419 (
4420 "size",
4421 "The total arrangement heap and batcher size in bytes for this object on this replica. \
4422 Objects smaller than 10 MiB are reported at their exact size; objects 10 MiB or larger \
4423 are rounded to the nearest 10 MiB boundary to reduce per-byte churn in the differential \
4424 collection.",
4425 ),
4426 ]),
4427 is_retained_metrics_object: true,
4428 access: vec![PUBLIC_SELECT],
4429 ontology: None,
4430 }
4431});
4432
4433pub static MZ_OBJECT_ARRANGEMENT_SIZES_IND: LazyLock<BuiltinIndex> =
4434 LazyLock::new(|| BuiltinIndex {
4435 name: "mz_object_arrangement_sizes_ind",
4436 schema: MZ_INTERNAL_SCHEMA,
4437 oid: oid::INDEX_MZ_OBJECT_ARRANGEMENT_SIZES_IND_OID,
4438 sql: "IN CLUSTER mz_catalog_server
4439 ON mz_internal.mz_object_arrangement_sizes (replica_id)",
4440 is_retained_metrics_object: true,
4441 });
4442
4443pub static MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY: LazyLock<BuiltinTable> = LazyLock::new(|| {
4444 BuiltinTable {
4445 name: "mz_object_arrangement_size_history",
4446 schema: MZ_INTERNAL_SCHEMA,
4447 oid: oid::TABLE_MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_OID,
4448 desc: RelationDesc::builder()
4449 .with_column("replica_id", SqlScalarType::String.nullable(false))
4450 .with_column("object_id", SqlScalarType::String.nullable(false))
4451 .with_column("size", SqlScalarType::Int64.nullable(false))
4452 .with_column(
4453 "collection_timestamp",
4454 SqlScalarType::TimestampTz { precision: None }.nullable(false),
4455 )
4456 .with_column("hydration_complete", SqlScalarType::Bool.nullable(false))
4457 .finish(),
4458 column_comments: BTreeMap::from_iter([
4459 (
4460 "replica_id",
4461 "The ID of the cluster replica. Corresponds to `mz_cluster_replicas.id`.",
4462 ),
4463 (
4464 "object_id",
4465 "The ID of the compute object (index or materialized view). Corresponds to `mz_objects.id`.",
4466 ),
4467 (
4468 "size",
4469 "The total arrangement heap and batcher size in bytes for this object on this replica \
4470 at `collection_timestamp`. Objects below 10 MiB are dropped from the snapshot; \
4471 objects at or above the floor are rounded to the nearest 10 MiB to reduce \
4472 per-byte churn in the underlying differential collection. May reflect a mid-build \
4473 size if `hydration_complete` is `false`.",
4474 ),
4475 (
4476 "collection_timestamp",
4477 "The timestamp when this snapshot was collected.",
4478 ),
4479 (
4480 "hydration_complete",
4481 "Whether the arrangement had finished its initial hydration on this replica when \
4482 the snapshot was collected. Filter for `true` to consider only stable, post-build \
4483 sizes.",
4484 ),
4485 ]),
4486 is_retained_metrics_object: true,
4487 access: vec![PUBLIC_SELECT],
4488 ontology: None,
4489 }
4490});
4491
4492pub static MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_OBJECT_IND: LazyLock<BuiltinIndex> =
4493 LazyLock::new(|| BuiltinIndex {
4494 name: "mz_object_arrangement_size_history_object_ind",
4495 schema: MZ_INTERNAL_SCHEMA,
4496 oid: oid::INDEX_MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_OBJECT_IND_OID,
4497 sql: "IN CLUSTER mz_catalog_server
4498 ON mz_internal.mz_object_arrangement_size_history (object_id)",
4499 is_retained_metrics_object: true,
4500 });
4501
4502pub static MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_TS_IND: LazyLock<BuiltinIndex> =
4503 LazyLock::new(|| BuiltinIndex {
4504 name: "mz_object_arrangement_size_history_ts_ind",
4505 schema: MZ_INTERNAL_SCHEMA,
4506 oid: oid::INDEX_MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_TS_IND_OID,
4507 sql: "IN CLUSTER mz_catalog_server
4508 ON mz_internal.mz_object_arrangement_size_history (collection_timestamp)",
4509 is_retained_metrics_object: true,
4510 });
4511
4512pub static MZ_COMPUTE_HYDRATION_STATUSES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4513 name: "mz_compute_hydration_statuses",
4514 schema: MZ_INTERNAL_SCHEMA,
4515 oid: oid::SOURCE_MZ_COMPUTE_HYDRATION_STATUSES_OID,
4516 desc: RelationDesc::builder()
4517 .with_column("object_id", SqlScalarType::String.nullable(false))
4518 .with_column("replica_id", SqlScalarType::String.nullable(false))
4519 .with_column("hydrated", SqlScalarType::Bool.nullable(false))
4520 .with_column("hydration_time", SqlScalarType::Interval.nullable(true))
4521 .finish(),
4522 column_comments: BTreeMap::from_iter([
4523 (
4524 "object_id",
4525 "The ID of a compute object. Corresponds to `mz_catalog.mz_indexes.id` or `mz_catalog.mz_materialized_views.id`",
4526 ),
4527 ("replica_id", "The ID of a cluster replica."),
4528 (
4529 "hydrated",
4530 "Whether the compute object is hydrated on the replica.",
4531 ),
4532 (
4533 "hydration_time",
4534 "The amount of time it took for the replica to hydrate the compute object.",
4535 ),
4536 ]),
4537 sql: "
4538WITH
4539 dataflows AS (
4540 SELECT
4541 object_id,
4542 replica_id,
4543 time_ns IS NOT NULL AS hydrated,
4544 ((time_ns / 1000) || 'microseconds')::interval AS hydration_time
4545 FROM mz_internal.mz_compute_hydration_times
4546 ),
4547 -- MVs that have advanced to the empty frontier don't have a dataflow installed anymore and
4548 -- therefore don't show up in `mz_compute_hydration_times`. We still want to show them here to
4549 -- avoid surprises for people joining `mz_materialized_views` against this relation (like the
4550 -- blue-green readiness query does), so we include them as 'hydrated'.
4551 complete_mvs AS (
4552 SELECT
4553 mv.id,
4554 f.replica_id,
4555 true AS hydrated,
4556 NULL::interval AS hydration_time
4557 FROM mz_materialized_views mv
4558 JOIN mz_catalog.mz_cluster_replica_frontiers f ON f.object_id = mv.id
4559 WHERE f.write_frontier IS NULL
4560 )
4561SELECT * FROM dataflows
4562UNION ALL
4563SELECT * FROM complete_mvs",
4564 access: vec![PUBLIC_SELECT],
4565 ontology: Some(Ontology {
4566 entity_name: "compute_hydration_status_view",
4567 description: "Computed hydration status per compute object",
4568 links: &const { [] },
4569 column_semantic_types: &const {
4570 [
4571 ("object_id", SemanticType::GlobalId),
4572 ("replica_id", SemanticType::ReplicaId),
4573 ]
4574 },
4575 }),
4576});
4577
4578pub static MZ_COMPUTE_OPERATOR_HYDRATION_STATUSES: LazyLock<BuiltinSource> = LazyLock::new(|| {
4579 BuiltinSource {
4580 name: "mz_compute_operator_hydration_statuses",
4581 schema: MZ_INTERNAL_SCHEMA,
4582 oid: oid::SOURCE_MZ_COMPUTE_OPERATOR_HYDRATION_STATUSES_OID,
4583 desc: RelationDesc::builder()
4584 .with_column("replica_id", SqlScalarType::String.nullable(false))
4585 .with_column("object_id", SqlScalarType::String.nullable(false))
4586 .with_column(
4587 "physical_plan_node_id",
4588 SqlScalarType::UInt64.nullable(false),
4589 )
4590 .with_column("hydrated", SqlScalarType::Bool.nullable(false))
4591 .with_key(vec![0, 1, 2])
4592 .finish(),
4593 data_source: IntrospectionType::ComputeOperatorHydrationStatus.into(),
4594 column_comments: BTreeMap::from_iter([
4595 ("replica_id", "The ID of a cluster replica."),
4596 (
4597 "object_id",
4598 "The ID of a compute object. Corresponds to `mz_catalog.mz_indexes.id` or `mz_catalog.mz_materialized_views.id`.",
4599 ),
4600 (
4601 "physical_plan_node_id",
4602 "The ID of a node in the physical plan of the compute object. Corresponds to a `node_id` displayed in the output of `EXPLAIN PHYSICAL PLAN WITH (node identifiers)`.",
4603 ),
4604 ("hydrated", "Whether the node is hydrated on the replica."),
4605 ]),
4606 is_retained_metrics_object: false,
4607 access: vec![PUBLIC_SELECT],
4608 ontology: Some(Ontology {
4609 entity_name: "compute_hydration_status",
4610 description: "Hydration status per compute operator",
4611 links: &const { [] },
4612 column_semantic_types: &const {
4613 [
4614 ("replica_id", SemanticType::ReplicaId),
4615 ("object_id", SemanticType::CatalogItemId),
4616 ]
4617 },
4618 }),
4619 }
4620});
4621
4622pub static MZ_CLUSTER_REPLICA_UTILIZATION: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4623 name: "mz_cluster_replica_utilization",
4624 schema: MZ_INTERNAL_SCHEMA,
4625 oid: oid::VIEW_MZ_CLUSTER_REPLICA_UTILIZATION_OID,
4626 desc: RelationDesc::builder()
4627 .with_column("replica_id", SqlScalarType::String.nullable(false))
4628 .with_column("process_id", SqlScalarType::UInt64.nullable(false))
4629 .with_column("cpu_percent", SqlScalarType::Float64.nullable(true))
4630 .with_column("memory_percent", SqlScalarType::Float64.nullable(true))
4631 .with_column("disk_percent", SqlScalarType::Float64.nullable(true))
4632 .with_column("heap_percent", SqlScalarType::Float64.nullable(true))
4633 .finish(),
4634 column_comments: BTreeMap::from_iter([
4635 ("replica_id", "The ID of a cluster replica."),
4636 ("process_id", "The ID of a process within the replica."),
4637 (
4638 "cpu_percent",
4639 "Approximate CPU usage, in percent of the total allocation.",
4640 ),
4641 (
4642 "memory_percent",
4643 "Approximate RAM usage, in percent of the total allocation.",
4644 ),
4645 (
4646 "disk_percent",
4647 "Approximate disk usage, in percent of the total allocation.",
4648 ),
4649 (
4650 "heap_percent",
4651 "Approximate heap (RAM + swap) usage, in percent of the total allocation.",
4652 ),
4653 ]),
4654 sql: "
4655SELECT
4656 r.id AS replica_id,
4657 m.process_id,
4658 m.cpu_nano_cores::float8 / NULLIF(s.cpu_nano_cores, 0) * 100 AS cpu_percent,
4659 m.memory_bytes::float8 / NULLIF(s.memory_bytes, 0) * 100 AS memory_percent,
4660 m.disk_bytes::float8 / NULLIF(s.disk_bytes, 0) * 100 AS disk_percent,
4661 m.heap_bytes::float8 / NULLIF(m.heap_limit, 0) * 100 AS heap_percent
4662FROM
4663 mz_catalog.mz_cluster_replicas AS r
4664 JOIN mz_catalog.mz_cluster_replica_sizes AS s ON r.size = s.size
4665 JOIN mz_internal.mz_cluster_replica_metrics AS m ON m.replica_id = r.id",
4666 access: vec![PUBLIC_SELECT],
4667 ontology: Some(Ontology {
4668 entity_name: "replica_utilization",
4669 description: "Computed utilization metrics per replica",
4670 links: &const {
4671 [OntologyLink {
4672 name: "utilization_of_replica",
4673 target: "replica",
4674 properties: LinkProperties::fk_typed(
4675 "replica_id",
4676 "id",
4677 Cardinality::OneToOne,
4678 mz_repr::SemanticType::CatalogItemId,
4679 ),
4680 }]
4681 },
4682 column_semantic_types: &[("replica_id", SemanticType::ReplicaId)],
4683 }),
4684});
4685
4686pub static MZ_CLUSTER_REPLICA_UTILIZATION_HISTORY: LazyLock<BuiltinView> =
4687 LazyLock::new(|| BuiltinView {
4688 name: "mz_cluster_replica_utilization_history",
4689 schema: MZ_INTERNAL_SCHEMA,
4690 oid: oid::VIEW_MZ_CLUSTER_REPLICA_UTILIZATION_HISTORY_OID,
4691 desc: RelationDesc::builder()
4692 .with_column("replica_id", SqlScalarType::String.nullable(false))
4693 .with_column("process_id", SqlScalarType::UInt64.nullable(false))
4694 .with_column("cpu_percent", SqlScalarType::Float64.nullable(true))
4695 .with_column("memory_percent", SqlScalarType::Float64.nullable(true))
4696 .with_column("disk_percent", SqlScalarType::Float64.nullable(true))
4697 .with_column("heap_percent", SqlScalarType::Float64.nullable(true))
4698 .with_column(
4699 "occurred_at",
4700 SqlScalarType::TimestampTz { precision: None }.nullable(false),
4701 )
4702 .finish(),
4703 column_comments: BTreeMap::from_iter([
4704 ("replica_id", "The ID of a cluster replica."),
4705 ("process_id", "The ID of a process within the replica."),
4706 (
4707 "cpu_percent",
4708 "Approximate CPU usage, in percent of the total allocation.",
4709 ),
4710 (
4711 "memory_percent",
4712 "Approximate RAM usage, in percent of the total allocation.",
4713 ),
4714 (
4715 "disk_percent",
4716 "Approximate disk usage, in percent of the total allocation.",
4717 ),
4718 (
4719 "heap_percent",
4720 "Approximate heap (RAM + swap) usage, in percent of the total allocation.",
4721 ),
4722 (
4723 "occurred_at",
4724 "Wall-clock timestamp at which the event occurred.",
4725 ),
4726 ]),
4727 sql: "
4728SELECT
4729 r.id AS replica_id,
4730 m.process_id,
4731 m.cpu_nano_cores::float8 / NULLIF(s.cpu_nano_cores, 0) * 100 AS cpu_percent,
4732 m.memory_bytes::float8 / NULLIF(s.memory_bytes, 0) * 100 AS memory_percent,
4733 m.disk_bytes::float8 / NULLIF(s.disk_bytes, 0) * 100 AS disk_percent,
4734 m.heap_bytes::float8 / NULLIF(m.heap_limit, 0) * 100 AS heap_percent,
4735 m.occurred_at
4736FROM
4737 mz_catalog.mz_cluster_replicas AS r
4738 JOIN mz_catalog.mz_cluster_replica_sizes AS s ON r.size = s.size
4739 JOIN mz_internal.mz_cluster_replica_metrics_history AS m ON m.replica_id = r.id",
4740 access: vec![PUBLIC_SELECT],
4741 ontology: None,
4742 });
4743
4744pub static MZ_INDEX_ADVICE: LazyLock<BuiltinView> = LazyLock::new(|| {
4745 BuiltinView {
4746 name: "mz_index_advice",
4747 schema: MZ_INTERNAL_SCHEMA,
4748 oid: oid::VIEW_MZ_INDEX_ADVICE_OID,
4749 desc: RelationDesc::builder()
4750 .with_column("object_id", SqlScalarType::String.nullable(true))
4751 .with_column("hint", SqlScalarType::String.nullable(false))
4752 .with_column("details", SqlScalarType::String.nullable(false))
4753 .with_column("referenced_object_ids", SqlScalarType::List { element_type: Box::new(SqlScalarType::String), custom_id: None }.nullable(true))
4754 .finish(),
4755 column_comments: BTreeMap::from_iter([
4756 ("object_id", "The ID of the object. Corresponds to mz_objects.id."),
4757 ("hint", "A suggestion to either change the object (e.g. create an index, turn a materialized view into an indexed view) or keep the object unchanged."),
4758 ("details", "Additional details on why the `hint` was proposed based on the dependencies of the object."),
4759 ("referenced_object_ids", "The IDs of objects referenced by `details`. Corresponds to mz_objects.id."),
4760 ]),
4761 sql: "
4762-- To avoid confusion with sources and sinks in the materialize sense,
4763-- the following uses the terms leafs (instead of sinks) and roots (instead of sources)
4764-- when referring to the object dependency graph.
4765--
4766-- The basic idea is to walk up the dependency graph to propagate the transitive dependencies
4767-- of maintained objected upwards. The leaves of the dependency graph are maintained objects
4768-- that are not depended on by other maintained objects and have a justification why they must
4769-- be maintained (e.g. a materialized view that is depended on by a sink).
4770-- Starting from these leaves, the dependencies are propagated upwards towards the roots according
4771-- to the object dependencies. Whenever there is a node that is being depended on by multiple
4772-- downstream objects, that node is marked to be converted into a maintained object and this
4773-- node is then propagated further up. Once completed, the list of objects that are marked as
4774-- maintained is checked against all objects to generate appropriate recommendations.
4775--
4776-- Note that the recommendations only incorporate dependencies between objects.
4777-- This can lead to bad recommendations, e.g. filters can no longer be pushed into (or close to)
4778-- a sink if an index is added in between the sink and the filter. For very selective filters,
4779-- this can lead to redundant work: the index is computing stuff only to discarded by the selective
4780-- filter later on. But these kind of aspects cannot be understood by merely looking at the
4781-- dependencies.
4782WITH MUTUALLY RECURSIVE
4783 -- for all objects, understand if they have an index on them and on which cluster they are running
4784 -- this avoids having different cases for views with an index and materialized views later on
4785 objects(id text, type text, cluster_id text, indexes text list) AS (
4786 -- views and materialized views without an index
4787 SELECT
4788 o.id,
4789 o.type,
4790 o.cluster_id,
4791 '{}'::text list AS indexes
4792 FROM mz_catalog.mz_objects o
4793 WHERE o.id LIKE 'u%' AND o.type IN ('materialized-view', 'view') AND NOT EXISTS (
4794 SELECT FROM mz_internal.mz_object_dependencies d
4795 JOIN mz_catalog.mz_objects AS i
4796 ON (i.id = d.object_id AND i.type = 'index')
4797 WHERE (o.id = d.referenced_object_id)
4798 )
4799
4800 UNION ALL
4801
4802 -- views and materialized views with an index
4803 SELECT
4804 o.id,
4805 o.type,
4806 -- o.cluster_id is always NULL for views, so use the cluster of the index instead
4807 COALESCE(o.cluster_id, i.cluster_id) AS cluster_id,
4808 list_agg(i.id) AS indexes
4809 FROM mz_catalog.mz_objects o
4810 JOIN mz_internal.mz_object_dependencies AS d
4811 ON (o.id = d.referenced_object_id)
4812 JOIN mz_catalog.mz_objects AS i
4813 ON (i.id = d.object_id AND i.type = 'index')
4814 WHERE o.id LIKE 'u%' AND o.type IN ('materialized-view', 'view', 'source')
4815 GROUP BY o.id, o.type, o.cluster_id, i.cluster_id
4816 ),
4817
4818 -- maintained objects that are at the leafs of the dependency graph with respect to a specific cluster
4819 maintained_leafs(id text, justification text) AS (
4820 -- materialized views that are connected to a sink
4821 SELECT
4822 m.id,
4823 s.id AS justification
4824 FROM objects AS m
4825 JOIN mz_internal.mz_object_dependencies AS d
4826 ON (m.id = d.referenced_object_id)
4827 JOIN mz_catalog.mz_objects AS s
4828 ON (s.id = d.object_id AND s.type = 'sink')
4829 WHERE m.type = 'materialized-view'
4830
4831 UNION ALL
4832
4833 -- (materialized) views with an index that are not transitively depend on by maintained objects on the same cluster
4834 SELECT
4835 v.id,
4836 unnest(v.indexes) AS justification
4837 FROM objects AS v
4838 WHERE v.type IN ('view', 'materialized-view', 'source') AND NOT EXISTS (
4839 SELECT FROM mz_internal.mz_object_transitive_dependencies AS d
4840 INNER JOIN mz_catalog.mz_objects AS child
4841 ON (d.object_id = child.id)
4842 WHERE d.referenced_object_id = v.id AND child.type IN ('materialized-view', 'index') AND v.cluster_id = child.cluster_id AND NOT v.indexes @> LIST[child.id]
4843 )
4844 ),
4845
4846 -- this is just a helper cte to union multiple lists as part of an aggregation, which is not directly possible in SQL
4847 agg_maintained_children(id text, maintained_children text list) AS (
4848 SELECT
4849 parent_id AS id,
4850 list_agg(maintained_child) AS maintained_leafs
4851 FROM (
4852 SELECT DISTINCT
4853 d.referenced_object_id AS parent_id,
4854 -- it's not possible to union lists in an aggregation, so we have to unnest the list first
4855 unnest(child.maintained_children) AS maintained_child
4856 FROM propagate_dependencies AS child
4857 INNER JOIN mz_internal.mz_object_dependencies AS d
4858 ON (child.id = d.object_id)
4859 )
4860 GROUP BY parent_id
4861 ),
4862
4863 -- propagate dependencies of maintained objects from the leafs to the roots of the dependency graph and
4864 -- record a justification when an object should be maintained, e.g. when it is depended on by more than one maintained object
4865 -- when an object should be maintained, maintained_children will just contain that object so that further upstream objects refer to it in their maintained_children
4866 propagate_dependencies(id text, maintained_children text list, justification text list) AS (
4867 -- base case: start with the leafs
4868 SELECT DISTINCT
4869 id,
4870 LIST[id] AS maintained_children,
4871 list_agg(justification) AS justification
4872 FROM maintained_leafs
4873 GROUP BY id
4874
4875 UNION
4876
4877 -- recursive case: if there is a child with the same dependencies as the parent,
4878 -- the parent is only reused by a single child
4879 SELECT
4880 parent.id,
4881 child.maintained_children,
4882 NULL::text list AS justification
4883 FROM agg_maintained_children AS parent
4884 INNER JOIN mz_internal.mz_object_dependencies AS d
4885 ON (parent.id = d.referenced_object_id)
4886 INNER JOIN propagate_dependencies AS child
4887 ON (d.object_id = child.id)
4888 WHERE parent.maintained_children = child.maintained_children
4889
4890 UNION
4891
4892 -- recursive case: if there is NO child with the same dependencies as the parent,
4893 -- different children are reusing the parent so maintaining the object is justified by itself
4894 SELECT DISTINCT
4895 parent.id,
4896 LIST[parent.id] AS maintained_children,
4897 parent.maintained_children AS justification
4898 FROM agg_maintained_children AS parent
4899 WHERE NOT EXISTS (
4900 SELECT FROM mz_internal.mz_object_dependencies AS d
4901 INNER JOIN propagate_dependencies AS child
4902 ON (d.object_id = child.id AND d.referenced_object_id = parent.id)
4903 WHERE parent.maintained_children = child.maintained_children
4904 )
4905 ),
4906
4907 objects_with_justification(id text, type text, cluster_id text, maintained_children text list, justification text list, indexes text list) AS (
4908 SELECT
4909 p.id,
4910 o.type,
4911 o.cluster_id,
4912 p.maintained_children,
4913 p.justification,
4914 o.indexes
4915 FROM propagate_dependencies p
4916 JOIN objects AS o
4917 ON (p.id = o.id)
4918 ),
4919
4920 hints(id text, hint text, details text, justification text list) AS (
4921 -- materialized views that are not required
4922 SELECT
4923 id,
4924 'convert to a view' AS hint,
4925 'no dependencies from sinks nor from objects on different clusters' AS details,
4926 justification
4927 FROM objects_with_justification
4928 WHERE type = 'materialized-view' AND justification IS NULL
4929
4930 UNION ALL
4931
4932 -- materialized views that are required because a sink or a maintained object from a different cluster depends on them
4933 SELECT
4934 id,
4935 'keep' AS hint,
4936 'dependencies from sinks or objects on different clusters: ' AS details,
4937 justification
4938 FROM objects_with_justification AS m
4939 WHERE type = 'materialized-view' AND justification IS NOT NULL AND EXISTS (
4940 SELECT FROM unnest(justification) AS dependency
4941 JOIN mz_catalog.mz_objects s ON (s.type = 'sink' AND s.id = dependency)
4942
4943 UNION ALL
4944
4945 SELECT FROM unnest(justification) AS dependency
4946 JOIN mz_catalog.mz_objects AS d ON (d.id = dependency)
4947 WHERE d.cluster_id != m.cluster_id
4948 )
4949
4950 UNION ALL
4951
4952 -- materialized views that can be converted to a view with or without an index because NO sink or a maintained object from a different cluster depends on them
4953 SELECT
4954 id,
4955 'convert to a view with an index' AS hint,
4956 'no dependencies from sinks nor from objects on different clusters, but maintained dependencies on the same cluster: ' AS details,
4957 justification
4958 FROM objects_with_justification AS m
4959 WHERE type = 'materialized-view' AND justification IS NOT NULL AND NOT EXISTS (
4960 SELECT FROM unnest(justification) AS dependency
4961 JOIN mz_catalog.mz_objects s ON (s.type = 'sink' AND s.id = dependency)
4962
4963 UNION ALL
4964
4965 SELECT FROM unnest(justification) AS dependency
4966 JOIN mz_catalog.mz_objects AS d ON (d.id = dependency)
4967 WHERE d.cluster_id != m.cluster_id
4968 )
4969
4970 UNION ALL
4971
4972 -- views that have indexes on different clusters should be a materialized view
4973 SELECT
4974 o.id,
4975 'convert to materialized view' AS hint,
4976 'dependencies on multiple clusters: ' AS details,
4977 o.justification
4978 FROM objects_with_justification o,
4979 LATERAL unnest(o.justification) j
4980 LEFT JOIN mz_catalog.mz_objects AS m
4981 ON (m.id = j AND m.type IN ('index', 'materialized-view'))
4982 WHERE o.type = 'view' AND o.justification IS NOT NULL
4983 GROUP BY o.id, o.justification
4984 HAVING count(DISTINCT m.cluster_id) >= 2
4985
4986 UNION ALL
4987
4988 -- views without an index that should be maintained
4989 SELECT
4990 id,
4991 'add index' AS hint,
4992 'multiple downstream dependencies: ' AS details,
4993 justification
4994 FROM objects_with_justification
4995 WHERE type = 'view' AND justification IS NOT NULL AND indexes = '{}'::text list
4996
4997 UNION ALL
4998
4999 -- index inside the dependency graph (not a leaf)
5000 SELECT
5001 unnest(indexes) AS id,
5002 'drop unless queried directly' AS hint,
5003 'fewer than two downstream dependencies: ' AS details,
5004 maintained_children AS justification
5005 FROM objects_with_justification
5006 WHERE type = 'view' AND NOT indexes = '{}'::text list AND justification IS NULL
5007
5008 UNION ALL
5009
5010 -- index on a leaf of the dependency graph
5011 SELECT
5012 unnest(indexes) AS id,
5013 'drop unless queried directly' AS hint,
5014 'associated object does not have any dependencies (maintained or not maintained)' AS details,
5015 NULL::text list AS justification
5016 FROM objects_with_justification
5017 -- indexes can only be part of justification for leaf nodes
5018 WHERE type IN ('view', 'materialized-view') AND NOT indexes = '{}'::text list AND justification @> indexes
5019
5020 UNION ALL
5021
5022 -- index on a source
5023 SELECT
5024 unnest(indexes) AS id,
5025 'drop unless queried directly' AS hint,
5026 'sources do not transform data and can expose data directly' AS details,
5027 NULL::text list AS justification
5028 FROM objects_with_justification
5029 -- indexes can only be part of justification for leaf nodes
5030 WHERE type = 'source' AND NOT indexes = '{}'::text list
5031
5032 UNION ALL
5033
5034 -- indexes on views inside the dependency graph
5035 SELECT
5036 unnest(indexes) AS id,
5037 'keep' AS hint,
5038 'multiple downstream dependencies: ' AS details,
5039 justification
5040 FROM objects_with_justification
5041 -- indexes can only be part of justification for leaf nodes
5042 WHERE type = 'view' AND justification IS NOT NULL AND NOT indexes = '{}'::text list AND NOT justification @> indexes
5043 ),
5044
5045 hints_resolved_ids(id text, hint text, details text, justification text list) AS (
5046 SELECT
5047 h.id,
5048 h.hint,
5049 h.details || list_agg(o.name)::text AS details,
5050 h.justification
5051 FROM hints AS h,
5052 LATERAL unnest(h.justification) j
5053 JOIN mz_catalog.mz_objects AS o
5054 ON (o.id = j)
5055 GROUP BY h.id, h.hint, h.details, h.justification
5056
5057 UNION ALL
5058
5059 SELECT
5060 id,
5061 hint,
5062 details,
5063 justification
5064 FROM hints
5065 WHERE justification IS NULL
5066 )
5067
5068SELECT
5069 h.id AS object_id,
5070 h.hint AS hint,
5071 h.details,
5072 h.justification AS referenced_object_ids
5073FROM hints_resolved_ids AS h",
5074 access: vec![PUBLIC_SELECT],
5075 ontology: None,
5076 }
5077});
5078
5079pub static PG_AUTHID_CORE: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5082 name: "pg_authid_core",
5083 schema: MZ_INTERNAL_SCHEMA,
5084 oid: oid::VIEW_PG_AUTHID_CORE_OID,
5085 desc: RelationDesc::builder()
5086 .with_column("oid", SqlScalarType::Oid.nullable(false))
5087 .with_column("rolname", SqlScalarType::String.nullable(false))
5088 .with_column("rolsuper", SqlScalarType::Bool.nullable(true))
5089 .with_column("rolinherit", SqlScalarType::Bool.nullable(false))
5090 .with_column("rolcanlogin", SqlScalarType::Bool.nullable(false))
5091 .with_column("rolreplication", SqlScalarType::Bool.nullable(false))
5092 .with_column("rolbypassrls", SqlScalarType::Bool.nullable(false))
5093 .with_column("rolconnlimit", SqlScalarType::Int32.nullable(false))
5094 .with_column("rolpassword", SqlScalarType::String.nullable(true))
5095 .with_column(
5096 "rolvaliduntil",
5097 SqlScalarType::TimestampTz { precision: None }.nullable(true),
5098 )
5099 .finish(),
5100 column_comments: BTreeMap::new(),
5101 sql: r#"
5102SELECT
5103 r.oid AS oid,
5104 r.name AS rolname,
5105 rolsuper,
5106 inherit AS rolinherit,
5107 COALESCE(r.rolcanlogin, false) AS rolcanlogin,
5108 -- MZ doesn't support replication in the same way Postgres does
5109 false AS rolreplication,
5110 -- MZ doesn't how row level security
5111 false AS rolbypassrls,
5112 -- MZ doesn't have a connection limit
5113 -1 AS rolconnlimit,
5114 a.password_hash AS rolpassword,
5115 NULL::pg_catalog.timestamptz AS rolvaliduntil
5116FROM mz_catalog.mz_roles r
5117LEFT JOIN mz_catalog.mz_role_auth a ON r.oid = a.role_oid"#,
5118 access: vec![rbac::owner_privilege(ObjectType::Table, MZ_SYSTEM_ROLE_ID)],
5119 ontology: None,
5120});
5121
5122pub const PG_AUTHID_CORE_IND: BuiltinIndex = BuiltinIndex {
5123 name: "pg_authid_core_ind",
5124 schema: MZ_INTERNAL_SCHEMA,
5125 oid: oid::INDEX_PG_AUTHID_CORE_IND_OID,
5126 sql: "IN CLUSTER mz_catalog_server
5127ON mz_internal.pg_authid_core (rolname)",
5128 is_retained_metrics_object: false,
5129};
5130
5131pub static MZ_SHOW_ALL_OBJECTS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5132 name: "mz_show_all_objects",
5133 schema: MZ_INTERNAL_SCHEMA,
5134 oid: oid::VIEW_MZ_SHOW_ALL_OBJECTS_OID,
5135 desc: RelationDesc::builder()
5136 .with_column("schema_id", SqlScalarType::String.nullable(false))
5137 .with_column("name", SqlScalarType::String.nullable(false))
5138 .with_column("type", SqlScalarType::String.nullable(false))
5139 .with_column("comment", SqlScalarType::String.nullable(false))
5140 .finish(),
5141 column_comments: BTreeMap::new(),
5142 sql: "WITH comments AS (
5143 SELECT id, object_type, comment
5144 FROM mz_internal.mz_comments
5145 WHERE object_sub_id IS NULL
5146 )
5147 SELECT schema_id, name, type, COALESCE(comment, '') AS comment
5148 FROM mz_catalog.mz_objects AS objs
5149 LEFT JOIN comments ON objs.id = comments.id
5150 WHERE (comments.object_type = objs.type OR comments.object_type IS NULL)",
5151 access: vec![PUBLIC_SELECT],
5152 ontology: None,
5153});
5154
5155pub static MZ_SHOW_CLUSTERS: LazyLock<BuiltinView> = LazyLock::new(|| {
5156 BuiltinView {
5157 name: "mz_show_clusters",
5158 schema: MZ_INTERNAL_SCHEMA,
5159 oid: oid::VIEW_MZ_SHOW_CLUSTERS_OID,
5160 desc: RelationDesc::builder()
5161 .with_column("name", SqlScalarType::String.nullable(false))
5162 .with_column("replicas", SqlScalarType::String.nullable(true))
5163 .with_column("comment", SqlScalarType::String.nullable(false))
5164 .finish(),
5165 column_comments: BTreeMap::new(),
5166 sql: "
5167 WITH clusters AS (
5168 SELECT
5169 mc.id,
5170 mc.name,
5171 pg_catalog.string_agg(mcr.name || ' (' || mcr.size || ')', ', ' ORDER BY mcr.name) AS replicas
5172 FROM mz_catalog.mz_clusters mc
5173 LEFT JOIN mz_catalog.mz_cluster_replicas mcr
5174 ON mc.id = mcr.cluster_id
5175 GROUP BY mc.id, mc.name
5176 ),
5177 comments AS (
5178 SELECT id, comment
5179 FROM mz_internal.mz_comments
5180 WHERE object_type = 'cluster' AND object_sub_id IS NULL
5181 )
5182 SELECT name, replicas, COALESCE(comment, '') as comment
5183 FROM clusters
5184 LEFT JOIN comments ON clusters.id = comments.id",
5185 access: vec![PUBLIC_SELECT],
5186 ontology: None,
5187}
5188});
5189
5190pub static MZ_SHOW_SECRETS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5191 name: "mz_show_secrets",
5192 schema: MZ_INTERNAL_SCHEMA,
5193 oid: oid::VIEW_MZ_SHOW_SECRETS_OID,
5194 desc: RelationDesc::builder()
5195 .with_column("schema_id", SqlScalarType::String.nullable(false))
5196 .with_column("name", SqlScalarType::String.nullable(false))
5197 .with_column("comment", SqlScalarType::String.nullable(false))
5198 .finish(),
5199 column_comments: BTreeMap::new(),
5200 sql: "WITH comments AS (
5201 SELECT id, comment
5202 FROM mz_internal.mz_comments
5203 WHERE object_type = 'secret' AND object_sub_id IS NULL
5204 )
5205 SELECT schema_id, name, COALESCE(comment, '') as comment
5206 FROM mz_catalog.mz_secrets secrets
5207 LEFT JOIN comments ON secrets.id = comments.id",
5208 access: vec![PUBLIC_SELECT],
5209 ontology: None,
5210});
5211
5212pub static MZ_SHOW_COLUMNS: LazyLock<BuiltinView> = LazyLock::new(|| {
5213 BuiltinView {
5214 name: "mz_show_columns",
5215 schema: MZ_INTERNAL_SCHEMA,
5216 oid: oid::VIEW_MZ_SHOW_COLUMNS_OID,
5217 desc: RelationDesc::builder()
5218 .with_column("id", SqlScalarType::String.nullable(false))
5219 .with_column("name", SqlScalarType::String.nullable(false))
5220 .with_column("nullable", SqlScalarType::Bool.nullable(false))
5221 .with_column("type", SqlScalarType::String.nullable(false))
5222 .with_column("position", SqlScalarType::UInt64.nullable(false))
5223 .with_column("comment", SqlScalarType::String.nullable(false))
5224 .finish(),
5225 column_comments: BTreeMap::new(),
5226 sql: "
5232 SELECT columns.id, columns.name, columns.nullable, columns.type, columns.position, COALESCE(comment, '') as comment
5233 FROM mz_catalog.mz_columns columns
5234 LEFT JOIN mz_catalog.mz_objects obj ON obj.id = columns.id
5235 LEFT JOIN mz_internal.mz_comments comments
5236 ON columns.id = comments.id
5237 AND columns.position = comments.object_sub_id
5238 AND comments.object_type = obj.type",
5239 access: vec![PUBLIC_SELECT],
5240 ontology: None,
5241}
5242});
5243
5244pub static MZ_SHOW_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5245 name: "mz_show_databases",
5246 schema: MZ_INTERNAL_SCHEMA,
5247 oid: oid::VIEW_MZ_SHOW_DATABASES_OID,
5248 desc: RelationDesc::builder()
5249 .with_column("name", SqlScalarType::String.nullable(false))
5250 .with_column("comment", SqlScalarType::String.nullable(false))
5251 .finish(),
5252 column_comments: BTreeMap::new(),
5253 sql: "WITH comments AS (
5254 SELECT id, comment
5255 FROM mz_internal.mz_comments
5256 WHERE object_type = 'database' AND object_sub_id IS NULL
5257 )
5258 SELECT name, COALESCE(comment, '') as comment
5259 FROM mz_catalog.mz_databases databases
5260 LEFT JOIN comments ON databases.id = comments.id",
5261 access: vec![PUBLIC_SELECT],
5262 ontology: None,
5263});
5264
5265pub static MZ_SHOW_SCHEMAS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5266 name: "mz_show_schemas",
5267 schema: MZ_INTERNAL_SCHEMA,
5268 oid: oid::VIEW_MZ_SHOW_SCHEMAS_OID,
5269 desc: RelationDesc::builder()
5270 .with_column("database_id", SqlScalarType::String.nullable(true))
5271 .with_column("name", SqlScalarType::String.nullable(false))
5272 .with_column("comment", SqlScalarType::String.nullable(false))
5273 .finish(),
5274 column_comments: BTreeMap::new(),
5275 sql: "WITH comments AS (
5276 SELECT id, comment
5277 FROM mz_internal.mz_comments
5278 WHERE object_type = 'schema' AND object_sub_id IS NULL
5279 )
5280 SELECT database_id, name, COALESCE(comment, '') as comment
5281 FROM mz_catalog.mz_schemas schemas
5282 LEFT JOIN comments ON schemas.id = comments.id",
5283 access: vec![PUBLIC_SELECT],
5284 ontology: None,
5285});
5286
5287pub static MZ_SHOW_ROLES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5288 name: "mz_show_roles",
5289 schema: MZ_INTERNAL_SCHEMA,
5290 oid: oid::VIEW_MZ_SHOW_ROLES_OID,
5291 desc: RelationDesc::builder()
5292 .with_column("name", SqlScalarType::String.nullable(false))
5293 .with_column("comment", SqlScalarType::String.nullable(false))
5294 .finish(),
5295 column_comments: BTreeMap::new(),
5296 sql: "WITH comments AS (
5297 SELECT id, comment
5298 FROM mz_internal.mz_comments
5299 WHERE object_type = 'role' AND object_sub_id IS NULL
5300 )
5301 SELECT name, COALESCE(comment, '') as comment
5302 FROM mz_catalog.mz_roles roles
5303 LEFT JOIN comments ON roles.id = comments.id
5304 WHERE roles.id NOT LIKE 's%'
5305 AND roles.id NOT LIKE 'g%'",
5306 access: vec![PUBLIC_SELECT],
5307 ontology: None,
5308});
5309
5310pub static MZ_SHOW_TABLES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5311 name: "mz_show_tables",
5312 schema: MZ_INTERNAL_SCHEMA,
5313 oid: oid::VIEW_MZ_SHOW_TABLES_OID,
5314 desc: RelationDesc::builder()
5315 .with_column("schema_id", SqlScalarType::String.nullable(false))
5316 .with_column("name", SqlScalarType::String.nullable(false))
5317 .with_column("comment", SqlScalarType::String.nullable(false))
5318 .with_column("source_id", SqlScalarType::String.nullable(true))
5319 .finish(),
5320 column_comments: BTreeMap::new(),
5321 sql: "WITH comments AS (
5322 SELECT id, comment
5323 FROM mz_internal.mz_comments
5324 WHERE object_type = 'table' AND object_sub_id IS NULL
5325 )
5326 SELECT schema_id, name, COALESCE(comment, '') as comment, source_id
5327 FROM mz_catalog.mz_tables tables
5328 LEFT JOIN comments ON tables.id = comments.id",
5329 access: vec![PUBLIC_SELECT],
5330 ontology: None,
5331});
5332
5333pub static MZ_SHOW_VIEWS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5334 name: "mz_show_views",
5335 schema: MZ_INTERNAL_SCHEMA,
5336 oid: oid::VIEW_MZ_SHOW_VIEWS_OID,
5337 desc: RelationDesc::builder()
5338 .with_column("schema_id", SqlScalarType::String.nullable(false))
5339 .with_column("name", SqlScalarType::String.nullable(false))
5340 .with_column("comment", SqlScalarType::String.nullable(false))
5341 .finish(),
5342 column_comments: BTreeMap::new(),
5343 sql: "WITH comments AS (
5344 SELECT id, comment
5345 FROM mz_internal.mz_comments
5346 WHERE object_type = 'view' AND object_sub_id IS NULL
5347 )
5348 SELECT schema_id, name, COALESCE(comment, '') as comment
5349 FROM mz_catalog.mz_views views
5350 LEFT JOIN comments ON views.id = comments.id",
5351 access: vec![PUBLIC_SELECT],
5352 ontology: None,
5353});
5354
5355pub static MZ_SHOW_TYPES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5356 name: "mz_show_types",
5357 schema: MZ_INTERNAL_SCHEMA,
5358 oid: oid::VIEW_MZ_SHOW_TYPES_OID,
5359 desc: RelationDesc::builder()
5360 .with_column("schema_id", SqlScalarType::String.nullable(false))
5361 .with_column("name", SqlScalarType::String.nullable(false))
5362 .with_column("comment", SqlScalarType::String.nullable(false))
5363 .finish(),
5364 column_comments: BTreeMap::new(),
5365 sql: "WITH comments AS (
5366 SELECT id, comment
5367 FROM mz_internal.mz_comments
5368 WHERE object_type = 'type' AND object_sub_id IS NULL
5369 )
5370 SELECT schema_id, name, COALESCE(comment, '') as comment
5371 FROM mz_catalog.mz_types types
5372 LEFT JOIN comments ON types.id = comments.id",
5373 access: vec![PUBLIC_SELECT],
5374 ontology: None,
5375});
5376
5377pub static MZ_SHOW_CONNECTIONS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5378 name: "mz_show_connections",
5379 schema: MZ_INTERNAL_SCHEMA,
5380 oid: oid::VIEW_MZ_SHOW_CONNECTIONS_OID,
5381 desc: RelationDesc::builder()
5382 .with_column("schema_id", SqlScalarType::String.nullable(false))
5383 .with_column("name", SqlScalarType::String.nullable(false))
5384 .with_column("type", SqlScalarType::String.nullable(false))
5385 .with_column("comment", SqlScalarType::String.nullable(false))
5386 .finish(),
5387 column_comments: BTreeMap::new(),
5388 sql: "WITH comments AS (
5389 SELECT id, comment
5390 FROM mz_internal.mz_comments
5391 WHERE object_type = 'connection' AND object_sub_id IS NULL
5392 )
5393 SELECT schema_id, name, type, COALESCE(comment, '') as comment
5394 FROM mz_catalog.mz_connections connections
5395 LEFT JOIN comments ON connections.id = comments.id",
5396 access: vec![PUBLIC_SELECT],
5397 ontology: None,
5398});
5399
5400pub static MZ_SHOW_SOURCES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5401 name: "mz_show_sources",
5402 schema: MZ_INTERNAL_SCHEMA,
5403 oid: oid::VIEW_MZ_SHOW_SOURCES_OID,
5404 desc: RelationDesc::builder()
5405 .with_column("id", SqlScalarType::String.nullable(false))
5406 .with_column("name", SqlScalarType::String.nullable(false))
5407 .with_column("type", SqlScalarType::String.nullable(false))
5408 .with_column("cluster", SqlScalarType::String.nullable(true))
5409 .with_column("schema_id", SqlScalarType::String.nullable(false))
5410 .with_column("cluster_id", SqlScalarType::String.nullable(true))
5411 .with_column("comment", SqlScalarType::String.nullable(false))
5412 .finish(),
5413 column_comments: BTreeMap::new(),
5414 sql: "
5415WITH comments AS (
5416 SELECT id, comment
5417 FROM mz_internal.mz_comments
5418 WHERE object_type = 'source' AND object_sub_id IS NULL
5419)
5420SELECT
5421 sources.id,
5422 sources.name,
5423 sources.type,
5424 clusters.name AS cluster,
5425 schema_id,
5426 cluster_id,
5427 COALESCE(comments.comment, '') as comment
5428FROM
5429 mz_catalog.mz_sources AS sources
5430 LEFT JOIN
5431 mz_catalog.mz_clusters AS clusters
5432 ON clusters.id = sources.cluster_id
5433 LEFT JOIN comments ON sources.id = comments.id",
5434 access: vec![PUBLIC_SELECT],
5435 ontology: None,
5436});
5437
5438pub static MZ_SHOW_SINKS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5439 name: "mz_show_sinks",
5440 schema: MZ_INTERNAL_SCHEMA,
5441 oid: oid::VIEW_MZ_SHOW_SINKS_OID,
5442 desc: RelationDesc::builder()
5443 .with_column("id", SqlScalarType::String.nullable(false))
5444 .with_column("name", SqlScalarType::String.nullable(false))
5445 .with_column("type", SqlScalarType::String.nullable(false))
5446 .with_column("cluster", SqlScalarType::String.nullable(false))
5447 .with_column("schema_id", SqlScalarType::String.nullable(false))
5448 .with_column("cluster_id", SqlScalarType::String.nullable(false))
5449 .with_column("comment", SqlScalarType::String.nullable(false))
5450 .finish(),
5451 column_comments: BTreeMap::new(),
5452 sql: "
5453WITH comments AS (
5454 SELECT id, comment
5455 FROM mz_internal.mz_comments
5456 WHERE object_type = 'sink' AND object_sub_id IS NULL
5457)
5458SELECT
5459 sinks.id,
5460 sinks.name,
5461 sinks.type,
5462 clusters.name AS cluster,
5463 schema_id,
5464 cluster_id,
5465 COALESCE(comments.comment, '') as comment
5466FROM
5467 mz_catalog.mz_sinks AS sinks
5468 JOIN
5469 mz_catalog.mz_clusters AS clusters
5470 ON clusters.id = sinks.cluster_id
5471 LEFT JOIN comments ON sinks.id = comments.id",
5472 access: vec![PUBLIC_SELECT],
5473 ontology: None,
5474});
5475
5476pub static MZ_SHOW_MATERIALIZED_VIEWS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5477 name: "mz_show_materialized_views",
5478 schema: MZ_INTERNAL_SCHEMA,
5479 oid: oid::VIEW_MZ_SHOW_MATERIALIZED_VIEWS_OID,
5480 desc: RelationDesc::builder()
5481 .with_column("id", SqlScalarType::String.nullable(false))
5482 .with_column("name", SqlScalarType::String.nullable(false))
5483 .with_column("cluster", SqlScalarType::String.nullable(false))
5484 .with_column("schema_id", SqlScalarType::String.nullable(false))
5485 .with_column("cluster_id", SqlScalarType::String.nullable(false))
5486 .with_column("comment", SqlScalarType::String.nullable(false))
5487 .finish(),
5488 column_comments: BTreeMap::new(),
5489 sql: "
5490WITH
5491 comments AS (
5492 SELECT id, comment
5493 FROM mz_internal.mz_comments
5494 WHERE object_type = 'materialized-view' AND object_sub_id IS NULL
5495 )
5496SELECT
5497 mviews.id as id,
5498 mviews.name,
5499 clusters.name AS cluster,
5500 schema_id,
5501 cluster_id,
5502 COALESCE(comments.comment, '') as comment
5503FROM
5504 mz_catalog.mz_materialized_views AS mviews
5505 JOIN mz_catalog.mz_clusters AS clusters ON clusters.id = mviews.cluster_id
5506 LEFT JOIN comments ON mviews.id = comments.id",
5507 access: vec![PUBLIC_SELECT],
5508 ontology: None,
5509});
5510
5511pub static MZ_SHOW_INDEXES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5512 name: "mz_show_indexes",
5513 schema: MZ_INTERNAL_SCHEMA,
5514 oid: oid::VIEW_MZ_SHOW_INDEXES_OID,
5515 desc: RelationDesc::builder()
5516 .with_column("id", SqlScalarType::String.nullable(false))
5517 .with_column("name", SqlScalarType::String.nullable(false))
5518 .with_column("on", SqlScalarType::String.nullable(false))
5519 .with_column("cluster", SqlScalarType::String.nullable(false))
5520 .with_column(
5521 "key",
5522 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
5523 )
5524 .with_column("on_id", SqlScalarType::String.nullable(false))
5525 .with_column("schema_id", SqlScalarType::String.nullable(false))
5526 .with_column("cluster_id", SqlScalarType::String.nullable(false))
5527 .with_column("comment", SqlScalarType::String.nullable(false))
5528 .finish(),
5529 column_comments: BTreeMap::new(),
5530 sql: "
5531WITH comments AS (
5532 SELECT id, comment
5533 FROM mz_internal.mz_comments
5534 WHERE object_type = 'index' AND object_sub_id IS NULL
5535)
5536SELECT
5537 idxs.id AS id,
5538 idxs.name AS name,
5539 objs.name AS on,
5540 clusters.name AS cluster,
5541 COALESCE(keys.key, '{}'::_text) AS key,
5542 idxs.on_id AS on_id,
5543 objs.schema_id AS schema_id,
5544 clusters.id AS cluster_id,
5545 COALESCE(comments.comment, '') as comment
5546FROM
5547 mz_catalog.mz_indexes AS idxs
5548 JOIN mz_catalog.mz_objects AS objs ON idxs.on_id = objs.id
5549 JOIN mz_catalog.mz_clusters AS clusters ON clusters.id = idxs.cluster_id
5550 LEFT JOIN
5551 (SELECT
5552 idxs.id,
5553 ARRAY_AGG(
5554 CASE
5555 WHEN idx_cols.on_expression IS NULL THEN obj_cols.name
5556 ELSE idx_cols.on_expression
5557 END
5558 ORDER BY idx_cols.index_position ASC
5559 ) AS key
5560 FROM
5561 mz_catalog.mz_indexes AS idxs
5562 JOIN mz_catalog.mz_index_columns idx_cols ON idxs.id = idx_cols.index_id
5563 LEFT JOIN mz_catalog.mz_columns obj_cols ON
5564 idxs.on_id = obj_cols.id AND idx_cols.on_position = obj_cols.position
5565 GROUP BY idxs.id) AS keys
5566 ON idxs.id = keys.id
5567 LEFT JOIN comments ON idxs.id = comments.id",
5568 access: vec![PUBLIC_SELECT],
5569 ontology: None,
5570});
5571
5572pub static MZ_SHOW_CLUSTER_REPLICAS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5573 name: "mz_show_cluster_replicas",
5574 schema: MZ_INTERNAL_SCHEMA,
5575 oid: oid::VIEW_MZ_SHOW_CLUSTER_REPLICAS_OID,
5576 desc: RelationDesc::builder()
5577 .with_column("cluster", SqlScalarType::String.nullable(false))
5578 .with_column("replica", SqlScalarType::String.nullable(false))
5579 .with_column("replica_id", SqlScalarType::String.nullable(false))
5580 .with_column("size", SqlScalarType::String.nullable(true))
5581 .with_column("ready", SqlScalarType::Bool.nullable(false))
5582 .with_column("comment", SqlScalarType::String.nullable(false))
5583 .finish(),
5584 column_comments: BTreeMap::new(),
5585 sql: r#"SELECT
5586 mz_catalog.mz_clusters.name AS cluster,
5587 mz_catalog.mz_cluster_replicas.name AS replica,
5588 mz_catalog.mz_cluster_replicas.id as replica_id,
5589 mz_catalog.mz_cluster_replicas.size AS size,
5590 coalesce(statuses.ready, FALSE) AS ready,
5591 coalesce(comments.comment, '') as comment
5592FROM
5593 mz_catalog.mz_cluster_replicas
5594 JOIN mz_catalog.mz_clusters
5595 ON mz_catalog.mz_cluster_replicas.cluster_id = mz_catalog.mz_clusters.id
5596 LEFT JOIN
5597 (
5598 SELECT
5599 replica_id,
5600 bool_and(hydrated) AS ready
5601 FROM mz_internal.mz_hydration_statuses
5602 WHERE replica_id is not null
5603 GROUP BY replica_id
5604 ) AS statuses
5605 ON mz_catalog.mz_cluster_replicas.id = statuses.replica_id
5606 LEFT JOIN mz_internal.mz_comments comments
5607 ON mz_catalog.mz_cluster_replicas.id = comments.id
5608WHERE (comments.object_type = 'cluster-replica' OR comments.object_type IS NULL)
5609ORDER BY 1, 2"#,
5610 access: vec![PUBLIC_SELECT],
5611 ontology: None,
5612});
5613
5614pub static MZ_MCP_DATA_PRODUCTS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5623 name: "mz_mcp_data_products",
5624 schema: MZ_INTERNAL_SCHEMA,
5625 oid: oid::VIEW_MZ_MCP_DATA_PRODUCTS_OID,
5626 desc: RelationDesc::builder()
5627 .with_column("object_name", SqlScalarType::String.nullable(false))
5628 .with_column("cluster", SqlScalarType::String.nullable(true))
5629 .with_column("description", SqlScalarType::String.nullable(true))
5630 .with_key(vec![0, 1, 2])
5631 .finish(),
5632 column_comments: BTreeMap::from_iter([
5633 (
5634 "object_name",
5635 "Fully qualified object name (database.schema.name).",
5636 ),
5637 (
5638 "cluster",
5639 "Cluster where the object computes or its index is hosted. Reads from any cluster work, but only reads on this cluster benefit from the index.",
5640 ),
5641 (
5642 "description",
5643 "Index comment if available, otherwise object comment. Used as data product description.",
5644 ),
5645 ]),
5646 sql: r#"
5647SELECT DISTINCT
5648 '"' || op.database || '"."' || op.schema || '"."' || op.name || '"' AS object_name,
5649 COALESCE(c_idx.name, c_obj.name) AS cluster,
5650 COALESCE(cts_idx.comment, cts_obj.comment) AS description
5651FROM mz_internal.mz_show_my_object_privileges op
5652JOIN mz_objects o ON op.name = o.name AND op.object_type = o.type
5653JOIN mz_schemas s ON s.name = op.schema AND s.id = o.schema_id
5654JOIN mz_databases d ON d.name = op.database AND d.id = s.database_id
5655LEFT JOIN mz_indexes i ON i.on_id = o.id
5656LEFT JOIN mz_clusters c_idx ON c_idx.id = i.cluster_id
5657LEFT JOIN mz_clusters c_obj ON c_obj.id = o.cluster_id
5658LEFT JOIN mz_internal.mz_comments cts_idx ON cts_idx.id = i.id AND cts_idx.object_sub_id IS NULL
5659LEFT JOIN mz_internal.mz_comments cts_obj ON cts_obj.id = o.id AND cts_obj.object_sub_id IS NULL
5660WHERE op.privilege_type = 'SELECT'
5661 AND (o.type = 'materialized-view' OR (o.type = 'view' AND i.id IS NOT NULL))
5662 AND s.name NOT IN ('mz_catalog', 'mz_internal', 'pg_catalog', 'information_schema', 'mz_introspection')
5663"#,
5664 access: vec![PUBLIC_SELECT],
5665 ontology: None,
5666});
5667
5668pub static MZ_MCP_DATA_PRODUCT_DETAILS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5677 name: "mz_mcp_data_product_details",
5678 schema: MZ_INTERNAL_SCHEMA,
5679 oid: oid::VIEW_MZ_MCP_DATA_PRODUCT_DETAILS_OID,
5680 desc: RelationDesc::builder()
5687 .with_column("object_name", SqlScalarType::String.nullable(false))
5688 .with_column("cluster", SqlScalarType::String.nullable(true))
5689 .with_column("description", SqlScalarType::String.nullable(true))
5690 .with_column("schema", SqlScalarType::Jsonb.nullable(false))
5691 .with_column("hydration", SqlScalarType::Jsonb.nullable(false))
5692 .finish(),
5693 column_comments: BTreeMap::from_iter([
5694 (
5695 "object_name",
5696 "Fully qualified object name (database.schema.name).",
5697 ),
5698 (
5699 "cluster",
5700 "Cluster where the object computes or its index is hosted. Reads from any cluster work, but only reads on this cluster benefit from the index.",
5701 ),
5702 (
5703 "description",
5704 "Index comment if available, otherwise object comment. Used as data product description.",
5705 ),
5706 (
5707 "schema",
5708 "JSON Schema describing the object's columns and types.",
5709 ),
5710 (
5711 "hydration",
5712 "Readiness summary as a JSON object with `hydrated` (bool), `replica_count` (int), and `hydrated_replica_count` (int). `hydrated` is true only when the cluster has at least one replica and the dataflow is hydrated on every replica. Reads against a non-hydrated data product block until the dataflow catches up (they never return partial data). Check this before reading: if `hydrated` is false and `replica_count > 0`, wait and retry; if `replica_count` is 0, the cluster has no replicas and that needs operator action, not a retry.",
5713 ),
5714 ]),
5715 sql: r#"
5716WITH details_raw AS (
5717 SELECT
5718 '"' || op.database || '"."' || op.schema || '"."' || op.name || '"' AS object_name,
5719 COALESCE(c_idx.name, c_obj.name) AS cluster,
5720 COALESCE(cts_idx.comment, cts_obj.comment) AS description,
5721 COALESCE(jsonb_build_object(
5722 'type', 'object',
5723 'indexedColumns', jsonb_agg(distinct ccol.name) FILTER (WHERE ccol.position = ic.on_position),
5724 'properties', jsonb_strip_nulls(jsonb_object_agg(
5725 ccol.name,
5726 CASE
5727 WHEN ccol.type IN (
5728 'uint2', 'uint4','uint8', 'int', 'integer', 'smallint',
5729 'double', 'double precision', 'bigint', 'float',
5730 'numeric', 'real'
5731 ) THEN jsonb_build_object(
5732 'type', 'number',
5733 'description', cts_col.comment
5734 )
5735 WHEN ccol.type = 'boolean' THEN jsonb_build_object(
5736 'type', 'boolean',
5737 'description', cts_col.comment
5738 )
5739 WHEN ccol.type = 'bytea' THEN jsonb_build_object(
5740 'type', 'string',
5741 'description', cts_col.comment,
5742 'contentEncoding', 'base64',
5743 'contentMediaType', 'application/octet-stream'
5744 )
5745 WHEN ccol.type = 'date' THEN jsonb_build_object(
5746 'type', 'string',
5747 'format', 'date',
5748 'description', cts_col.comment
5749 )
5750 WHEN ccol.type = 'time' THEN jsonb_build_object(
5751 'type', 'string',
5752 'format', 'time',
5753 'description', cts_col.comment
5754 )
5755 WHEN ccol.type ilike 'timestamp%%' THEN jsonb_build_object(
5756 'type', 'string',
5757 'format', 'date-time',
5758 'description', cts_col.comment
5759 )
5760 WHEN ccol.type = 'jsonb' THEN jsonb_build_object(
5761 'type', 'object',
5762 'description', cts_col.comment
5763 )
5764 WHEN ccol.type = 'uuid' THEN jsonb_build_object(
5765 'type', 'string',
5766 'format', 'uuid',
5767 'description', cts_col.comment
5768 )
5769 ELSE jsonb_build_object(
5770 'type', 'string',
5771 'description', cts_col.comment
5772 )
5773 END
5774 ))
5775 ), '{"type": "object", "properties": {}}'::jsonb) AS schema
5776FROM mz_internal.mz_show_my_object_privileges op
5777JOIN mz_objects o ON op.name = o.name AND op.object_type = o.type
5778JOIN mz_schemas s ON s.name = op.schema AND s.id = o.schema_id
5779JOIN mz_databases d ON d.name = op.database AND d.id = s.database_id
5780JOIN mz_columns ccol ON ccol.id = o.id
5781LEFT JOIN mz_indexes i ON i.on_id = o.id
5782LEFT JOIN mz_index_columns ic ON i.id = ic.index_id
5783LEFT JOIN mz_clusters c_idx ON c_idx.id = i.cluster_id
5784LEFT JOIN mz_clusters c_obj ON c_obj.id = o.cluster_id
5785LEFT JOIN mz_internal.mz_comments cts_idx ON cts_idx.id = i.id AND cts_idx.object_sub_id IS NULL
5786LEFT JOIN mz_internal.mz_comments cts_obj ON cts_obj.id = o.id AND cts_obj.object_sub_id IS NULL
5787LEFT JOIN mz_internal.mz_comments cts_col ON cts_col.id = o.id AND cts_col.object_sub_id = ccol.position
5788WHERE op.privilege_type = 'SELECT'
5789 AND (o.type = 'materialized-view' OR (o.type = 'view' AND i.id IS NOT NULL))
5790 AND s.name NOT IN ('mz_catalog', 'mz_internal', 'pg_catalog', 'information_schema', 'mz_introspection')
5791GROUP BY 1, 2, 3
5792),
5793-- Pick the right (object_id, cluster_id) for hydration: the index's id +
5794-- cluster when an index exists (its arrangement is what the data product
5795-- reads from), otherwise the materialized view's own id + cluster.
5796hydration_meta AS (
5797 SELECT DISTINCT
5798 '"' || db.name || '"."' || s.name || '"."' || o.name || '"' AS object_name,
5799 COALESCE(c_idx.name, c_obj.name) AS cluster,
5800 COALESCE(i.id, o.id) AS hydration_object_id,
5801 COALESCE(i.cluster_id, o.cluster_id) AS cluster_id
5802 FROM mz_objects o
5803 JOIN mz_schemas s ON s.id = o.schema_id
5804 JOIN mz_databases db ON db.id = s.database_id
5805 LEFT JOIN mz_indexes i ON i.on_id = o.id
5806 LEFT JOIN mz_clusters c_idx ON c_idx.id = i.cluster_id
5807 LEFT JOIN mz_clusters c_obj ON c_obj.id = o.cluster_id
5808 WHERE (o.type = 'materialized-view' OR (o.type = 'view' AND i.id IS NOT NULL))
5809 AND s.name NOT IN ('mz_catalog', 'mz_internal', 'pg_catalog', 'information_schema', 'mz_introspection')
5810),
5811-- Dedupe by replica before counting: an MV with multiple indexes on the
5812-- same cluster has multiple rows in `hydration_meta`, and joining each
5813-- of them against `mz_cluster_replicas` would otherwise inflate the
5814-- counts by the number of indexes. A replica is "hydrated" only when
5815-- every index dataflow for this data product is hydrated on it.
5816hydration_per_replica AS (
5817 SELECT
5818 m.object_name,
5819 m.cluster,
5820 r.id AS replica_id,
5821 bool_and(COALESCE(h.hydrated, false)) AS replica_hydrated
5822 FROM hydration_meta m
5823 LEFT JOIN mz_catalog.mz_cluster_replicas r ON r.cluster_id = m.cluster_id
5824 LEFT JOIN mz_internal.mz_hydration_statuses h
5825 ON h.replica_id = r.id AND h.object_id = m.hydration_object_id
5826 GROUP BY m.object_name, m.cluster, r.id
5827),
5828hydration AS (
5829 SELECT
5830 object_name,
5831 cluster,
5832 COUNT(replica_id)::int AS replica_count,
5833 COUNT(replica_id) FILTER (WHERE replica_hydrated)::int AS hydrated_replica_count
5834 FROM hydration_per_replica
5835 GROUP BY object_name, cluster
5836)
5837SELECT
5838 d.object_name,
5839 d.cluster,
5840 d.description,
5841 d.schema,
5842 jsonb_build_object(
5843 'hydrated',
5844 COALESCE(h.replica_count > 0 AND h.hydrated_replica_count = h.replica_count, false),
5845 'replica_count', COALESCE(h.replica_count, 0),
5846 'hydrated_replica_count', COALESCE(h.hydrated_replica_count, 0)
5847 ) AS hydration
5848FROM details_raw d
5849LEFT JOIN hydration h
5850 ON h.object_name = d.object_name
5851 AND h.cluster IS NOT DISTINCT FROM d.cluster
5852"#,
5853 access: vec![PUBLIC_SELECT],
5854 ontology: None,
5855});
5856
5857pub static MZ_SHOW_ROLE_MEMBERS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5858 name: "mz_show_role_members",
5859 schema: MZ_INTERNAL_SCHEMA,
5860 oid: oid::VIEW_MZ_SHOW_ROLE_MEMBERS_OID,
5861 desc: RelationDesc::builder()
5862 .with_column("role", SqlScalarType::String.nullable(false))
5863 .with_column("member", SqlScalarType::String.nullable(false))
5864 .with_column("grantor", SqlScalarType::String.nullable(false))
5865 .finish(),
5866 column_comments: BTreeMap::from_iter([
5867 ("role", "The role that `member` is a member of."),
5868 ("member", "The role that is a member of `role`."),
5869 (
5870 "grantor",
5871 "The role that granted membership of `member` to `role`.",
5872 ),
5873 ]),
5874 sql: r#"SELECT
5875 r1.name AS role,
5876 r2.name AS member,
5877 r3.name AS grantor
5878FROM mz_catalog.mz_role_members rm
5879JOIN mz_catalog.mz_roles r1 ON r1.id = rm.role_id
5880JOIN mz_catalog.mz_roles r2 ON r2.id = rm.member
5881JOIN mz_catalog.mz_roles r3 ON r3.id = rm.grantor
5882ORDER BY role"#,
5883 access: vec![PUBLIC_SELECT],
5884 ontology: None,
5885});
5886
5887pub static MZ_SHOW_MY_ROLE_MEMBERS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5888 name: "mz_show_my_role_members",
5889 schema: MZ_INTERNAL_SCHEMA,
5890 oid: oid::VIEW_MZ_SHOW_MY_ROLE_MEMBERS_OID,
5891 desc: RelationDesc::builder()
5892 .with_column("role", SqlScalarType::String.nullable(false))
5893 .with_column("member", SqlScalarType::String.nullable(false))
5894 .with_column("grantor", SqlScalarType::String.nullable(false))
5895 .finish(),
5896 column_comments: BTreeMap::from_iter([
5897 ("role", "The role that `member` is a member of."),
5898 ("member", "The role that is a member of `role`."),
5899 (
5900 "grantor",
5901 "The role that granted membership of `member` to `role`.",
5902 ),
5903 ]),
5904 sql: r#"SELECT role, member, grantor
5905FROM mz_internal.mz_show_role_members
5906WHERE pg_has_role(member, 'USAGE')"#,
5907 access: vec![PUBLIC_SELECT],
5908 ontology: None,
5909});
5910
5911pub static MZ_SHOW_SYSTEM_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5912 name: "mz_show_system_privileges",
5913 schema: MZ_INTERNAL_SCHEMA,
5914 oid: oid::VIEW_MZ_SHOW_SYSTEM_PRIVILEGES_OID,
5915 desc: RelationDesc::builder()
5916 .with_column("grantor", SqlScalarType::String.nullable(true))
5917 .with_column("grantee", SqlScalarType::String.nullable(true))
5918 .with_column("privilege_type", SqlScalarType::String.nullable(false))
5919 .finish(),
5920 column_comments: BTreeMap::from_iter([
5921 ("grantor", "The role that granted the privilege."),
5922 ("grantee", "The role that the privilege was granted to."),
5923 ("privilege_type", "They type of privilege granted."),
5924 ]),
5925 sql: r#"SELECT
5926 grantor.name AS grantor,
5927 CASE privileges.grantee
5928 WHEN 'p' THEN 'PUBLIC'
5929 ELSE grantee.name
5930 END AS grantee,
5931 privileges.privilege_type AS privilege_type
5932FROM
5933 (SELECT mz_internal.mz_aclexplode(ARRAY[privileges]).*
5934 FROM mz_catalog.mz_system_privileges) AS privileges
5935LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
5936LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
5937WHERE privileges.grantee NOT LIKE 's%'"#,
5938 access: vec![PUBLIC_SELECT],
5939 ontology: None,
5940});
5941
5942pub static MZ_SHOW_MY_SYSTEM_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5943 name: "mz_show_my_system_privileges",
5944 schema: MZ_INTERNAL_SCHEMA,
5945 oid: oid::VIEW_MZ_SHOW_MY_SYSTEM_PRIVILEGES_OID,
5946 desc: RelationDesc::builder()
5947 .with_column("grantor", SqlScalarType::String.nullable(true))
5948 .with_column("grantee", SqlScalarType::String.nullable(true))
5949 .with_column("privilege_type", SqlScalarType::String.nullable(false))
5950 .finish(),
5951 column_comments: BTreeMap::from_iter([
5952 ("grantor", "The role that granted the privilege."),
5953 ("grantee", "The role that the privilege was granted to."),
5954 ("privilege_type", "They type of privilege granted."),
5955 ]),
5956 sql: r#"SELECT grantor, grantee, privilege_type
5957FROM mz_internal.mz_show_system_privileges
5958WHERE
5959 CASE
5960 WHEN grantee = 'PUBLIC' THEN true
5961 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
5962 -- whether the current user holds role `grantee`. For a nonexistent grantee
5963 -- name, both return false. We use mz_session_role_memberships() instead
5964 -- because pg_has_role internally calls mz_role_oid_memberships(), which
5965 -- loads the full system role graph and is blocked in restricted sessions.
5966 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
5967 END"#,
5968 access: vec![PUBLIC_SELECT],
5969 ontology: None,
5970});
5971
5972pub static MZ_SHOW_CLUSTER_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5973 name: "mz_show_cluster_privileges",
5974 schema: MZ_INTERNAL_SCHEMA,
5975 oid: oid::VIEW_MZ_SHOW_CLUSTER_PRIVILEGES_OID,
5976 desc: RelationDesc::builder()
5977 .with_column("grantor", SqlScalarType::String.nullable(true))
5978 .with_column("grantee", SqlScalarType::String.nullable(true))
5979 .with_column("name", SqlScalarType::String.nullable(false))
5980 .with_column("privilege_type", SqlScalarType::String.nullable(false))
5981 .finish(),
5982 column_comments: BTreeMap::from_iter([
5983 ("grantor", "The role that granted the privilege."),
5984 ("grantee", "The role that the privilege was granted to."),
5985 ("name", "The name of the cluster."),
5986 ("privilege_type", "They type of privilege granted."),
5987 ]),
5988 sql: r#"SELECT
5989 grantor.name AS grantor,
5990 CASE privileges.grantee
5991 WHEN 'p' THEN 'PUBLIC'
5992 ELSE grantee.name
5993 END AS grantee,
5994 privileges.name AS name,
5995 privileges.privilege_type AS privilege_type
5996FROM
5997 (SELECT mz_internal.mz_aclexplode(privileges).*, name
5998 FROM mz_catalog.mz_clusters
5999 WHERE id NOT LIKE 's%') AS privileges
6000LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
6001LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
6002WHERE privileges.grantee NOT LIKE 's%'"#,
6003 access: vec![PUBLIC_SELECT],
6004 ontology: None,
6005});
6006
6007pub static MZ_SHOW_MY_CLUSTER_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6008 name: "mz_show_my_cluster_privileges",
6009 schema: MZ_INTERNAL_SCHEMA,
6010 oid: oid::VIEW_MZ_SHOW_MY_CLUSTER_PRIVILEGES_OID,
6011 desc: RelationDesc::builder()
6012 .with_column("grantor", SqlScalarType::String.nullable(true))
6013 .with_column("grantee", SqlScalarType::String.nullable(true))
6014 .with_column("name", SqlScalarType::String.nullable(false))
6015 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6016 .finish(),
6017 column_comments: BTreeMap::from_iter([
6018 ("grantor", "The role that granted the privilege."),
6019 ("grantee", "The role that the privilege was granted to."),
6020 ("name", "The name of the cluster."),
6021 ("privilege_type", "They type of privilege granted."),
6022 ]),
6023 sql: r#"SELECT grantor, grantee, name, privilege_type
6024FROM mz_internal.mz_show_cluster_privileges
6025WHERE
6026 CASE
6027 WHEN grantee = 'PUBLIC' THEN true
6028 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6029 -- whether the current user holds role `grantee`. For a nonexistent grantee
6030 -- name, both return false. We use mz_session_role_memberships() instead
6031 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6032 -- loads the full system role graph and is blocked in restricted sessions.
6033 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6034 END"#,
6035 access: vec![PUBLIC_SELECT],
6036 ontology: None,
6037});
6038
6039pub static MZ_SHOW_DATABASE_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6040 name: "mz_show_database_privileges",
6041 schema: MZ_INTERNAL_SCHEMA,
6042 oid: oid::VIEW_MZ_SHOW_DATABASE_PRIVILEGES_OID,
6043 desc: RelationDesc::builder()
6044 .with_column("grantor", SqlScalarType::String.nullable(true))
6045 .with_column("grantee", SqlScalarType::String.nullable(true))
6046 .with_column("name", SqlScalarType::String.nullable(false))
6047 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6048 .finish(),
6049 column_comments: BTreeMap::from_iter([
6050 ("grantor", "The role that granted the privilege."),
6051 ("grantee", "The role that the privilege was granted to."),
6052 ("name", "The name of the database."),
6053 ("privilege_type", "They type of privilege granted."),
6054 ]),
6055 sql: r#"SELECT
6056 grantor.name AS grantor,
6057 CASE privileges.grantee
6058 WHEN 'p' THEN 'PUBLIC'
6059 ELSE grantee.name
6060 END AS grantee,
6061 privileges.name AS name,
6062 privileges.privilege_type AS privilege_type
6063FROM
6064 (SELECT mz_internal.mz_aclexplode(privileges).*, name
6065 FROM mz_catalog.mz_databases
6066 WHERE id NOT LIKE 's%') AS privileges
6067LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
6068LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
6069WHERE privileges.grantee NOT LIKE 's%'"#,
6070 access: vec![PUBLIC_SELECT],
6071 ontology: None,
6072});
6073
6074pub static MZ_SHOW_MY_DATABASE_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6075 name: "mz_show_my_database_privileges",
6076 schema: MZ_INTERNAL_SCHEMA,
6077 oid: oid::VIEW_MZ_SHOW_MY_DATABASE_PRIVILEGES_OID,
6078 desc: RelationDesc::builder()
6079 .with_column("grantor", SqlScalarType::String.nullable(true))
6080 .with_column("grantee", SqlScalarType::String.nullable(true))
6081 .with_column("name", SqlScalarType::String.nullable(false))
6082 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6083 .finish(),
6084 column_comments: BTreeMap::from_iter([
6085 ("grantor", "The role that granted the privilege."),
6086 ("grantee", "The role that the privilege was granted to."),
6087 ("name", "The name of the cluster."),
6088 ("privilege_type", "They type of privilege granted."),
6089 ]),
6090 sql: r#"SELECT grantor, grantee, name, privilege_type
6091FROM mz_internal.mz_show_database_privileges
6092WHERE
6093 CASE
6094 WHEN grantee = 'PUBLIC' THEN true
6095 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6096 -- whether the current user holds role `grantee`. For a nonexistent grantee
6097 -- name, both return false. We use mz_session_role_memberships() instead
6098 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6099 -- loads the full system role graph and is blocked in restricted sessions.
6100 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6101 END"#,
6102 access: vec![PUBLIC_SELECT],
6103 ontology: None,
6104});
6105
6106pub static MZ_SHOW_SCHEMA_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6107 name: "mz_show_schema_privileges",
6108 schema: MZ_INTERNAL_SCHEMA,
6109 oid: oid::VIEW_MZ_SHOW_SCHEMA_PRIVILEGES_OID,
6110 desc: RelationDesc::builder()
6111 .with_column("grantor", SqlScalarType::String.nullable(true))
6112 .with_column("grantee", SqlScalarType::String.nullable(true))
6113 .with_column("database", SqlScalarType::String.nullable(true))
6114 .with_column("name", SqlScalarType::String.nullable(false))
6115 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6116 .finish(),
6117 column_comments: BTreeMap::from_iter([
6118 ("grantor", "The role that granted the privilege."),
6119 ("grantee", "The role that the privilege was granted to."),
6120 (
6121 "database",
6122 "The name of the database containing the schema.",
6123 ),
6124 ("name", "The name of the schema."),
6125 ("privilege_type", "They type of privilege granted."),
6126 ]),
6127 sql: r#"SELECT
6128 grantor.name AS grantor,
6129 CASE privileges.grantee
6130 WHEN 'p' THEN 'PUBLIC'
6131 ELSE grantee.name
6132 END AS grantee,
6133 databases.name AS database,
6134 privileges.name AS name,
6135 privileges.privilege_type AS privilege_type
6136FROM
6137 (SELECT mz_internal.mz_aclexplode(privileges).*, database_id, name
6138 FROM mz_catalog.mz_schemas
6139 WHERE id NOT LIKE 's%') AS privileges
6140LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
6141LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
6142LEFT JOIN mz_catalog.mz_databases databases ON privileges.database_id = databases.id
6143WHERE privileges.grantee NOT LIKE 's%'"#,
6144 access: vec![PUBLIC_SELECT],
6145 ontology: None,
6146});
6147
6148pub static MZ_SHOW_MY_SCHEMA_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6149 name: "mz_show_my_schema_privileges",
6150 schema: MZ_INTERNAL_SCHEMA,
6151 oid: oid::VIEW_MZ_SHOW_MY_SCHEMA_PRIVILEGES_OID,
6152 desc: RelationDesc::builder()
6153 .with_column("grantor", SqlScalarType::String.nullable(true))
6154 .with_column("grantee", SqlScalarType::String.nullable(true))
6155 .with_column("database", SqlScalarType::String.nullable(true))
6156 .with_column("name", SqlScalarType::String.nullable(false))
6157 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6158 .finish(),
6159 column_comments: BTreeMap::from_iter([
6160 ("grantor", "The role that granted the privilege."),
6161 ("grantee", "The role that the privilege was granted to."),
6162 (
6163 "database",
6164 "The name of the database containing the schema.",
6165 ),
6166 ("name", "The name of the schema."),
6167 ("privilege_type", "They type of privilege granted."),
6168 ]),
6169 sql: r#"SELECT grantor, grantee, database, name, privilege_type
6170FROM mz_internal.mz_show_schema_privileges
6171WHERE
6172 CASE
6173 WHEN grantee = 'PUBLIC' THEN true
6174 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6175 -- whether the current user holds role `grantee`. For a nonexistent grantee
6176 -- name, both return false. We use mz_session_role_memberships() instead
6177 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6178 -- loads the full system role graph and is blocked in restricted sessions.
6179 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6180 END"#,
6181 access: vec![PUBLIC_SELECT],
6182 ontology: None,
6183});
6184
6185pub static MZ_SHOW_OBJECT_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6186 name: "mz_show_object_privileges",
6187 schema: MZ_INTERNAL_SCHEMA,
6188 oid: oid::VIEW_MZ_SHOW_OBJECT_PRIVILEGES_OID,
6189 desc: RelationDesc::builder()
6190 .with_column("grantor", SqlScalarType::String.nullable(true))
6191 .with_column("grantee", SqlScalarType::String.nullable(true))
6192 .with_column("database", SqlScalarType::String.nullable(true))
6193 .with_column("schema", SqlScalarType::String.nullable(true))
6194 .with_column("name", SqlScalarType::String.nullable(false))
6195 .with_column("object_type", SqlScalarType::String.nullable(false))
6196 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6197 .finish(),
6198 column_comments: BTreeMap::from_iter([
6199 ("grantor", "The role that granted the privilege."),
6200 ("grantee", "The role that the privilege was granted to."),
6201 (
6202 "database",
6203 "The name of the database containing the object.",
6204 ),
6205 ("schema", "The name of the schema containing the object."),
6206 ("name", "The name of the object."),
6207 (
6208 "object_type",
6209 "The type of object the privilege is granted on.",
6210 ),
6211 ("privilege_type", "They type of privilege granted."),
6212 ]),
6213 sql: r#"SELECT
6214 grantor.name AS grantor,
6215 CASE privileges.grantee
6216 WHEN 'p' THEN 'PUBLIC'
6217 ELSE grantee.name
6218 END AS grantee,
6219 databases.name AS database,
6220 schemas.name AS schema,
6221 privileges.name AS name,
6222 privileges.type AS object_type,
6223 privileges.privilege_type AS privilege_type
6224FROM
6225 (SELECT mz_internal.mz_aclexplode(privileges).*, schema_id, name, type
6226 FROM mz_catalog.mz_objects
6227 WHERE id NOT LIKE 's%') AS privileges
6228LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
6229LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
6230LEFT JOIN mz_catalog.mz_schemas schemas ON privileges.schema_id = schemas.id
6231LEFT JOIN mz_catalog.mz_databases databases ON schemas.database_id = databases.id
6232WHERE privileges.grantee NOT LIKE 's%'"#,
6233 access: vec![PUBLIC_SELECT],
6234 ontology: None,
6235});
6236
6237pub static MZ_SHOW_MY_OBJECT_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6238 name: "mz_show_my_object_privileges",
6239 schema: MZ_INTERNAL_SCHEMA,
6240 oid: oid::VIEW_MZ_SHOW_MY_OBJECT_PRIVILEGES_OID,
6241 desc: RelationDesc::builder()
6242 .with_column("grantor", SqlScalarType::String.nullable(true))
6243 .with_column("grantee", SqlScalarType::String.nullable(true))
6244 .with_column("database", SqlScalarType::String.nullable(true))
6245 .with_column("schema", SqlScalarType::String.nullable(true))
6246 .with_column("name", SqlScalarType::String.nullable(false))
6247 .with_column("object_type", SqlScalarType::String.nullable(false))
6248 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6249 .finish(),
6250 column_comments: BTreeMap::from_iter([
6251 ("grantor", "The role that granted the privilege."),
6252 ("grantee", "The role that the privilege was granted to."),
6253 (
6254 "database",
6255 "The name of the database containing the object.",
6256 ),
6257 ("schema", "The name of the schema containing the object."),
6258 ("name", "The name of the object."),
6259 (
6260 "object_type",
6261 "The type of object the privilege is granted on.",
6262 ),
6263 ("privilege_type", "They type of privilege granted."),
6264 ]),
6265 sql: r#"SELECT grantor, grantee, database, schema, name, object_type, privilege_type
6266FROM mz_internal.mz_show_object_privileges
6267WHERE
6268 CASE
6269 WHEN grantee = 'PUBLIC' THEN true
6270 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6271 -- whether the current user holds role `grantee`. For a nonexistent grantee
6272 -- name, both return false. We use mz_session_role_memberships() instead
6273 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6274 -- loads the full system role graph and is blocked in restricted sessions.
6275 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6276 END"#,
6277 access: vec![PUBLIC_SELECT],
6278 ontology: None,
6279});
6280
6281pub static MZ_SHOW_ALL_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6282 name: "mz_show_all_privileges",
6283 schema: MZ_INTERNAL_SCHEMA,
6284 oid: oid::VIEW_MZ_SHOW_ALL_PRIVILEGES_OID,
6285 desc: RelationDesc::builder()
6286 .with_column("grantor", SqlScalarType::String.nullable(true))
6287 .with_column("grantee", SqlScalarType::String.nullable(true))
6288 .with_column("database", SqlScalarType::String.nullable(true))
6289 .with_column("schema", SqlScalarType::String.nullable(true))
6290 .with_column("name", SqlScalarType::String.nullable(true))
6291 .with_column("object_type", SqlScalarType::String.nullable(false))
6292 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6293 .finish(),
6294 column_comments: BTreeMap::from_iter([
6295 ("grantor", "The role that granted the privilege."),
6296 ("grantee", "The role that the privilege was granted to."),
6297 (
6298 "database",
6299 "The name of the database containing the object.",
6300 ),
6301 ("schema", "The name of the schema containing the object."),
6302 ("name", "The name of the privilege target."),
6303 (
6304 "object_type",
6305 "The type of object the privilege is granted on.",
6306 ),
6307 ("privilege_type", "They type of privilege granted."),
6308 ]),
6309 sql: r#"SELECT grantor, grantee, NULL AS database, NULL AS schema, NULL AS name, 'system' AS object_type, privilege_type
6310FROM mz_internal.mz_show_system_privileges
6311UNION ALL
6312SELECT grantor, grantee, NULL AS database, NULL AS schema, name, 'cluster' AS object_type, privilege_type
6313FROM mz_internal.mz_show_cluster_privileges
6314UNION ALL
6315SELECT grantor, grantee, NULL AS database, NULL AS schema, name, 'database' AS object_type, privilege_type
6316FROM mz_internal.mz_show_database_privileges
6317UNION ALL
6318SELECT grantor, grantee, database, NULL AS schema, name, 'schema' AS object_type, privilege_type
6319FROM mz_internal.mz_show_schema_privileges
6320UNION ALL
6321SELECT grantor, grantee, database, schema, name, object_type, privilege_type
6322FROM mz_internal.mz_show_object_privileges"#,
6323 access: vec![PUBLIC_SELECT],
6324 ontology: None,
6325});
6326
6327pub static MZ_SHOW_ALL_MY_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6328 name: "mz_show_all_my_privileges",
6329 schema: MZ_INTERNAL_SCHEMA,
6330 oid: oid::VIEW_MZ_SHOW_ALL_MY_PRIVILEGES_OID,
6331 desc: RelationDesc::builder()
6332 .with_column("grantor", SqlScalarType::String.nullable(true))
6333 .with_column("grantee", SqlScalarType::String.nullable(true))
6334 .with_column("database", SqlScalarType::String.nullable(true))
6335 .with_column("schema", SqlScalarType::String.nullable(true))
6336 .with_column("name", SqlScalarType::String.nullable(true))
6337 .with_column("object_type", SqlScalarType::String.nullable(false))
6338 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6339 .finish(),
6340 column_comments: BTreeMap::from_iter([
6341 ("grantor", "The role that granted the privilege."),
6342 ("grantee", "The role that the privilege was granted to."),
6343 (
6344 "database",
6345 "The name of the database containing the object.",
6346 ),
6347 ("schema", "The name of the schema containing the object."),
6348 ("name", "The name of the privilege target."),
6349 (
6350 "object_type",
6351 "The type of object the privilege is granted on.",
6352 ),
6353 ("privilege_type", "They type of privilege granted."),
6354 ]),
6355 sql: r#"SELECT grantor, grantee, database, schema, name, object_type, privilege_type
6356FROM mz_internal.mz_show_all_privileges
6357WHERE
6358 CASE
6359 WHEN grantee = 'PUBLIC' THEN true
6360 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6361 -- whether the current user holds role `grantee`. For a nonexistent grantee
6362 -- name, both return false. We use mz_session_role_memberships() instead
6363 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6364 -- loads the full system role graph and is blocked in restricted sessions.
6365 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6366 END"#,
6367 access: vec![PUBLIC_SELECT],
6368 ontology: None,
6369});
6370
6371pub static MZ_SHOW_DEFAULT_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6372 name: "mz_show_default_privileges",
6373 schema: MZ_INTERNAL_SCHEMA,
6374 oid: oid::VIEW_MZ_SHOW_DEFAULT_PRIVILEGES_OID,
6375 desc: RelationDesc::builder()
6376 .with_column("object_owner", SqlScalarType::String.nullable(true))
6377 .with_column("database", SqlScalarType::String.nullable(true))
6378 .with_column("schema", SqlScalarType::String.nullable(true))
6379 .with_column("object_type", SqlScalarType::String.nullable(false))
6380 .with_column("grantee", SqlScalarType::String.nullable(true))
6381 .with_column("privilege_type", SqlScalarType::String.nullable(true))
6382 .finish(),
6383 column_comments: BTreeMap::from_iter([
6384 (
6385 "object_owner",
6386 "Privileges described in this row will be granted on objects created by `object_owner`.",
6387 ),
6388 (
6389 "database",
6390 "Privileges described in this row will be granted only on objects created in `database` if non-null.",
6391 ),
6392 (
6393 "schema",
6394 "Privileges described in this row will be granted only on objects created in `schema` if non-null.",
6395 ),
6396 (
6397 "object_type",
6398 "Privileges described in this row will be granted only on objects of type `object_type`.",
6399 ),
6400 (
6401 "grantee",
6402 "Privileges described in this row will be granted to `grantee`.",
6403 ),
6404 ("privilege_type", "They type of privilege to be granted."),
6405 ]),
6406 sql: r#"SELECT
6407 CASE defaults.role_id
6408 WHEN 'p' THEN 'PUBLIC'
6409 ELSE object_owner.name
6410 END AS object_owner,
6411 databases.name AS database,
6412 schemas.name AS schema,
6413 object_type,
6414 CASE defaults.grantee
6415 WHEN 'p' THEN 'PUBLIC'
6416 ELSE grantee.name
6417 END AS grantee,
6418 unnest(mz_internal.mz_format_privileges(defaults.privileges)) AS privilege_type
6419FROM mz_catalog.mz_default_privileges defaults
6420LEFT JOIN mz_catalog.mz_roles AS object_owner ON defaults.role_id = object_owner.id
6421LEFT JOIN mz_catalog.mz_roles AS grantee ON defaults.grantee = grantee.id
6422LEFT JOIN mz_catalog.mz_databases AS databases ON defaults.database_id = databases.id
6423LEFT JOIN mz_catalog.mz_schemas AS schemas ON defaults.schema_id = schemas.id
6424WHERE defaults.grantee NOT LIKE 's%'
6425 AND defaults.database_id IS NULL OR defaults.database_id NOT LIKE 's%'
6426 AND defaults.schema_id IS NULL OR defaults.schema_id NOT LIKE 's%'"#,
6427 access: vec![PUBLIC_SELECT],
6428 ontology: None,
6429});
6430
6431pub static MZ_SHOW_MY_DEFAULT_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6432 name: "mz_show_my_default_privileges",
6433 schema: MZ_INTERNAL_SCHEMA,
6434 oid: oid::VIEW_MZ_SHOW_MY_DEFAULT_PRIVILEGES_OID,
6435 desc: RelationDesc::builder()
6436 .with_column("object_owner", SqlScalarType::String.nullable(true))
6437 .with_column("database", SqlScalarType::String.nullable(true))
6438 .with_column("schema", SqlScalarType::String.nullable(true))
6439 .with_column("object_type", SqlScalarType::String.nullable(false))
6440 .with_column("grantee", SqlScalarType::String.nullable(true))
6441 .with_column("privilege_type", SqlScalarType::String.nullable(true))
6442 .finish(),
6443 column_comments: BTreeMap::from_iter([
6444 (
6445 "object_owner",
6446 "Privileges described in this row will be granted on objects created by `object_owner`.",
6447 ),
6448 (
6449 "database",
6450 "Privileges described in this row will be granted only on objects created in `database` if non-null.",
6451 ),
6452 (
6453 "schema",
6454 "Privileges described in this row will be granted only on objects created in `schema` if non-null.",
6455 ),
6456 (
6457 "object_type",
6458 "Privileges described in this row will be granted only on objects of type `object_type`.",
6459 ),
6460 (
6461 "grantee",
6462 "Privileges described in this row will be granted to `grantee`.",
6463 ),
6464 ("privilege_type", "They type of privilege to be granted."),
6465 ]),
6466 sql: r#"SELECT object_owner, database, schema, object_type, grantee, privilege_type
6467FROM mz_internal.mz_show_default_privileges
6468WHERE
6469 CASE
6470 WHEN grantee = 'PUBLIC' THEN true
6471 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6472 -- whether the current user holds role `grantee`. For a nonexistent grantee
6473 -- name, both return false. We use mz_session_role_memberships() instead
6474 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6475 -- loads the full system role graph and is blocked in restricted sessions.
6476 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6477 END"#,
6478 access: vec![PUBLIC_SELECT],
6479 ontology: None,
6480});
6481
6482pub static MZ_SHOW_NETWORK_POLICIES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6483 name: "mz_show_network_policies",
6484 schema: MZ_INTERNAL_SCHEMA,
6485 oid: oid::VIEW_MZ_SHOW_NETWORK_POLICIES_OID,
6486 desc: RelationDesc::builder()
6487 .with_column("name", SqlScalarType::String.nullable(false))
6488 .with_column("rules", SqlScalarType::String.nullable(true))
6489 .with_column("comment", SqlScalarType::String.nullable(false))
6490 .finish(),
6491 column_comments: BTreeMap::new(),
6492 sql: "
6493WITH comments AS (
6494 SELECT id, comment
6495 FROM mz_internal.mz_comments
6496 WHERE object_type = 'network-policy' AND object_sub_id IS NULL
6497)
6498SELECT
6499 policy.name,
6500 pg_catalog.string_agg(rule.name,',' ORDER BY rule.name) as rules,
6501 COALESCE(comment, '') as comment
6502FROM
6503 mz_internal.mz_network_policies as policy
6504LEFT JOIN
6505 mz_internal.mz_network_policy_rules as rule ON policy.id = rule.policy_id
6506LEFT JOIN
6507 comments ON policy.id = comments.id
6508WHERE
6509 policy.id NOT LIKE 's%'
6510AND
6511 policy.id NOT LIKE 'g%'
6512GROUP BY policy.name, comments.comment;",
6513 access: vec![PUBLIC_SELECT],
6514 ontology: None,
6515});
6516
6517pub static MZ_CLUSTER_REPLICA_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6518 name: "mz_cluster_replica_history",
6519 schema: MZ_INTERNAL_SCHEMA,
6520 oid: oid::VIEW_MZ_CLUSTER_REPLICA_HISTORY_OID,
6521 desc: RelationDesc::builder()
6522 .with_column("replica_id", SqlScalarType::String.nullable(true))
6523 .with_column("size", SqlScalarType::String.nullable(true))
6524 .with_column("cluster_id", SqlScalarType::String.nullable(true))
6525 .with_column("cluster_name", SqlScalarType::String.nullable(true))
6526 .with_column("replica_name", SqlScalarType::String.nullable(true))
6527 .with_column(
6528 "created_at",
6529 SqlScalarType::TimestampTz { precision: None }.nullable(false),
6530 )
6531 .with_column(
6532 "dropped_at",
6533 SqlScalarType::TimestampTz { precision: None }.nullable(true),
6534 )
6535 .with_column(
6536 "credits_per_hour",
6537 SqlScalarType::Numeric { max_scale: None }.nullable(true),
6538 )
6539 .finish(),
6540 column_comments: BTreeMap::from_iter([
6541 ("replica_id", "The ID of a cluster replica."),
6542 (
6543 "size",
6544 "The size of the cluster replica. Corresponds to `mz_cluster_replica_sizes.size`.",
6545 ),
6546 (
6547 "cluster_id",
6548 "The ID of the cluster associated with the replica.",
6549 ),
6550 (
6551 "cluster_name",
6552 "The name of the cluster associated with the replica.",
6553 ),
6554 ("replica_name", "The name of the replica."),
6555 ("created_at", "The time at which the replica was created."),
6556 (
6557 "dropped_at",
6558 "The time at which the replica was dropped, or `NULL` if it still exists.",
6559 ),
6560 (
6561 "credits_per_hour",
6562 "The number of compute credits consumed per hour. Corresponds to `mz_cluster_replica_sizes.credits_per_hour`.",
6563 ),
6564 ]),
6565 sql: r#"
6566 WITH
6567 creates AS
6568 (
6569 SELECT
6570 details ->> 'logical_size' AS size,
6571 details ->> 'replica_id' AS replica_id,
6572 details ->> 'replica_name' AS replica_name,
6573 details ->> 'cluster_name' AS cluster_name,
6574 details ->> 'cluster_id' AS cluster_id,
6575 occurred_at
6576 FROM mz_catalog.mz_audit_events
6577 WHERE
6578 object_type = 'cluster-replica' AND event_type = 'create'
6579 AND
6580 details ->> 'replica_id' IS NOT NULL
6581 AND
6582 details ->> 'cluster_id' !~~ 's%'
6583 ),
6584 drops AS
6585 (
6586 SELECT details ->> 'replica_id' AS replica_id, occurred_at
6587 FROM mz_catalog.mz_audit_events
6588 WHERE object_type = 'cluster-replica' AND event_type = 'drop'
6589 )
6590 SELECT
6591 creates.replica_id,
6592 creates.size,
6593 creates.cluster_id,
6594 creates.cluster_name,
6595 creates.replica_name,
6596 creates.occurred_at AS created_at,
6597 drops.occurred_at AS dropped_at,
6598 mz_cluster_replica_sizes.credits_per_hour as credits_per_hour
6599 FROM
6600 creates
6601 LEFT JOIN drops ON creates.replica_id = drops.replica_id
6602 LEFT JOIN
6603 mz_catalog.mz_cluster_replica_sizes
6604 ON mz_cluster_replica_sizes.size = creates.size"#,
6605 access: vec![PUBLIC_SELECT],
6606 ontology: Some(Ontology {
6607 entity_name: "replica_history",
6608 description: "Historical record of replica creation/drops",
6609 links: &const { [] },
6610 column_semantic_types: &[],
6611 }),
6612});
6613
6614pub static MZ_CLUSTER_REPLICA_NAME_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6615 name: "mz_cluster_replica_name_history",
6616 schema: MZ_INTERNAL_SCHEMA,
6617 oid: oid::VIEW_MZ_CLUSTER_REPLICA_NAME_HISTORY_OID,
6618 desc: RelationDesc::builder()
6619 .with_column(
6620 "occurred_at",
6621 SqlScalarType::TimestampTz { precision: None }.nullable(true),
6622 )
6623 .with_column("id", SqlScalarType::String.nullable(true))
6624 .with_column("previous_name", SqlScalarType::String.nullable(true))
6625 .with_column("new_name", SqlScalarType::String.nullable(true))
6626 .finish(),
6627 column_comments: BTreeMap::from_iter([
6628 (
6629 "occurred_at",
6630 "The time at which the cluster replica was created or renamed. `NULL` if it's a built in system cluster replica.",
6631 ),
6632 ("id", "The ID of the cluster replica."),
6633 (
6634 "previous_name",
6635 "The previous name of the cluster replica. `NULL` if there was no previous name.",
6636 ),
6637 ("new_name", "The new name of the cluster replica."),
6638 ]),
6639 sql: r#"WITH user_replica_alter_history AS (
6640 SELECT occurred_at,
6641 audit_events.details->>'replica_id' AS id,
6642 audit_events.details->>'old_name' AS previous_name,
6643 audit_events.details->>'new_name' AS new_name
6644 FROM mz_catalog.mz_audit_events AS audit_events
6645 WHERE object_type = 'cluster-replica'
6646 AND audit_events.event_type = 'alter'
6647 AND audit_events.details->>'replica_id' like 'u%'
6648),
6649user_replica_create_history AS (
6650 SELECT occurred_at,
6651 audit_events.details->>'replica_id' AS id,
6652 NULL AS previous_name,
6653 audit_events.details->>'replica_name' AS new_name
6654 FROM mz_catalog.mz_audit_events AS audit_events
6655 WHERE object_type = 'cluster-replica'
6656 AND audit_events.event_type = 'create'
6657 AND audit_events.details->>'replica_id' like 'u%'
6658),
6659-- Because built in system cluster replicas don't have audit events, we need to manually add them
6660system_replicas AS (
6661 -- We assume that the system cluster replicas were created at the beginning of time
6662 SELECT NULL::timestamptz AS occurred_at,
6663 id,
6664 NULL AS previous_name,
6665 name AS new_name
6666 FROM mz_catalog.mz_cluster_replicas
6667 WHERE id LIKE 's%'
6668)
6669SELECT *
6670FROM user_replica_alter_history
6671UNION ALL
6672SELECT *
6673FROM user_replica_create_history
6674UNION ALL
6675SELECT *
6676FROM system_replicas"#,
6677 access: vec![PUBLIC_SELECT],
6678 ontology: Some(Ontology {
6679 entity_name: "replica_name_history",
6680 description: "Historical replica names",
6681 links: &const { [] },
6682 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
6683 }),
6684});
6685
6686pub static MZ_HYDRATION_STATUSES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6687 name: "mz_hydration_statuses",
6688 schema: MZ_INTERNAL_SCHEMA,
6689 oid: oid::VIEW_MZ_HYDRATION_STATUSES_OID,
6690 desc: RelationDesc::builder()
6691 .with_column("object_id", SqlScalarType::String.nullable(false))
6692 .with_column("replica_id", SqlScalarType::String.nullable(true))
6693 .with_column("hydrated", SqlScalarType::Bool.nullable(true))
6694 .finish(),
6695 column_comments: BTreeMap::from_iter([
6696 (
6697 "object_id",
6698 "The ID of a dataflow-powered object. Corresponds to `mz_catalog.mz_indexes.id`, `mz_catalog.mz_materialized_views.id`, `mz_internal.mz_subscriptions`, `mz_catalog.mz_sources.id`, or `mz_catalog.mz_sinks.id`.",
6699 ),
6700 ("replica_id", "The ID of a cluster replica."),
6701 ("hydrated", "Whether the object is hydrated on the replica."),
6702 ]),
6703 sql: r#"WITH
6704-- Joining against the linearizable catalog tables ensures that this view
6705-- always contains the set of installed objects, even when it depends
6706-- on introspection relations that may received delayed updates.
6707--
6708-- Note that this view only includes objects that are maintained by dataflows.
6709-- In particular, some source types (webhook, introspection, ...) are not and
6710-- are therefore omitted.
6711indexes AS (
6712 SELECT
6713 i.id AS object_id,
6714 h.replica_id,
6715 COALESCE(h.hydrated, false) AS hydrated
6716 FROM mz_catalog.mz_indexes i
6717 LEFT JOIN mz_internal.mz_compute_hydration_statuses h
6718 ON (h.object_id = i.id)
6719),
6720materialized_views AS (
6721 SELECT
6722 i.id AS object_id,
6723 h.replica_id,
6724 COALESCE(h.hydrated, false) AS hydrated
6725 FROM mz_catalog.mz_materialized_views i
6726 LEFT JOIN mz_internal.mz_compute_hydration_statuses h
6727 ON (h.object_id = i.id)
6728),
6729-- Hydration is a dataflow concept and not all sources are maintained by
6730-- dataflows, so we need to find the ones that are. Generally, sources that
6731-- have a cluster ID are maintained by a dataflow running on that cluster.
6732-- Webhook sources are an exception to this rule.
6733sources_with_clusters AS (
6734 SELECT id, cluster_id
6735 FROM mz_catalog.mz_sources
6736 WHERE cluster_id IS NOT NULL AND type != 'webhook'
6737),
6738sources AS (
6739 SELECT
6740 s.id AS object_id,
6741 ss.replica_id AS replica_id,
6742 ss.rehydration_latency IS NOT NULL AS hydrated
6743 FROM sources_with_clusters s
6744 LEFT JOIN mz_internal.mz_source_statistics ss USING (id)
6745),
6746-- We don't yet report sink hydration status (database-issues#8331), so we do a best effort attempt here and
6747-- define a sink as hydrated when it's both "running" and has a frontier greater than the minimum.
6748-- There is likely still a possibility of FPs.
6749sinks AS (
6750 SELECT
6751 s.id AS object_id,
6752 r.id AS replica_id,
6753 ss.status = 'running' AND COALESCE(f.write_frontier, 0) > 0 AS hydrated
6754 FROM mz_catalog.mz_sinks s
6755 LEFT JOIN mz_internal.mz_sink_statuses ss USING (id)
6756 JOIN mz_catalog.mz_cluster_replicas r
6757 ON (r.cluster_id = s.cluster_id)
6758 LEFT JOIN mz_catalog.mz_cluster_replica_frontiers f
6759 ON (f.object_id = s.id AND f.replica_id = r.id)
6760)
6761SELECT * FROM indexes
6762UNION ALL
6763SELECT * FROM materialized_views
6764UNION ALL
6765SELECT * FROM sources
6766UNION ALL
6767SELECT * FROM sinks"#,
6768 access: vec![PUBLIC_SELECT],
6769 ontology: Some(Ontology {
6770 entity_name: "hydration_status",
6771 description: "Overall hydration status per object",
6772 links: &const {
6773 [
6774 OntologyLink {
6775 name: "hydration_of",
6776 target: "object",
6777 properties: LinkProperties::fk_typed(
6778 "object_id",
6779 "id",
6780 Cardinality::OneToOne,
6781 mz_repr::SemanticType::CatalogItemId,
6782 ),
6783 },
6784 OntologyLink {
6785 name: "hydration_on_replica",
6786 target: "replica",
6787 properties: LinkProperties::fk("replica_id", "id", Cardinality::ManyToOne),
6788 },
6789 ]
6790 },
6791 column_semantic_types: &const {
6792 [
6793 ("object_id", SemanticType::CatalogItemId),
6794 ("replica_id", SemanticType::ReplicaId),
6795 ]
6796 },
6797 }),
6798});
6799
6800pub const MZ_HYDRATION_STATUSES_IND: BuiltinIndex = BuiltinIndex {
6801 name: "mz_hydration_statuses_ind",
6802 schema: MZ_INTERNAL_SCHEMA,
6803 oid: oid::INDEX_MZ_HYDRATION_STATUSES_IND_OID,
6804 sql: "IN CLUSTER mz_catalog_server
6805ON mz_internal.mz_hydration_statuses (object_id, replica_id)",
6806 is_retained_metrics_object: false,
6807};
6808
6809pub static MZ_MATERIALIZATION_DEPENDENCIES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6810 name: "mz_materialization_dependencies",
6811 schema: MZ_INTERNAL_SCHEMA,
6812 oid: oid::VIEW_MZ_MATERIALIZATION_DEPENDENCIES_OID,
6813 desc: RelationDesc::builder()
6814 .with_column("object_id", SqlScalarType::String.nullable(false))
6815 .with_column("dependency_id", SqlScalarType::String.nullable(false))
6816 .finish(),
6817 column_comments: BTreeMap::from_iter([
6818 (
6819 "object_id",
6820 "The ID of a materialization. Corresponds to `mz_catalog.mz_indexes.id`, `mz_catalog.mz_materialized_views.id`, or `mz_catalog.mz_sinks.id`.",
6821 ),
6822 (
6823 "dependency_id",
6824 "The ID of a dataflow dependency. Corresponds to `mz_catalog.mz_indexes.id`, `mz_catalog.mz_materialized_views.id`, `mz_catalog.mz_sources.id`, or `mz_catalog.mz_tables.id`.",
6825 ),
6826 ]),
6827 sql: "
6828SELECT object_id, dependency_id
6829FROM mz_internal.mz_compute_dependencies
6830UNION ALL
6831SELECT s.id, d.referenced_object_id AS dependency_id
6832FROM mz_internal.mz_object_dependencies d
6833JOIN mz_catalog.mz_sinks s ON (s.id = d.object_id)
6834JOIN mz_catalog.mz_relations r ON (r.id = d.referenced_object_id)",
6835 access: vec![PUBLIC_SELECT],
6836 ontology: Some(Ontology {
6837 entity_name: "materialization_dep",
6838 description: "Dependencies between materializations",
6839 links: &const {
6840 [
6841 OntologyLink {
6842 name: "depends_on",
6843 target: "object",
6844 properties: LinkProperties::DependsOn {
6845 source_column: "object_id",
6846 target_column: "id",
6847 source_id_type: Some(mz_repr::SemanticType::CatalogItemId),
6848 requires_mapping: None,
6849 },
6850 },
6851 OntologyLink {
6852 name: "dependency_is",
6853 target: "object",
6854 properties: LinkProperties::fk("dependency_id", "id", Cardinality::ManyToOne),
6855 },
6856 ]
6857 },
6858 column_semantic_types: &const {
6859 [
6860 ("object_id", SemanticType::CatalogItemId),
6861 ("dependency_id", SemanticType::CatalogItemId),
6862 ]
6863 },
6864 }),
6865});
6866
6867pub static MZ_MATERIALIZATION_LAG: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6868 name: "mz_materialization_lag",
6869 schema: MZ_INTERNAL_SCHEMA,
6870 oid: oid::VIEW_MZ_MATERIALIZATION_LAG_OID,
6871 desc: RelationDesc::builder()
6872 .with_column("object_id", SqlScalarType::String.nullable(false))
6873 .with_column("local_lag", SqlScalarType::Interval.nullable(true))
6874 .with_column("global_lag", SqlScalarType::Interval.nullable(true))
6875 .with_column(
6876 "slowest_local_input_id",
6877 SqlScalarType::String.nullable(false),
6878 )
6879 .with_column(
6880 "slowest_global_input_id",
6881 SqlScalarType::String.nullable(false),
6882 )
6883 .finish(),
6884 column_comments: BTreeMap::from_iter([
6885 (
6886 "object_id",
6887 "The ID of the materialized view, index, or sink.",
6888 ),
6889 (
6890 "local_lag",
6891 "The amount of time the materialization lags behind its direct inputs.",
6892 ),
6893 (
6894 "global_lag",
6895 "The amount of time the materialization lags behind its root inputs (sources and tables).",
6896 ),
6897 (
6898 "slowest_local_input_id",
6899 "The ID of the slowest direct input.",
6900 ),
6901 (
6902 "slowest_global_input_id",
6903 "The ID of the slowest root input.",
6904 ),
6905 ]),
6906 sql: "
6907WITH MUTUALLY RECURSIVE
6908 -- IDs of objects for which we want to know the lag.
6909 materializations (id text) AS (
6910 SELECT id FROM mz_catalog.mz_indexes
6911 UNION ALL
6912 SELECT id FROM mz_catalog.mz_materialized_views
6913 UNION ALL
6914 SELECT id FROM mz_catalog.mz_sinks
6915 ),
6916 -- Direct dependencies of materializations.
6917 direct_dependencies (id text, dep_id text) AS (
6918 SELECT m.id, d.dependency_id
6919 FROM materializations m
6920 JOIN mz_internal.mz_materialization_dependencies d ON (m.id = d.object_id)
6921 ),
6922 -- All transitive dependencies of materializations.
6923 transitive_dependencies (id text, dep_id text) AS (
6924 SELECT id, dep_id FROM direct_dependencies
6925 UNION
6926 SELECT td.id, dd.dep_id
6927 FROM transitive_dependencies td
6928 JOIN direct_dependencies dd ON (dd.id = td.dep_id)
6929 ),
6930 -- Root dependencies of materializations (sources and tables).
6931 root_dependencies (id text, dep_id text) AS (
6932 SELECT *
6933 FROM transitive_dependencies td
6934 WHERE NOT EXISTS (
6935 SELECT 1
6936 FROM direct_dependencies dd
6937 WHERE dd.id = td.dep_id
6938 )
6939 ),
6940 -- Write progress times of materializations.
6941 materialization_times (id text, time timestamptz) AS (
6942 SELECT m.id, to_timestamp(f.write_frontier::text::double / 1000)
6943 FROM materializations m
6944 JOIN mz_internal.mz_frontiers f ON (m.id = f.object_id)
6945 ),
6946 -- Write progress times of direct dependencies of materializations.
6947 input_times (id text, slowest_dep text, time timestamptz) AS (
6948 SELECT DISTINCT ON (d.id)
6949 d.id,
6950 d.dep_id,
6951 to_timestamp(f.write_frontier::text::double / 1000)
6952 FROM direct_dependencies d
6953 JOIN mz_internal.mz_frontiers f ON (d.dep_id = f.object_id)
6954 ORDER BY d.id, f.write_frontier ASC
6955 ),
6956 -- Write progress times of root dependencies of materializations.
6957 root_times (id text, slowest_dep text, time timestamptz) AS (
6958 SELECT DISTINCT ON (d.id)
6959 d.id,
6960 d.dep_id,
6961 to_timestamp(f.write_frontier::text::double / 1000)
6962 FROM root_dependencies d
6963 JOIN mz_internal.mz_frontiers f ON (d.dep_id = f.object_id)
6964 ORDER BY d.id, f.write_frontier ASC
6965 )
6966SELECT
6967 id AS object_id,
6968 -- Ensure that lag values are always NULL for materializations that have reached the empty
6969 -- frontier, as those have processed all their input data.
6970 -- Also make sure that lag values are never negative, even when input frontiers are before
6971 -- output frontiers (as can happen during hydration).
6972 CASE
6973 WHEN m.time IS NULL THEN INTERVAL '0'
6974 WHEN i.time IS NULL THEN NULL
6975 ELSE greatest(i.time - m.time, INTERVAL '0')
6976 END AS local_lag,
6977 CASE
6978 WHEN m.time IS NULL THEN INTERVAL '0'
6979 WHEN r.time IS NULL THEN NULL
6980 ELSE greatest(r.time - m.time, INTERVAL '0')
6981 END AS global_lag,
6982 i.slowest_dep AS slowest_local_input_id,
6983 r.slowest_dep AS slowest_global_input_id
6984FROM materialization_times m
6985JOIN input_times i USING (id)
6986JOIN root_times r USING (id)",
6987 access: vec![PUBLIC_SELECT],
6988 ontology: Some(Ontology {
6989 entity_name: "materialization_lag",
6990 description: "Lag between a materialization and its inputs",
6991 links: &const {
6992 [
6993 OntologyLink {
6994 name: "measures_materialization_lag",
6995 target: "object",
6996 properties: LinkProperties::measures("object_id", "id", "materialization_lag"),
6997 },
6998 OntologyLink {
6999 name: "slowest_local_input",
7000 target: "object",
7001 properties: LinkProperties::fk(
7002 "slowest_local_input_id",
7003 "id",
7004 Cardinality::ManyToOne,
7005 ),
7006 },
7007 OntologyLink {
7008 name: "slowest_global_input",
7009 target: "object",
7010 properties: LinkProperties::fk(
7011 "slowest_global_input_id",
7012 "id",
7013 Cardinality::ManyToOne,
7014 ),
7015 },
7016 ]
7017 },
7018 column_semantic_types: &const {
7019 [
7020 ("object_id", SemanticType::CatalogItemId),
7021 ("slowest_local_input_id", SemanticType::CatalogItemId),
7022 ("slowest_global_input_id", SemanticType::CatalogItemId),
7023 ]
7024 },
7025 }),
7026});
7027fn console_cluster_utilization_overview_desc() -> RelationDesc {
7031 RelationDesc::builder()
7032 .with_column(
7033 "bucket_start",
7034 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7035 )
7036 .with_column("replica_id", SqlScalarType::String.nullable(false))
7037 .with_column("memory_percent", SqlScalarType::Float64.nullable(true))
7038 .with_column(
7039 "max_memory_at",
7040 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7041 )
7042 .with_column("disk_percent", SqlScalarType::Float64.nullable(true))
7043 .with_column(
7044 "max_disk_at",
7045 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7046 )
7047 .with_column(
7048 "memory_and_disk_percent",
7049 SqlScalarType::Float64.nullable(true),
7050 )
7051 .with_column(
7052 "max_memory_and_disk_memory_percent",
7053 SqlScalarType::Float64.nullable(true),
7054 )
7055 .with_column(
7056 "max_memory_and_disk_disk_percent",
7057 SqlScalarType::Float64.nullable(true),
7058 )
7059 .with_column(
7060 "max_memory_and_disk_at",
7061 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7062 )
7063 .with_column("heap_percent", SqlScalarType::Float64.nullable(true))
7064 .with_column(
7065 "max_heap_at",
7066 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7067 )
7068 .with_column("max_cpu_percent", SqlScalarType::Float64.nullable(true))
7069 .with_column(
7070 "max_cpu_at",
7071 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7072 )
7073 .with_column("offline_events", SqlScalarType::Jsonb.nullable(true))
7074 .with_column(
7075 "bucket_end",
7076 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7077 )
7078 .with_column("name", SqlScalarType::String.nullable(true))
7079 .with_column("cluster_id", SqlScalarType::String.nullable(true))
7080 .with_column("size", SqlScalarType::String.nullable(true))
7081 .finish()
7082}
7083
7084fn console_cluster_utilization_overview_sql(bin: &str, retention: &str, group_size: u32) -> String {
7102 format!(
7103 r#"WITH replica_history AS (
7104 SELECT replica_id, size, cluster_id
7105 FROM mz_internal.mz_cluster_replica_history
7106 UNION
7107 -- We union the current set of cluster replicas since mz_cluster_replica_history doesn't include system clusters.
7108 SELECT id AS replica_id, size, cluster_id
7109 FROM mz_catalog.mz_cluster_replicas
7110),
7111replica_metrics_history AS (
7112 SELECT
7113 m.occurred_at,
7114 m.replica_id,
7115 r.size,
7116 (SUM(m.cpu_nano_cores::float8) / NULLIF(s.cpu_nano_cores, 0) / NULLIF(s.processes, 0)) AS cpu_percent,
7117 (SUM(m.memory_bytes::float8) / NULLIF(s.memory_bytes, 0) / NULLIF(s.processes, 0)) AS memory_percent,
7118 (SUM(m.disk_bytes::float8) / NULLIF(s.disk_bytes, 0) / NULLIF(s.processes, 0)) AS disk_percent,
7119 SUM(m.disk_bytes::float8) AS disk_bytes,
7120 SUM(m.memory_bytes::float8) AS memory_bytes,
7121 s.disk_bytes::float8 * s.processes AS total_disk_bytes,
7122 s.memory_bytes::float8 * s.processes AS total_memory_bytes,
7123 MAX(m.heap_bytes::float8) AS heap_bytes,
7124 MAX(m.heap_limit) AS heap_limit,
7125 -- heap_limit is NULL when clusterd isn't launched with --heap-limit (e.g.
7126 -- the emulator's process orchestrator). Fall back to the size-based memory
7127 -- percent so the chart still renders.
7128 COALESCE(
7129 MAX(m.heap_bytes::float8 / NULLIF(m.heap_limit, 0)),
7130 SUM(m.memory_bytes::float8) / NULLIF(s.memory_bytes, 0) / NULLIF(s.processes, 0)
7131 ) AS heap_percent
7132 FROM
7133 replica_history AS r
7134 INNER JOIN mz_catalog.mz_cluster_replica_sizes AS s ON r.size = s.size
7135 INNER JOIN mz_internal.mz_cluster_replica_metrics_history AS m ON m.replica_id = r.replica_id
7136 GROUP BY
7137 m.occurred_at,
7138 m.replica_id,
7139 r.size,
7140 s.cpu_nano_cores,
7141 s.memory_bytes,
7142 s.disk_bytes,
7143 s.processes
7144),
7145replica_utilization_history_binned AS (
7146 -- NOTE: we read directly from replica_metrics_history rather than re-joining
7147 -- replica_history; every replica_id here already came from replica_history,
7148 -- so the join was redundant (and could fan out a replica that changed size).
7149 SELECT
7150 m.occurred_at,
7151 m.replica_id,
7152 m.cpu_percent,
7153 m.memory_percent,
7154 m.memory_bytes,
7155 m.disk_percent,
7156 m.disk_bytes,
7157 m.total_disk_bytes,
7158 m.total_memory_bytes,
7159 m.heap_bytes,
7160 m.heap_percent,
7161 m.size,
7162 date_bin('{bin}', m.occurred_at, '1970-01-01'::timestamp) AS bucket_start
7163 FROM replica_metrics_history AS m
7164 WHERE mz_now() <= date_bin('{bin}', m.occurred_at, '1970-01-01'::timestamp) + INTERVAL '{retention}'
7165),
7166-- For each (replica, bucket), take the sample with the highest memory.
7167max_memory AS (
7168 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, memory_percent, occurred_at
7169 FROM replica_utilization_history_binned
7170 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
7171 ORDER BY bucket_start, replica_id, COALESCE(memory_bytes, 0) DESC
7172),
7173-- For each (replica, bucket), take the sample with the highest disk.
7174max_disk AS (
7175 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, disk_percent, occurred_at
7176 FROM replica_utilization_history_binned
7177 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
7178 ORDER BY bucket_start, replica_id, COALESCE(disk_bytes, 0) DESC
7179),
7180-- For each (replica, bucket), take the sample with the highest cpu.
7181max_cpu AS (
7182 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, cpu_percent, occurred_at
7183 FROM replica_utilization_history_binned
7184 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
7185 ORDER BY bucket_start, replica_id, COALESCE(cpu_percent, 0) DESC
7186),
7187/*
7188 For each (replica, bucket), take the sample with the highest combined memory
7189 and disk. This is different from adding max_memory and max_disk per bucket
7190 because both values may not occur at the same time if the bucket interval is
7191 large.
7192*/
7193max_memory_and_disk AS (
7194 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, memory_percent, disk_percent, memory_and_disk_percent, occurred_at
7195 FROM (
7196 SELECT *,
7197 CASE
7198 WHEN disk_bytes IS NULL AND memory_bytes IS NULL THEN NULL
7199 ELSE (COALESCE(memory_bytes, 0) + COALESCE(disk_bytes, 0)) / NULLIF((total_memory_bytes + total_disk_bytes), 0)
7200 END AS memory_and_disk_percent
7201 FROM replica_utilization_history_binned
7202 ) AS max_memory_and_disk_inner
7203 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
7204 ORDER BY bucket_start, replica_id, COALESCE(memory_and_disk_percent, 0) DESC
7205),
7206-- For each (replica, bucket), take the sample with the highest heap.
7207max_heap AS (
7208 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, heap_percent, occurred_at
7209 FROM replica_utilization_history_binned
7210 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
7211 ORDER BY bucket_start, replica_id, COALESCE(heap_bytes, 0) DESC
7212),
7213-- For each (replica, bucket), collect its offline events at that time.
7214replica_offline_event_history AS (
7215 SELECT
7216 date_bin('{bin}', occurred_at, '1970-01-01'::timestamp) AS bucket_start,
7217 replica_id,
7218 jsonb_agg(
7219 jsonb_build_object(
7220 'replicaId', rsh.replica_id,
7221 'occurredAt', rsh.occurred_at,
7222 'status', rsh.status,
7223 'reason', rsh.reason
7224 )
7225 ) AS offline_events
7226 FROM mz_internal.mz_cluster_replica_status_history AS rsh
7227 -- We assume the statuses for process 0 are the same as all processes.
7228 WHERE process_id = '0'
7229 AND status = 'offline'
7230 AND mz_now() <= date_bin('{bin}', occurred_at, '1970-01-01'::timestamp) + INTERVAL '{retention}'
7231 GROUP BY bucket_start, replica_id
7232)
7233SELECT
7234 bucket_start,
7235 replica_id,
7236 max_memory.memory_percent,
7237 max_memory.occurred_at AS max_memory_at,
7238 max_disk.disk_percent,
7239 max_disk.occurred_at AS max_disk_at,
7240 max_memory_and_disk.memory_and_disk_percent AS memory_and_disk_percent,
7241 max_memory_and_disk.memory_percent AS max_memory_and_disk_memory_percent,
7242 max_memory_and_disk.disk_percent AS max_memory_and_disk_disk_percent,
7243 max_memory_and_disk.occurred_at AS max_memory_and_disk_at,
7244 max_heap.heap_percent,
7245 max_heap.occurred_at AS max_heap_at,
7246 max_cpu.cpu_percent AS max_cpu_percent,
7247 max_cpu.occurred_at AS max_cpu_at,
7248 replica_offline_event_history.offline_events,
7249 bucket_start + INTERVAL '{bin}' AS bucket_end,
7250 replica_name_history.new_name AS name,
7251 replica_history.cluster_id,
7252 replica_history.size
7253FROM max_memory
7254JOIN max_disk USING (bucket_start, replica_id)
7255JOIN max_cpu USING (bucket_start, replica_id)
7256JOIN max_memory_and_disk USING (bucket_start, replica_id)
7257JOIN max_heap USING (bucket_start, replica_id)
7258JOIN replica_history USING (replica_id)
7259/*
7260 TOP k=1 over the name history via a LATERAL subquery + LIMIT: for each bucket,
7261 get the most recent replica name as of the end of the bucket.
7262*/
7263CROSS JOIN LATERAL (
7264 SELECT new_name
7265 FROM mz_internal.mz_cluster_replica_name_history AS replica_name_history
7266 WHERE replica_id = replica_name_history.id
7267 -- We treat NULLs as the beginning of time.
7268 AND bucket_start + INTERVAL '{bin}' >= COALESCE(replica_name_history.occurred_at, '1970-01-01'::timestamp)
7269 ORDER BY replica_name_history.occurred_at DESC
7270 LIMIT 1
7271) AS replica_name_history
7272LEFT JOIN replica_offline_event_history USING (bucket_start, replica_id)"#,
7273 bin = bin,
7274 retention = retention,
7275 group_size = group_size,
7276 )
7277}
7278
7279fn console_cluster_utilization_unbinned_3h_desc() -> RelationDesc {
7283 RelationDesc::builder()
7284 .with_column("replica_id", SqlScalarType::String.nullable(false))
7285 .with_column("cluster_id", SqlScalarType::String.nullable(true))
7286 .with_column("size", SqlScalarType::String.nullable(false))
7287 .with_column("name", SqlScalarType::String.nullable(true))
7288 .with_column(
7289 "occurred_at",
7290 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7291 )
7292 .with_column("cpu_percent", SqlScalarType::Float64.nullable(true))
7293 .with_column("memory_percent", SqlScalarType::Float64.nullable(true))
7294 .with_column("disk_percent", SqlScalarType::Float64.nullable(true))
7295 .with_column("heap_percent", SqlScalarType::Float64.nullable(true))
7296 .with_column(
7297 "memory_and_disk_percent",
7298 SqlScalarType::Float64.nullable(true),
7299 )
7300 .finish()
7301}
7302
7303fn console_cluster_utilization_unbinned_3h_sql(retention: &str) -> String {
7311 format!(
7312 r#"WITH replica_history AS (
7313 -- Dedup to one row per replica (prefer the current size). Size is fixed per
7314 -- replica so this is normally a no-op, but a stray duplicate size in history
7315 -- would fan out the metrics join; with no Top-1 dedup here that would emit two
7316 -- rows per (replica_id, occurred_at) and break the Console SUBSCRIBE upsert key.
7317 SELECT DISTINCT ON (replica_id) replica_id, size, cluster_id
7318 FROM (
7319 -- We union the current set of cluster replicas since mz_cluster_replica_history doesn't include system clusters.
7320 SELECT id AS replica_id, size, cluster_id, 0 AS source_rank
7321 FROM mz_catalog.mz_cluster_replicas
7322 UNION ALL
7323 SELECT replica_id, size, cluster_id, 1 AS source_rank
7324 FROM mz_internal.mz_cluster_replica_history
7325 ) all_replicas
7326 ORDER BY replica_id, source_rank
7327),
7328replica_metrics AS (
7329 SELECT
7330 m.occurred_at,
7331 m.replica_id,
7332 r.cluster_id,
7333 r.size,
7334 (SUM(m.cpu_nano_cores::float8) / NULLIF(s.cpu_nano_cores, 0) / NULLIF(s.processes, 0)) AS cpu_percent,
7335 (SUM(m.memory_bytes::float8) / NULLIF(s.memory_bytes, 0) / NULLIF(s.processes, 0)) AS memory_percent,
7336 (SUM(m.disk_bytes::float8) / NULLIF(s.disk_bytes, 0) / NULLIF(s.processes, 0)) AS disk_percent,
7337 COALESCE(
7338 MAX(m.heap_bytes::float8 / NULLIF(m.heap_limit, 0)),
7339 SUM(m.memory_bytes::float8) / NULLIF(s.memory_bytes, 0) / NULLIF(s.processes, 0)
7340 ) AS heap_percent,
7341 CASE
7342 WHEN SUM(m.disk_bytes::float8) IS NULL AND SUM(m.memory_bytes::float8) IS NULL THEN NULL
7343 ELSE (COALESCE(SUM(m.memory_bytes::float8), 0) + COALESCE(SUM(m.disk_bytes::float8), 0))
7344 / NULLIF((s.memory_bytes::float8 + s.disk_bytes::float8) * s.processes, 0)
7345 END AS memory_and_disk_percent
7346 FROM replica_history AS r
7347 INNER JOIN mz_catalog.mz_cluster_replica_sizes AS s ON r.size = s.size
7348 INNER JOIN mz_internal.mz_cluster_replica_metrics_history AS m ON m.replica_id = r.replica_id
7349 -- No aggregation over time: one row per (replica, sample) so the Console bins
7350 -- client-side. The temporal mz_now() filter keeps the maintained arrangement
7351 -- bounded to the retention window.
7352 WHERE mz_now() <= m.occurred_at + INTERVAL '{retention}'
7353 GROUP BY
7354 m.occurred_at,
7355 m.replica_id,
7356 r.cluster_id,
7357 r.size,
7358 s.cpu_nano_cores,
7359 s.memory_bytes,
7360 s.disk_bytes,
7361 s.processes
7362)
7363SELECT
7364 m.replica_id,
7365 m.cluster_id,
7366 m.size,
7367 replica_name_history.new_name AS name,
7368 m.occurred_at,
7369 m.cpu_percent,
7370 m.memory_percent,
7371 m.disk_percent,
7372 m.heap_percent,
7373 m.memory_and_disk_percent
7374FROM replica_metrics AS m
7375/* Most recent replica name as of the sample time. */
7376CROSS JOIN LATERAL (
7377 SELECT new_name
7378 FROM mz_internal.mz_cluster_replica_name_history AS replica_name_history
7379 WHERE m.replica_id = replica_name_history.id
7380 -- We treat NULLs as the beginning of time.
7381 AND m.occurred_at >= COALESCE(replica_name_history.occurred_at, '1970-01-01'::timestamp)
7382 ORDER BY replica_name_history.occurred_at DESC
7383 LIMIT 1
7384) AS replica_name_history"#,
7385 retention = retention,
7386 )
7387}
7388
7389pub static MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW: LazyLock<BuiltinView> =
7396 LazyLock::new(|| BuiltinView {
7397 name: "mz_console_cluster_utilization_overview",
7398 schema: MZ_INTERNAL_SCHEMA,
7399 oid: oid::VIEW_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_OID,
7400 desc: console_cluster_utilization_overview_desc(),
7401 column_comments: BTreeMap::new(),
7402 sql: Box::leak(
7403 console_cluster_utilization_overview_sql("1 HOUR", "14 DAYS", 60).into_boxed_str(),
7404 ),
7405 access: vec![PUBLIC_SELECT],
7406 ontology: None,
7407 });
7408
7409pub static MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_3H: LazyLock<BuiltinView> =
7416 LazyLock::new(|| BuiltinView {
7417 name: "mz_console_cluster_utilization_overview_3h",
7418 schema: MZ_INTERNAL_SCHEMA,
7419 oid: oid::VIEW_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_3H_OID,
7420 desc: console_cluster_utilization_unbinned_3h_desc(),
7421 column_comments: BTreeMap::new(),
7422 sql: Box::leak(console_cluster_utilization_unbinned_3h_sql("3 HOURS").into_boxed_str()),
7423 access: vec![PUBLIC_SELECT],
7424 ontology: None,
7425 });
7426
7427pub static MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_24H: LazyLock<BuiltinView> =
7433 LazyLock::new(|| BuiltinView {
7434 name: "mz_console_cluster_utilization_overview_24h",
7435 schema: MZ_INTERNAL_SCHEMA,
7436 oid: oid::VIEW_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_24H_OID,
7437 desc: console_cluster_utilization_overview_desc(),
7438 column_comments: BTreeMap::new(),
7439 sql: Box::leak(
7440 console_cluster_utilization_overview_sql("5 MINUTES", "24 HOURS", 5).into_boxed_str(),
7441 ),
7442 access: vec![PUBLIC_SELECT],
7443 ontology: None,
7444 });
7445pub static MZ_CLUSTER_DEPLOYMENT_LINEAGE: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7468 name: "mz_cluster_deployment_lineage",
7469 schema: MZ_INTERNAL_SCHEMA,
7470 oid: oid::VIEW_MZ_CLUSTER_DEPLOYMENT_LINEAGE_OID,
7471 desc: RelationDesc::builder()
7472 .with_column("cluster_id", SqlScalarType::String.nullable(true))
7473 .with_column(
7474 "current_deployment_cluster_id",
7475 SqlScalarType::String.nullable(false),
7476 )
7477 .with_column("cluster_name", SqlScalarType::String.nullable(false))
7478 .with_key(vec![0, 1, 2])
7479 .finish(),
7480 column_comments: BTreeMap::from_iter([
7481 (
7482 "cluster_id",
7483 "The ID of the cluster. Corresponds to `mz_clusters.id` (though the cluster may no longer exist).",
7484 ),
7485 (
7486 "current_deployment_cluster_id",
7487 "The cluster ID of the last cluster in `cluster_id`'s blue/green lineage (the cluster is guaranteed to exist).",
7488 ),
7489 ("cluster_name", "The name of the cluster"),
7490 ]),
7491 sql: r#"WITH MUTUALLY RECURSIVE cluster_events (
7492 cluster_id text,
7493 cluster_name text,
7494 event_type text,
7495 occurred_at timestamptz
7496) AS (
7497 SELECT coalesce(details->>'id', details->>'cluster_id') AS cluster_id,
7498 coalesce(details->>'name', details->>'new_name') AS cluster_name,
7499 event_type,
7500 occurred_at
7501 FROM mz_audit_events
7502 WHERE (
7503 event_type IN ('create', 'drop')
7504 OR (
7505 event_type = 'alter'
7506 AND details ? 'new_name'
7507 )
7508 )
7509 AND object_type = 'cluster'
7510 AND mz_now() < occurred_at + INTERVAL '30 days'
7511),
7512mz_cluster_deployment_lineage (
7513 cluster_id text,
7514 current_deployment_cluster_id text,
7515 cluster_name text
7516) AS (
7517 SELECT c.id,
7518 c.id,
7519 c.name
7520 FROM mz_clusters c
7521 WHERE c.id LIKE 'u%'
7522 UNION
7523 SELECT *
7524 FROM dropped_clusters
7525),
7526-- Closest create or rename event based on the current clusters in the result set
7527most_recent_create_or_rename (
7528 cluster_id text,
7529 current_deployment_cluster_id text,
7530 cluster_name text,
7531 occurred_at timestamptz
7532) AS (
7533 SELECT DISTINCT ON (e.cluster_id) e.cluster_id,
7534 c.current_deployment_cluster_id,
7535 e.cluster_name,
7536 e.occurred_at
7537 FROM mz_cluster_deployment_lineage c
7538 JOIN cluster_events e ON c.cluster_id = e.cluster_id
7539 AND c.cluster_name = e.cluster_name
7540 WHERE e.event_type <> 'drop'
7541 ORDER BY e.cluster_id,
7542 e.occurred_at DESC
7543),
7544-- Clusters that were dropped most recently within 1 minute of most_recent_create_or_rename
7545dropped_clusters (
7546 cluster_id text,
7547 current_deployment_cluster_id text,
7548 cluster_name text
7549) AS (
7550 SELECT DISTINCT ON (cr.cluster_id) e.cluster_id,
7551 cr.current_deployment_cluster_id,
7552 cr.cluster_name
7553 FROM most_recent_create_or_rename cr
7554 JOIN cluster_events e ON e.occurred_at BETWEEN cr.occurred_at - interval '1 minute'
7555 AND cr.occurred_at + interval '1 minute'
7556 AND (
7557 e.cluster_name = cr.cluster_name
7558 OR e.cluster_name = cr.cluster_name || '_dbt_deploy'
7559 )
7560 WHERE e.event_type = 'drop'
7561 ORDER BY cr.cluster_id,
7562 abs(
7563 extract(
7564 epoch
7565 FROM cr.occurred_at - e.occurred_at
7566 )
7567 )
7568)
7569SELECT *
7570FROM mz_cluster_deployment_lineage"#,
7571 access: vec![PUBLIC_SELECT],
7572 ontology: Some(Ontology {
7573 entity_name: "cluster_deployment",
7574 description: "Cluster deployment lineage information",
7575 links: &const {
7576 [
7577 OntologyLink {
7578 name: "deployment_of",
7579 target: "cluster",
7580 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
7581 },
7582 OntologyLink {
7583 name: "current_deployment",
7584 target: "cluster",
7585 properties: LinkProperties::fk(
7586 "current_deployment_cluster_id",
7587 "id",
7588 Cardinality::ManyToOne,
7589 ),
7590 },
7591 ]
7592 },
7593 column_semantic_types: &[],
7594 }),
7595});
7596
7597pub const MZ_SHOW_DATABASES_IND: BuiltinIndex = BuiltinIndex {
7598 name: "mz_show_databases_ind",
7599 schema: MZ_INTERNAL_SCHEMA,
7600 oid: oid::INDEX_MZ_SHOW_DATABASES_IND_OID,
7601 sql: "IN CLUSTER mz_catalog_server
7602ON mz_internal.mz_show_databases (name)",
7603 is_retained_metrics_object: false,
7604};
7605
7606pub const MZ_SHOW_SCHEMAS_IND: BuiltinIndex = BuiltinIndex {
7607 name: "mz_show_schemas_ind",
7608 schema: MZ_INTERNAL_SCHEMA,
7609 oid: oid::INDEX_MZ_SHOW_SCHEMAS_IND_OID,
7610 sql: "IN CLUSTER mz_catalog_server
7611ON mz_internal.mz_show_schemas (database_id)",
7612 is_retained_metrics_object: false,
7613};
7614
7615pub const MZ_SHOW_CONNECTIONS_IND: BuiltinIndex = BuiltinIndex {
7616 name: "mz_show_connections_ind",
7617 schema: MZ_INTERNAL_SCHEMA,
7618 oid: oid::INDEX_MZ_SHOW_CONNECTIONS_IND_OID,
7619 sql: "IN CLUSTER mz_catalog_server
7620ON mz_internal.mz_show_connections (schema_id)",
7621 is_retained_metrics_object: false,
7622};
7623
7624pub const MZ_SHOW_TABLES_IND: BuiltinIndex = BuiltinIndex {
7625 name: "mz_show_tables_ind",
7626 schema: MZ_INTERNAL_SCHEMA,
7627 oid: oid::INDEX_MZ_SHOW_TABLES_IND_OID,
7628 sql: "IN CLUSTER mz_catalog_server
7629ON mz_internal.mz_show_tables (schema_id)",
7630 is_retained_metrics_object: false,
7631};
7632
7633pub const MZ_SHOW_SOURCES_IND: BuiltinIndex = BuiltinIndex {
7634 name: "mz_show_sources_ind",
7635 schema: MZ_INTERNAL_SCHEMA,
7636 oid: oid::INDEX_MZ_SHOW_SOURCES_IND_OID,
7637 sql: "IN CLUSTER mz_catalog_server
7638ON mz_internal.mz_show_sources (schema_id)",
7639 is_retained_metrics_object: false,
7640};
7641
7642pub const MZ_SHOW_VIEWS_IND: BuiltinIndex = BuiltinIndex {
7643 name: "mz_show_views_ind",
7644 schema: MZ_INTERNAL_SCHEMA,
7645 oid: oid::INDEX_MZ_SHOW_VIEWS_IND_OID,
7646 sql: "IN CLUSTER mz_catalog_server
7647ON mz_internal.mz_show_views (schema_id)",
7648 is_retained_metrics_object: false,
7649};
7650
7651pub const MZ_SHOW_MATERIALIZED_VIEWS_IND: BuiltinIndex = BuiltinIndex {
7652 name: "mz_show_materialized_views_ind",
7653 schema: MZ_INTERNAL_SCHEMA,
7654 oid: oid::INDEX_MZ_SHOW_MATERIALIZED_VIEWS_IND_OID,
7655 sql: "IN CLUSTER mz_catalog_server
7656ON mz_internal.mz_show_materialized_views (schema_id)",
7657 is_retained_metrics_object: false,
7658};
7659
7660pub const MZ_SHOW_SINKS_IND: BuiltinIndex = BuiltinIndex {
7661 name: "mz_show_sinks_ind",
7662 schema: MZ_INTERNAL_SCHEMA,
7663 oid: oid::INDEX_MZ_SHOW_SINKS_IND_OID,
7664 sql: "IN CLUSTER mz_catalog_server
7665ON mz_internal.mz_show_sinks (schema_id)",
7666 is_retained_metrics_object: false,
7667};
7668
7669pub const MZ_SHOW_TYPES_IND: BuiltinIndex = BuiltinIndex {
7670 name: "mz_show_types_ind",
7671 schema: MZ_INTERNAL_SCHEMA,
7672 oid: oid::INDEX_MZ_SHOW_TYPES_IND_OID,
7673 sql: "IN CLUSTER mz_catalog_server
7674ON mz_internal.mz_show_types (schema_id)",
7675 is_retained_metrics_object: false,
7676};
7677
7678pub const MZ_SHOW_ROLES_IND: BuiltinIndex = BuiltinIndex {
7679 name: "mz_show_roles_ind",
7680 schema: MZ_INTERNAL_SCHEMA,
7681 oid: oid::INDEX_MZ_SHOW_ROLES_IND_OID,
7682 sql: "IN CLUSTER mz_catalog_server
7683ON mz_internal.mz_show_roles (name)",
7684 is_retained_metrics_object: false,
7685};
7686
7687pub const MZ_SHOW_ALL_OBJECTS_IND: BuiltinIndex = BuiltinIndex {
7688 name: "mz_show_all_objects_ind",
7689 schema: MZ_INTERNAL_SCHEMA,
7690 oid: oid::INDEX_MZ_SHOW_ALL_OBJECTS_IND_OID,
7691 sql: "IN CLUSTER mz_catalog_server
7692ON mz_internal.mz_show_all_objects (schema_id)",
7693 is_retained_metrics_object: false,
7694};
7695
7696pub const MZ_SHOW_INDEXES_IND: BuiltinIndex = BuiltinIndex {
7697 name: "mz_show_indexes_ind",
7698 schema: MZ_INTERNAL_SCHEMA,
7699 oid: oid::INDEX_MZ_SHOW_INDEXES_IND_OID,
7700 sql: "IN CLUSTER mz_catalog_server
7701ON mz_internal.mz_show_indexes (schema_id)",
7702 is_retained_metrics_object: false,
7703};
7704
7705pub const MZ_SHOW_COLUMNS_IND: BuiltinIndex = BuiltinIndex {
7706 name: "mz_show_columns_ind",
7707 schema: MZ_INTERNAL_SCHEMA,
7708 oid: oid::INDEX_MZ_SHOW_COLUMNS_IND_OID,
7709 sql: "IN CLUSTER mz_catalog_server
7710ON mz_internal.mz_show_columns (id)",
7711 is_retained_metrics_object: false,
7712};
7713
7714pub const MZ_SHOW_CLUSTERS_IND: BuiltinIndex = BuiltinIndex {
7715 name: "mz_show_clusters_ind",
7716 schema: MZ_INTERNAL_SCHEMA,
7717 oid: oid::INDEX_MZ_SHOW_CLUSTERS_IND_OID,
7718 sql: "IN CLUSTER mz_catalog_server
7719ON mz_internal.mz_show_clusters (name)",
7720 is_retained_metrics_object: false,
7721};
7722
7723pub const MZ_SHOW_CLUSTER_REPLICAS_IND: BuiltinIndex = BuiltinIndex {
7724 name: "mz_show_cluster_replicas_ind",
7725 schema: MZ_INTERNAL_SCHEMA,
7726 oid: oid::INDEX_MZ_SHOW_CLUSTER_REPLICAS_IND_OID,
7727 sql: "IN CLUSTER mz_catalog_server
7728ON mz_internal.mz_show_cluster_replicas (cluster)",
7729 is_retained_metrics_object: false,
7730};
7731
7732pub const MZ_SHOW_SECRETS_IND: BuiltinIndex = BuiltinIndex {
7733 name: "mz_show_secrets_ind",
7734 schema: MZ_INTERNAL_SCHEMA,
7735 oid: oid::INDEX_MZ_SHOW_SECRETS_IND_OID,
7736 sql: "IN CLUSTER mz_catalog_server
7737ON mz_internal.mz_show_secrets (schema_id)",
7738 is_retained_metrics_object: false,
7739};
7740
7741pub const MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_IND: BuiltinIndex = BuiltinIndex {
7742 name: "mz_console_cluster_utilization_overview_ind",
7743 schema: MZ_INTERNAL_SCHEMA,
7744 oid: oid::INDEX_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_IND_OID,
7745 sql: "IN CLUSTER mz_catalog_server
7746ON mz_internal.mz_console_cluster_utilization_overview (cluster_id)",
7747 is_retained_metrics_object: false,
7748};
7749
7750pub const MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_3H_IND: BuiltinIndex = BuiltinIndex {
7751 name: "mz_console_cluster_utilization_overview_3h_ind",
7752 schema: MZ_INTERNAL_SCHEMA,
7753 oid: oid::INDEX_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_3H_IND_OID,
7754 sql: "IN CLUSTER mz_catalog_server
7755ON mz_internal.mz_console_cluster_utilization_overview_3h (cluster_id)",
7756 is_retained_metrics_object: false,
7757};
7758
7759pub const MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_24H_IND: BuiltinIndex = BuiltinIndex {
7760 name: "mz_console_cluster_utilization_overview_24h_ind",
7761 schema: MZ_INTERNAL_SCHEMA,
7762 oid: oid::INDEX_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_24H_IND_OID,
7763 sql: "IN CLUSTER mz_catalog_server
7764ON mz_internal.mz_console_cluster_utilization_overview_24h (cluster_id)",
7765 is_retained_metrics_object: false,
7766};
7767
7768pub const MZ_CLUSTER_DEPLOYMENT_LINEAGE_IND: BuiltinIndex = BuiltinIndex {
7769 name: "mz_cluster_deployment_lineage_ind",
7770 schema: MZ_INTERNAL_SCHEMA,
7771 oid: oid::INDEX_MZ_CLUSTER_DEPLOYMENT_LINEAGE_IND_OID,
7772 sql: "IN CLUSTER mz_catalog_server
7773ON mz_internal.mz_cluster_deployment_lineage (cluster_id)",
7774 is_retained_metrics_object: false,
7775};
7776
7777pub const MZ_SOURCE_STATUSES_IND: BuiltinIndex = BuiltinIndex {
7778 name: "mz_source_statuses_ind",
7779 schema: MZ_INTERNAL_SCHEMA,
7780 oid: oid::INDEX_MZ_SOURCE_STATUSES_IND_OID,
7781 sql: "IN CLUSTER mz_catalog_server
7782ON mz_internal.mz_source_statuses (id)",
7783 is_retained_metrics_object: false,
7784};
7785
7786pub const MZ_SINK_STATUSES_IND: BuiltinIndex = BuiltinIndex {
7787 name: "mz_sink_statuses_ind",
7788 schema: MZ_INTERNAL_SCHEMA,
7789 oid: oid::INDEX_MZ_SINK_STATUSES_IND_OID,
7790 sql: "IN CLUSTER mz_catalog_server
7791ON mz_internal.mz_sink_statuses (id)",
7792 is_retained_metrics_object: false,
7793};
7794
7795pub const MZ_SOURCE_STATUS_HISTORY_IND: BuiltinIndex = BuiltinIndex {
7796 name: "mz_source_status_history_ind",
7797 schema: MZ_INTERNAL_SCHEMA,
7798 oid: oid::INDEX_MZ_SOURCE_STATUS_HISTORY_IND_OID,
7799 sql: "IN CLUSTER mz_catalog_server
7800ON mz_internal.mz_source_status_history (source_id)",
7801 is_retained_metrics_object: false,
7802};
7803
7804pub const MZ_SINK_STATUS_HISTORY_IND: BuiltinIndex = BuiltinIndex {
7805 name: "mz_sink_status_history_ind",
7806 schema: MZ_INTERNAL_SCHEMA,
7807 oid: oid::INDEX_MZ_SINK_STATUS_HISTORY_IND_OID,
7808 sql: "IN CLUSTER mz_catalog_server
7809ON mz_internal.mz_sink_status_history (sink_id)",
7810 is_retained_metrics_object: false,
7811};
7812
7813pub static MZ_SOURCE_STATISTICS_WITH_HISTORY: LazyLock<BuiltinView> =
7826 LazyLock::new(|| BuiltinView {
7827 name: "mz_source_statistics_with_history",
7828 schema: MZ_INTERNAL_SCHEMA,
7829 oid: oid::VIEW_MZ_SOURCE_STATISTICS_WITH_HISTORY_OID,
7830 desc: RelationDesc::builder()
7831 .with_column("id", SqlScalarType::String.nullable(false))
7832 .with_column("replica_id", SqlScalarType::String.nullable(true))
7833 .with_column("messages_received", SqlScalarType::UInt64.nullable(false))
7834 .with_column("bytes_received", SqlScalarType::UInt64.nullable(false))
7835 .with_column("updates_staged", SqlScalarType::UInt64.nullable(false))
7836 .with_column("updates_committed", SqlScalarType::UInt64.nullable(false))
7837 .with_column("records_indexed", SqlScalarType::UInt64.nullable(false))
7838 .with_column("bytes_indexed", SqlScalarType::UInt64.nullable(false))
7839 .with_column(
7840 "rehydration_latency",
7841 SqlScalarType::Interval.nullable(true),
7842 )
7843 .with_column(
7844 "snapshot_records_known",
7845 SqlScalarType::UInt64.nullable(true),
7846 )
7847 .with_column(
7848 "snapshot_records_staged",
7849 SqlScalarType::UInt64.nullable(true),
7850 )
7851 .with_column("snapshot_committed", SqlScalarType::Bool.nullable(false))
7852 .with_column("offset_known", SqlScalarType::UInt64.nullable(true))
7853 .with_column("offset_committed", SqlScalarType::UInt64.nullable(true))
7854 .with_key(vec![0, 1])
7855 .finish(),
7856 column_comments: BTreeMap::new(),
7857 sql: "
7858WITH
7859 -- For each subsource, statistics are reported as its parent source
7860 subsource_to_parent AS
7861 (
7862 SELECT subsource.id AS id, parent.id AS report_id
7863 FROM mz_catalog.mz_sources AS subsource
7864 JOIN mz_internal.mz_object_dependencies AS dep ON subsource.id = dep.object_id
7865 JOIN mz_catalog.mz_sources AS parent ON parent.id = dep.referenced_object_id
7866 WHERE subsource.type = 'subsource'
7867 ),
7868 -- For each table from source, statistics are reported as its parent source
7869 table_to_parent AS
7870 (
7871 SELECT id, source_id AS report_id
7872 FROM mz_catalog.mz_tables
7873 WHERE source_id IS NOT NULL
7874 ),
7875 -- For each source and subsource, statistics are reported as itself
7876 source_refl AS
7877 (
7878 SELECT id, id AS report_id
7879 FROM mz_catalog.mz_sources
7880 WHERE type NOT IN ('progress', 'log')
7881 ),
7882 -- For each table from source, statistics are reported as itself
7883 table_refl AS
7884 (
7885 SELECT id, id AS report_id
7886 FROM mz_catalog.mz_tables
7887 WHERE source_id IS NOT NULL
7888 ),
7889 report_paths AS
7890 (
7891 SELECT id, report_id FROM subsource_to_parent
7892 UNION ALL SELECT id, report_id FROM table_to_parent
7893 UNION ALL SELECT id, report_id FROM source_refl
7894 UNION ALL SELECT id, report_id FROM table_refl
7895 )
7896SELECT
7897 report_paths.report_id AS id,
7898 replica_id,
7899 -- Counters
7900 SUM(messages_received)::uint8 AS messages_received,
7901 SUM(bytes_received)::uint8 AS bytes_received,
7902 SUM(updates_staged)::uint8 AS updates_staged,
7903 SUM(updates_committed)::uint8 AS updates_committed,
7904 -- Resetting Gauges
7905 SUM(records_indexed)::uint8 AS records_indexed,
7906 SUM(bytes_indexed)::uint8 AS bytes_indexed,
7907 -- Ensure we aggregate to NULL when not all workers are done rehydrating.
7908 CASE
7909 WHEN bool_or(rehydration_latency IS NULL) THEN NULL
7910 ELSE MAX(rehydration_latency)::interval
7911 END AS rehydration_latency,
7912 SUM(snapshot_records_known)::uint8 AS snapshot_records_known,
7913 SUM(snapshot_records_staged)::uint8 AS snapshot_records_staged,
7914 bool_and(snapshot_committed) as snapshot_committed,
7915 -- Gauges
7916 MAX(offset_known)::uint8 AS offset_known,
7917 MIN(offset_committed)::uint8 AS offset_committed
7918FROM mz_internal.mz_source_statistics_raw
7919 JOIN report_paths USING (id)
7920GROUP BY report_paths.report_id, replica_id",
7921 access: vec![PUBLIC_SELECT],
7922 ontology: None,
7923 });
7924
7925pub const MZ_SOURCE_STATISTICS_WITH_HISTORY_IND: BuiltinIndex = BuiltinIndex {
7926 name: "mz_source_statistics_with_history_ind",
7927 schema: MZ_INTERNAL_SCHEMA,
7928 oid: oid::INDEX_MZ_SOURCE_STATISTICS_WITH_HISTORY_IND_OID,
7929 sql: "IN CLUSTER mz_catalog_server
7930ON mz_internal.mz_source_statistics_with_history (id, replica_id)",
7931 is_retained_metrics_object: true,
7932};
7933
7934pub static MZ_SOURCE_STATISTICS: LazyLock<BuiltinView> = LazyLock::new(|| {
7937 BuiltinView {
7938 name: "mz_source_statistics",
7939 schema: MZ_INTERNAL_SCHEMA,
7940 oid: oid::VIEW_MZ_SOURCE_STATISTICS_OID,
7941 desc: RelationDesc::builder()
7943 .with_column("id", SqlScalarType::String.nullable(false))
7944 .with_column("replica_id", SqlScalarType::String.nullable(true))
7945 .with_column("messages_received", SqlScalarType::UInt64.nullable(false))
7946 .with_column("bytes_received", SqlScalarType::UInt64.nullable(false))
7947 .with_column("updates_staged", SqlScalarType::UInt64.nullable(false))
7948 .with_column("updates_committed", SqlScalarType::UInt64.nullable(false))
7949 .with_column("records_indexed", SqlScalarType::UInt64.nullable(false))
7950 .with_column("bytes_indexed", SqlScalarType::UInt64.nullable(false))
7951 .with_column(
7952 "rehydration_latency",
7953 SqlScalarType::Interval.nullable(true),
7954 )
7955 .with_column(
7956 "snapshot_records_known",
7957 SqlScalarType::UInt64.nullable(true),
7958 )
7959 .with_column(
7960 "snapshot_records_staged",
7961 SqlScalarType::UInt64.nullable(true),
7962 )
7963 .with_column("snapshot_committed", SqlScalarType::Bool.nullable(false))
7964 .with_column("offset_known", SqlScalarType::UInt64.nullable(true))
7965 .with_column("offset_committed", SqlScalarType::UInt64.nullable(true))
7966 .with_key(vec![0, 1])
7967 .finish(),
7968 column_comments: BTreeMap::from_iter([
7969 (
7970 "id",
7971 "The ID of the source. Corresponds to `mz_catalog.mz_sources.id`.",
7972 ),
7973 (
7974 "replica_id",
7975 "The ID of a replica running the source. Corresponds to `mz_catalog.mz_cluster_replicas.id`.",
7976 ),
7977 (
7978 "messages_received",
7979 "The number of messages the source has received from the external system. Messages are counted in a source type-specific manner. Messages do not correspond directly to updates: some messages produce multiple updates, while other messages may be coalesced into a single update.",
7980 ),
7981 (
7982 "bytes_received",
7983 "The number of bytes the source has read from the external system. Bytes are counted in a source type-specific manner and may or may not include protocol overhead.",
7984 ),
7985 (
7986 "updates_staged",
7987 "The number of updates (insertions plus deletions) the source has written but not yet committed to the storage layer.",
7988 ),
7989 (
7990 "updates_committed",
7991 "The number of updates (insertions plus deletions) the source has committed to the storage layer.",
7992 ),
7993 (
7994 "records_indexed",
7995 "The number of individual records indexed in the source envelope state.",
7996 ),
7997 (
7998 "bytes_indexed",
7999 "The number of bytes stored in the source's internal index, if any.",
8000 ),
8001 (
8002 "rehydration_latency",
8003 "The amount of time it took for the source to rehydrate its internal index, if any, after the source last restarted.",
8004 ),
8005 (
8006 "snapshot_records_known",
8007 "The size of the source's snapshot, measured in number of records. See below to learn what constitutes a record.",
8008 ),
8009 (
8010 "snapshot_records_staged",
8011 "The number of records in the source's snapshot that Materialize has read. See below to learn what constitutes a record.",
8012 ),
8013 (
8014 "snapshot_committed",
8015 "Whether the source has committed the initial snapshot for a source.",
8016 ),
8017 (
8018 "offset_known",
8019 "The offset of the most recent data in the source's upstream service that Materialize knows about. See below to learn what constitutes an offset.",
8020 ),
8021 (
8022 "offset_committed",
8023 "The offset of the the data that Materialize has durably ingested. See below to learn what constitutes an offset.",
8024 ),
8025 ]),
8026 sql: "SELECT * FROM mz_internal.mz_source_statistics_with_history WHERE length(id) > 0",
8027 access: vec![PUBLIC_SELECT],
8028 ontology: Some(Ontology {
8029 entity_name: "source_statistics",
8030 description: "Aggregated source ingestion statistics",
8031 links: &const {
8032 [OntologyLink {
8033 name: "statistics_of_source",
8034 target: "source",
8035 properties: LinkProperties::measures("id", "id", "ingestion_statistics"),
8036 }]
8037 },
8038 column_semantic_types: &const {
8039 [
8040 ("id", SemanticType::CatalogItemId),
8041 ("replica_id", SemanticType::ReplicaId),
8042 ("messages_received", SemanticType::RecordCount),
8043 ("bytes_received", SemanticType::ByteCount),
8044 ("updates_staged", SemanticType::RecordCount),
8045 ("updates_committed", SemanticType::RecordCount),
8046 ("records_indexed", SemanticType::RecordCount),
8047 ("bytes_indexed", SemanticType::ByteCount),
8048 ("snapshot_records_known", SemanticType::RecordCount),
8049 ("snapshot_records_staged", SemanticType::RecordCount),
8050 ]
8051 },
8052 }),
8053 }
8054});
8055
8056pub const MZ_SOURCE_STATISTICS_IND: BuiltinIndex = BuiltinIndex {
8057 name: "mz_source_statistics_ind",
8058 schema: MZ_INTERNAL_SCHEMA,
8059 oid: oid::INDEX_MZ_SOURCE_STATISTICS_IND_OID,
8060 sql: "IN CLUSTER mz_catalog_server
8061ON mz_internal.mz_source_statistics (id, replica_id)",
8062 is_retained_metrics_object: false,
8063};
8064
8065pub static MZ_SINK_STATISTICS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
8066 name: "mz_sink_statistics",
8067 schema: MZ_INTERNAL_SCHEMA,
8068 oid: oid::VIEW_MZ_SINK_STATISTICS_OID,
8069 desc: RelationDesc::builder()
8070 .with_column("id", SqlScalarType::String.nullable(false))
8071 .with_column("replica_id", SqlScalarType::String.nullable(true))
8072 .with_column("messages_staged", SqlScalarType::UInt64.nullable(false))
8073 .with_column("messages_committed", SqlScalarType::UInt64.nullable(false))
8074 .with_column("bytes_staged", SqlScalarType::UInt64.nullable(false))
8075 .with_column("bytes_committed", SqlScalarType::UInt64.nullable(false))
8076 .with_key(vec![0, 1])
8077 .finish(),
8078 column_comments: BTreeMap::from_iter([
8079 (
8080 "id",
8081 "The ID of the sink. Corresponds to `mz_catalog.mz_sinks.id`.",
8082 ),
8083 (
8084 "replica_id",
8085 "The ID of a replica running the sink. Corresponds to `mz_catalog.mz_cluster_replicas.id`.",
8086 ),
8087 (
8088 "messages_staged",
8089 "The number of messages staged but possibly not committed to the sink.",
8090 ),
8091 (
8092 "messages_committed",
8093 "The number of messages committed to the sink.",
8094 ),
8095 (
8096 "bytes_staged",
8097 "The number of bytes staged but possibly not committed to the sink. This counts both keys and values, if applicable.",
8098 ),
8099 (
8100 "bytes_committed",
8101 "The number of bytes committed to the sink. This counts both keys and values, if applicable.",
8102 ),
8103 ]),
8104 sql: "
8105SELECT
8106 id,
8107 replica_id,
8108 SUM(messages_staged)::uint8 AS messages_staged,
8109 SUM(messages_committed)::uint8 AS messages_committed,
8110 SUM(bytes_staged)::uint8 AS bytes_staged,
8111 SUM(bytes_committed)::uint8 AS bytes_committed
8112FROM mz_internal.mz_sink_statistics_raw
8113GROUP BY id, replica_id",
8114 access: vec![PUBLIC_SELECT],
8115 ontology: Some(Ontology {
8116 entity_name: "sink_statistics",
8117 description: "Aggregated sink export statistics",
8118 links: &const {
8119 [OntologyLink {
8120 name: "statistics_of_sink",
8121 target: "sink",
8122 properties: LinkProperties::measures("id", "id", "export_statistics"),
8123 }]
8124 },
8125 column_semantic_types: &const {
8126 [
8127 ("id", SemanticType::CatalogItemId),
8128 ("replica_id", SemanticType::ReplicaId),
8129 ("messages_staged", SemanticType::RecordCount),
8130 ("messages_committed", SemanticType::RecordCount),
8131 ("bytes_staged", SemanticType::ByteCount),
8132 ("bytes_committed", SemanticType::ByteCount),
8133 ]
8134 },
8135 }),
8136});
8137
8138pub const MZ_SINK_STATISTICS_IND: BuiltinIndex = BuiltinIndex {
8139 name: "mz_sink_statistics_ind",
8140 schema: MZ_INTERNAL_SCHEMA,
8141 oid: oid::INDEX_MZ_SINK_STATISTICS_IND_OID,
8142 sql: "IN CLUSTER mz_catalog_server
8143ON mz_internal.mz_sink_statistics (id, replica_id)",
8144 is_retained_metrics_object: true,
8145};
8146
8147pub const MZ_CLUSTER_REPLICA_STATUSES_IND: BuiltinIndex = BuiltinIndex {
8148 name: "mz_cluster_replica_statuses_ind",
8149 schema: MZ_INTERNAL_SCHEMA,
8150 oid: oid::INDEX_MZ_CLUSTER_REPLICA_STATUSES_IND_OID,
8151 sql: "IN CLUSTER mz_catalog_server
8152ON mz_internal.mz_cluster_replica_statuses (replica_id)",
8153 is_retained_metrics_object: false,
8154};
8155
8156pub const MZ_CLUSTER_REPLICA_STATUS_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8157 name: "mz_cluster_replica_status_history_ind",
8158 schema: MZ_INTERNAL_SCHEMA,
8159 oid: oid::INDEX_MZ_CLUSTER_REPLICA_STATUS_HISTORY_IND_OID,
8160 sql: "IN CLUSTER mz_catalog_server
8161ON mz_internal.mz_cluster_replica_status_history (replica_id)",
8162 is_retained_metrics_object: false,
8163};
8164
8165pub const MZ_CLUSTER_REPLICA_METRICS_IND: BuiltinIndex = BuiltinIndex {
8166 name: "mz_cluster_replica_metrics_ind",
8167 schema: MZ_INTERNAL_SCHEMA,
8168 oid: oid::INDEX_MZ_CLUSTER_REPLICA_METRICS_IND_OID,
8169 sql: "IN CLUSTER mz_catalog_server
8170ON mz_internal.mz_cluster_replica_metrics (replica_id)",
8171 is_retained_metrics_object: false,
8172};
8173
8174pub const MZ_CLUSTER_REPLICA_METRICS_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8175 name: "mz_cluster_replica_metrics_history_ind",
8176 schema: MZ_INTERNAL_SCHEMA,
8177 oid: oid::INDEX_MZ_CLUSTER_REPLICA_METRICS_HISTORY_IND_OID,
8178 sql: "IN CLUSTER mz_catalog_server
8179ON mz_internal.mz_cluster_replica_metrics_history (replica_id)",
8180 is_retained_metrics_object: false,
8181};
8182
8183pub const MZ_CLUSTER_REPLICA_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8184 name: "mz_cluster_replica_history_ind",
8185 schema: MZ_INTERNAL_SCHEMA,
8186 oid: oid::INDEX_MZ_CLUSTER_REPLICA_HISTORY_IND_OID,
8187 sql: "IN CLUSTER mz_catalog_server
8188ON mz_internal.mz_cluster_replica_history (dropped_at)",
8189 is_retained_metrics_object: true,
8190};
8191
8192pub const MZ_CLUSTER_REPLICA_NAME_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8193 name: "mz_cluster_replica_name_history_ind",
8194 schema: MZ_INTERNAL_SCHEMA,
8195 oid: oid::INDEX_MZ_CLUSTER_REPLICA_NAME_HISTORY_IND_OID,
8196 sql: "IN CLUSTER mz_catalog_server
8197ON mz_internal.mz_cluster_replica_name_history (id)",
8198 is_retained_metrics_object: false,
8199};
8200
8201pub const MZ_OBJECT_LIFETIMES_IND: BuiltinIndex = BuiltinIndex {
8202 name: "mz_object_lifetimes_ind",
8203 schema: MZ_INTERNAL_SCHEMA,
8204 oid: oid::INDEX_MZ_OBJECT_LIFETIMES_IND_OID,
8205 sql: "IN CLUSTER mz_catalog_server
8206ON mz_internal.mz_object_lifetimes (id)",
8207 is_retained_metrics_object: false,
8208};
8209
8210pub const MZ_OBJECT_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8211 name: "mz_object_history_ind",
8212 schema: MZ_INTERNAL_SCHEMA,
8213 oid: oid::INDEX_MZ_OBJECT_HISTORY_IND_OID,
8214 sql: "IN CLUSTER mz_catalog_server
8215ON mz_internal.mz_object_history (id)",
8216 is_retained_metrics_object: false,
8217};
8218
8219pub const MZ_OBJECT_DEPENDENCIES_IND: BuiltinIndex = BuiltinIndex {
8220 name: "mz_object_dependencies_ind",
8221 schema: MZ_INTERNAL_SCHEMA,
8222 oid: oid::INDEX_MZ_OBJECT_DEPENDENCIES_IND_OID,
8223 sql: "IN CLUSTER mz_catalog_server
8224ON mz_internal.mz_object_dependencies (object_id)",
8225 is_retained_metrics_object: true,
8226};
8227
8228pub const MZ_COMPUTE_DEPENDENCIES_IND: BuiltinIndex = BuiltinIndex {
8229 name: "mz_compute_dependencies_ind",
8230 schema: MZ_INTERNAL_SCHEMA,
8231 oid: oid::INDEX_MZ_COMPUTE_DEPENDENCIES_IND_OID,
8232 sql: "IN CLUSTER mz_catalog_server
8233ON mz_internal.mz_compute_dependencies (dependency_id)",
8234 is_retained_metrics_object: false,
8235};
8236
8237pub const MZ_OBJECT_TRANSITIVE_DEPENDENCIES_IND: BuiltinIndex = BuiltinIndex {
8238 name: "mz_object_transitive_dependencies_ind",
8239 schema: MZ_INTERNAL_SCHEMA,
8240 oid: oid::INDEX_MZ_OBJECT_TRANSITIVE_DEPENDENCIES_IND_OID,
8241 sql: "IN CLUSTER mz_catalog_server
8242ON mz_internal.mz_object_transitive_dependencies (object_id)",
8243 is_retained_metrics_object: false,
8244};
8245
8246pub const MZ_FRONTIERS_IND: BuiltinIndex = BuiltinIndex {
8247 name: "mz_frontiers_ind",
8248 schema: MZ_INTERNAL_SCHEMA,
8249 oid: oid::INDEX_MZ_FRONTIERS_IND_OID,
8250 sql: "IN CLUSTER mz_catalog_server
8251ON mz_internal.mz_frontiers (object_id)",
8252 is_retained_metrics_object: false,
8253};
8254
8255pub const MZ_WALLCLOCK_GLOBAL_LAG_RECENT_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8256 name: "mz_wallclock_global_lag_recent_history_ind",
8257 schema: MZ_INTERNAL_SCHEMA,
8258 oid: oid::INDEX_MZ_WALLCLOCK_GLOBAL_LAG_RECENT_HISTORY_IND_OID,
8259 sql: "IN CLUSTER mz_catalog_server
8260ON mz_internal.mz_wallclock_global_lag_recent_history (object_id)",
8261 is_retained_metrics_object: false,
8262};
8263
8264pub const MZ_RECENT_ACTIVITY_LOG_THINNED_IND: BuiltinIndex = BuiltinIndex {
8265 name: "mz_recent_activity_log_thinned_ind",
8266 schema: MZ_INTERNAL_SCHEMA,
8267 oid: oid::INDEX_MZ_RECENT_ACTIVITY_LOG_THINNED_IND_OID,
8268 sql: "IN CLUSTER mz_catalog_server
8269-- sql_hash because we plan to join
8270-- this against mz_internal.mz_sql_text
8271ON mz_internal.mz_recent_activity_log_thinned (sql_hash)",
8272 is_retained_metrics_object: false,
8273};
8274
8275pub const MZ_WEBHOOK_SOURCES_IND: BuiltinIndex = BuiltinIndex {
8276 name: "mz_webhook_sources_ind",
8277 schema: MZ_INTERNAL_SCHEMA,
8278 oid: oid::INDEX_MZ_WEBHOOK_SOURCES_IND_OID,
8279 sql: "IN CLUSTER mz_catalog_server
8280ON mz_internal.mz_webhook_sources (id)",
8281 is_retained_metrics_object: true,
8282};
8283
8284pub const MZ_COMMENTS_IND: BuiltinIndex = BuiltinIndex {
8285 name: "mz_comments_ind",
8286 schema: MZ_INTERNAL_SCHEMA,
8287 oid: oid::INDEX_MZ_COMMENTS_IND_OID,
8288 sql: "IN CLUSTER mz_catalog_server
8289ON mz_internal.mz_comments (id)",
8290 is_retained_metrics_object: true,
8291};
8292
8293pub static MZ_ANALYTICS: BuiltinConnection = BuiltinConnection {
8294 name: "mz_analytics",
8295 schema: MZ_INTERNAL_SCHEMA,
8296 oid: oid::CONNECTION_MZ_ANALYTICS_OID,
8297 sql: "CREATE CONNECTION mz_internal.mz_analytics TO AWS (ASSUME ROLE ARN = '')",
8298 access: &[MzAclItem {
8299 grantee: MZ_SYSTEM_ROLE_ID,
8300 grantor: MZ_ANALYTICS_ROLE_ID,
8301 acl_mode: rbac::all_object_privileges(SystemObjectType::Object(ObjectType::Connection)),
8302 }],
8303 owner_id: &MZ_ANALYTICS_ROLE_ID,
8304 runtime_alterable: true,
8305};