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