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