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