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 ]),
2738 is_retained_metrics_object: false,
2739 access: vec![PUBLIC_SELECT],
2740 ontology: None,
2741 });
2742
2743pub static MZ_CLUSTER_REPLICA_METRICS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2744 name: "mz_cluster_replica_metrics",
2745 schema: MZ_INTERNAL_SCHEMA,
2746 oid: oid::VIEW_MZ_CLUSTER_REPLICA_METRICS_OID,
2747 desc: RelationDesc::builder()
2748 .with_column("replica_id", SqlScalarType::String.nullable(false))
2749 .with_column("process_id", SqlScalarType::UInt64.nullable(false))
2750 .with_column("cpu_nano_cores", SqlScalarType::UInt64.nullable(true))
2751 .with_column("memory_bytes", SqlScalarType::UInt64.nullable(true))
2752 .with_column("disk_bytes", SqlScalarType::UInt64.nullable(true))
2753 .with_column("heap_bytes", SqlScalarType::UInt64.nullable(true))
2754 .with_column("heap_limit", SqlScalarType::UInt64.nullable(true))
2755 .with_key(vec![0, 1])
2756 .finish(),
2757 column_comments: BTreeMap::from_iter([
2758 ("replica_id", "The ID of a cluster replica."),
2759 ("process_id", "The ID of a process within the replica."),
2760 (
2761 "cpu_nano_cores",
2762 "Approximate CPU usage, in billionths of a vCPU core.",
2763 ),
2764 ("memory_bytes", "Approximate RAM usage, in bytes."),
2765 ("disk_bytes", "Approximate disk usage, in bytes."),
2766 (
2767 "heap_bytes",
2768 "Approximate heap (RAM + swap) usage, in bytes.",
2769 ),
2770 ("heap_limit", "Available heap (RAM + swap) space, in bytes."),
2771 ]),
2772 sql: "
2773SELECT
2774 DISTINCT ON (replica_id, process_id)
2775 replica_id,
2776 process_id,
2777 cpu_nano_cores,
2778 memory_bytes,
2779 disk_bytes,
2780 heap_bytes,
2781 heap_limit
2782FROM mz_internal.mz_cluster_replica_metrics_history
2783JOIN mz_cluster_replicas r ON r.id = replica_id
2784ORDER BY replica_id, process_id, occurred_at DESC",
2785 access: vec![PUBLIC_SELECT],
2786 ontology: Some(Ontology {
2787 entity_name: "replica_metrics",
2788 description: "CPU and memory metrics per replica",
2789 links: &const {
2790 [OntologyLink {
2791 name: "metrics_of_replica",
2792 target: "replica",
2793 properties: LinkProperties::fk_typed(
2794 "replica_id",
2795 "id",
2796 Cardinality::OneToOne,
2797 mz_repr::SemanticType::CatalogItemId,
2798 ),
2799 }]
2800 },
2801 column_semantic_types: &const {
2802 [
2803 ("replica_id", SemanticType::ReplicaId),
2804 ("memory_bytes", SemanticType::ByteCount),
2805 ("disk_bytes", SemanticType::ByteCount),
2806 ("heap_bytes", SemanticType::ByteCount),
2807 ("heap_limit", SemanticType::ByteCount),
2808 ]
2809 },
2810 }),
2811});
2812
2813pub static MZ_FRONTIERS: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
2814 name: "mz_frontiers",
2815 schema: MZ_INTERNAL_SCHEMA,
2816 oid: oid::SOURCE_MZ_FRONTIERS_OID,
2817 data_source: IntrospectionType::Frontiers.into(),
2818 desc: RelationDesc::builder()
2819 .with_column("object_id", SqlScalarType::String.nullable(false))
2820 .with_column("read_frontier", SqlScalarType::MzTimestamp.nullable(true))
2821 .with_column("write_frontier", SqlScalarType::MzTimestamp.nullable(true))
2822 .finish(),
2823 column_comments: BTreeMap::from_iter([
2824 (
2825 "object_id",
2826 "The ID of the source, sink, table, index, materialized view, or subscription.",
2827 ),
2828 (
2829 "read_frontier",
2830 "The earliest timestamp at which the output is still readable.",
2831 ),
2832 (
2833 "write_frontier",
2834 "The next timestamp at which the output may change.",
2835 ),
2836 ]),
2837 is_retained_metrics_object: false,
2838 access: vec![PUBLIC_SELECT],
2839 ontology: Some(Ontology {
2840 entity_name: "frontier",
2841 description: "Current read/write frontiers for sources, sinks, tables, materialized views, indexes, and subscriptions",
2842 links: &const {
2843 [OntologyLink {
2844 name: "frontier_of",
2845 target: "object",
2846 properties: LinkProperties::fk_mapped(
2847 "object_id",
2848 "id",
2849 Cardinality::ManyToOne,
2850 mz_repr::SemanticType::GlobalId,
2851 "mz_internal.mz_object_global_ids",
2852 ),
2853 }]
2854 },
2855 column_semantic_types: &const {
2856 [
2857 ("object_id", SemanticType::GlobalId),
2858 ("read_frontier", SemanticType::MzTimestamp),
2859 ("write_frontier", SemanticType::MzTimestamp),
2860 ]
2861 },
2862 }),
2863});
2864
2865pub static MZ_GLOBAL_FRONTIERS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2867 name: "mz_global_frontiers",
2868 schema: MZ_INTERNAL_SCHEMA,
2869 oid: oid::VIEW_MZ_GLOBAL_FRONTIERS_OID,
2870 desc: RelationDesc::builder()
2871 .with_column("object_id", SqlScalarType::String.nullable(false))
2872 .with_column("time", SqlScalarType::MzTimestamp.nullable(false))
2873 .finish(),
2874 column_comments: BTreeMap::new(),
2875 sql: "
2876SELECT object_id, write_frontier AS time
2877FROM mz_internal.mz_frontiers
2878WHERE write_frontier IS NOT NULL",
2879 access: vec![PUBLIC_SELECT],
2880 ontology: None,
2881});
2882
2883pub static MZ_WALLCLOCK_LAG_HISTORY: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
2884 name: "mz_wallclock_lag_history",
2885 schema: MZ_INTERNAL_SCHEMA,
2886 oid: oid::SOURCE_MZ_WALLCLOCK_LAG_HISTORY_OID,
2887 desc: WALLCLOCK_LAG_HISTORY_DESC.clone(),
2888 data_source: IntrospectionType::WallclockLagHistory.into(),
2889 column_comments: BTreeMap::from_iter([
2890 (
2891 "object_id",
2892 "The ID of the table, source, materialized view, index, or sink. Corresponds to `mz_objects.id`.",
2893 ),
2894 (
2895 "replica_id",
2896 "The ID of a replica computing the object, or `NULL` for persistent objects. Corresponds to `mz_cluster_replicas.id`.",
2897 ),
2898 (
2899 "lag",
2900 "The amount of time the object's write frontier lags behind wallclock time.",
2901 ),
2902 (
2903 "occurred_at",
2904 "Wall-clock timestamp at which the event occurred.",
2905 ),
2906 ]),
2907 is_retained_metrics_object: false,
2908 access: vec![PUBLIC_SELECT],
2909 ontology: Some(Ontology {
2910 entity_name: "wallclock_lag_event",
2911 description: "Historical wallclock lag per object",
2912 links: &const {
2913 [
2914 OntologyLink {
2915 name: "measures_lag_of",
2916 target: "object",
2917 properties: LinkProperties::measures_mapped(
2918 "object_id",
2919 "id",
2920 "wallclock_lag",
2921 mz_repr::SemanticType::GlobalId,
2922 "mz_internal.mz_object_global_ids",
2923 ),
2924 },
2925 OntologyLink {
2926 name: "on_replica",
2927 target: "replica",
2928 properties: LinkProperties::fk_nullable(
2929 "replica_id",
2930 "id",
2931 Cardinality::ManyToOne,
2932 ),
2933 },
2934 ]
2935 },
2936 column_semantic_types: &const {
2937 [
2938 ("object_id", SemanticType::GlobalId),
2939 ("replica_id", SemanticType::ReplicaId),
2940 ("occurred_at", SemanticType::WallclockTimestamp),
2941 ]
2942 },
2943 }),
2944});
2945
2946pub static MZ_WALLCLOCK_GLOBAL_LAG_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2947 name: "mz_wallclock_global_lag_history",
2948 schema: MZ_INTERNAL_SCHEMA,
2949 oid: oid::VIEW_MZ_WALLCLOCK_GLOBAL_LAG_HISTORY_OID,
2950 desc: RelationDesc::builder()
2951 .with_column("object_id", SqlScalarType::String.nullable(false))
2952 .with_column("lag", SqlScalarType::Interval.nullable(true))
2953 .with_column(
2954 "occurred_at",
2955 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2956 )
2957 .with_key(vec![0, 2])
2958 .finish(),
2959 column_comments: BTreeMap::from_iter([
2960 (
2961 "object_id",
2962 "The ID of the table, source, materialized view, index, or sink. Corresponds to `mz_objects.id`.",
2963 ),
2964 (
2965 "lag",
2966 "The minimum wallclock lag observed for the object during the minute.",
2967 ),
2968 (
2969 "occurred_at",
2970 "The minute-aligned timestamp of the observation.",
2971 ),
2972 ]),
2973 sql: "
2974WITH times_binned AS (
2975 SELECT
2976 object_id,
2977 lag,
2978 date_trunc('minute', occurred_at) AS occurred_at
2979 FROM mz_internal.mz_wallclock_lag_history
2980)
2981SELECT
2982 object_id,
2983 min(lag) AS lag,
2984 occurred_at
2985FROM times_binned
2986GROUP BY object_id, occurred_at
2987OPTIONS (AGGREGATE INPUT GROUP SIZE = 1)",
2988 access: vec![PUBLIC_SELECT],
2989 ontology: Some(Ontology {
2990 entity_name: "wallclock_global_lag_event",
2991 description: "Historical global wallclock lag",
2992 links: &const {
2993 [OntologyLink {
2994 name: "lag_of",
2995 target: "object_global_id",
2996 properties: LinkProperties::fk("object_id", "global_id", Cardinality::ManyToOne),
2997 }]
2998 },
2999 column_semantic_types: &const {
3000 [
3001 ("object_id", SemanticType::GlobalId),
3002 ("occurred_at", SemanticType::WallclockTimestamp),
3003 ]
3004 },
3005 }),
3006});
3007
3008pub static MZ_WALLCLOCK_GLOBAL_LAG_RECENT_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| {
3009 BuiltinView {
3010 name: "mz_wallclock_global_lag_recent_history",
3011 schema: MZ_INTERNAL_SCHEMA,
3012 oid: oid::VIEW_MZ_WALLCLOCK_GLOBAL_LAG_RECENT_HISTORY_OID,
3013 desc: RelationDesc::builder()
3014 .with_column("object_id", SqlScalarType::String.nullable(false))
3015 .with_column("lag", SqlScalarType::Interval.nullable(true))
3016 .with_column(
3017 "occurred_at",
3018 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3019 )
3020 .with_key(vec![0, 2])
3021 .finish(),
3022 column_comments: BTreeMap::from_iter([
3023 (
3024 "object_id",
3025 "The ID of the table, source, materialized view, index, or sink. Corresponds to `mz_objects.id`.",
3026 ),
3027 (
3028 "lag",
3029 "The minimum wallclock lag observed for the object during the minute.",
3030 ),
3031 (
3032 "occurred_at",
3033 "The minute-aligned timestamp of the observation.",
3034 ),
3035 ]),
3036 sql: "
3037SELECT object_id, lag, occurred_at
3038FROM mz_internal.mz_wallclock_global_lag_history
3039WHERE occurred_at + '1 day' > mz_now()",
3040 access: vec![PUBLIC_SELECT],
3041 ontology: None,
3042 }
3043});
3044
3045pub static MZ_WALLCLOCK_GLOBAL_LAG: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3046 name: "mz_wallclock_global_lag",
3047 schema: MZ_INTERNAL_SCHEMA,
3048 oid: oid::VIEW_MZ_WALLCLOCK_GLOBAL_LAG_OID,
3049 desc: RelationDesc::builder()
3050 .with_column("object_id", SqlScalarType::String.nullable(false))
3051 .with_column("lag", SqlScalarType::Interval.nullable(true))
3052 .with_key(vec![0])
3053 .finish(),
3054 column_comments: BTreeMap::from_iter([
3055 (
3056 "object_id",
3057 "The ID of the table, source, materialized view, index, or sink. Corresponds to `mz_objects.id`.",
3058 ),
3059 (
3060 "lag",
3061 "The amount of time the object's write frontier lags behind wallclock time.",
3062 ),
3063 ]),
3064 sql: "
3065SELECT DISTINCT ON (object_id) object_id, lag
3066FROM mz_internal.mz_wallclock_global_lag_recent_history
3067WHERE occurred_at + '5 minutes' > mz_now()
3068ORDER BY object_id, occurred_at DESC",
3069 access: vec![PUBLIC_SELECT],
3070 ontology: Some(Ontology {
3071 entity_name: "wallclock_global_lag",
3072 description: "Current wallclock lag aggregated across replicas",
3073 links: &const {
3074 [OntologyLink {
3075 name: "measures_global_lag_of",
3076 target: "object",
3077 properties: LinkProperties::measures_mapped(
3078 "object_id",
3079 "id",
3080 "wallclock_lag_global",
3081 mz_repr::SemanticType::GlobalId,
3082 "mz_internal.mz_object_global_ids",
3083 ),
3084 }]
3085 },
3086 column_semantic_types: &[("object_id", SemanticType::GlobalId)],
3087 }),
3088});
3089
3090pub static MZ_WALLCLOCK_GLOBAL_LAG_HISTOGRAM_RAW: LazyLock<BuiltinSource> =
3091 LazyLock::new(|| BuiltinSource {
3092 name: "mz_wallclock_global_lag_histogram_raw",
3093 schema: MZ_INTERNAL_SCHEMA,
3094 oid: oid::SOURCE_MZ_WALLCLOCK_GLOBAL_LAG_HISTOGRAM_RAW_OID,
3095 desc: WALLCLOCK_GLOBAL_LAG_HISTOGRAM_RAW_DESC.clone(),
3096 column_comments: BTreeMap::new(),
3097 data_source: IntrospectionType::WallclockLagHistogram.into(),
3098 is_retained_metrics_object: false,
3099 access: vec![PUBLIC_SELECT],
3100 ontology: None,
3101 });
3102
3103pub static MZ_WALLCLOCK_GLOBAL_LAG_HISTOGRAM: LazyLock<BuiltinView> =
3104 LazyLock::new(|| BuiltinView {
3105 name: "mz_wallclock_global_lag_histogram",
3106 schema: MZ_INTERNAL_SCHEMA,
3107 oid: oid::VIEW_MZ_WALLCLOCK_GLOBAL_LAG_HISTOGRAM_OID,
3108 desc: RelationDesc::builder()
3109 .with_column(
3110 "period_start",
3111 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3112 )
3113 .with_column(
3114 "period_end",
3115 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3116 )
3117 .with_column("object_id", SqlScalarType::String.nullable(false))
3118 .with_column("lag_seconds", SqlScalarType::UInt64.nullable(true))
3119 .with_column("labels", SqlScalarType::Jsonb.nullable(false))
3120 .with_column("count", SqlScalarType::Int64.nullable(false))
3121 .with_key(vec![0, 1, 2, 3, 4])
3122 .finish(),
3123 column_comments: BTreeMap::new(),
3124 sql: "
3125SELECT *, count(*) AS count
3126FROM mz_internal.mz_wallclock_global_lag_histogram_raw
3127GROUP BY period_start, period_end, object_id, lag_seconds, labels",
3128 access: vec![PUBLIC_SELECT],
3129 ontology: None,
3130 });
3131
3132pub static MZ_MATERIALIZED_VIEW_REFRESHES: LazyLock<BuiltinSource> = LazyLock::new(|| {
3133 BuiltinSource {
3134 name: "mz_materialized_view_refreshes",
3135 schema: MZ_INTERNAL_SCHEMA,
3136 oid: oid::SOURCE_MZ_MATERIALIZED_VIEW_REFRESHES_OID,
3137 data_source: DataSourceDesc::Introspection(
3138 IntrospectionType::ComputeMaterializedViewRefreshes,
3139 ),
3140 desc: RelationDesc::builder()
3141 .with_column(
3142 "materialized_view_id",
3143 SqlScalarType::String.nullable(false),
3144 )
3145 .with_column(
3146 "last_completed_refresh",
3147 SqlScalarType::MzTimestamp.nullable(true),
3148 )
3149 .with_column("next_refresh", SqlScalarType::MzTimestamp.nullable(true))
3150 .finish(),
3151 column_comments: BTreeMap::from_iter([
3152 (
3153 "materialized_view_id",
3154 "The ID of the materialized view. Corresponds to `mz_catalog.mz_materialized_views.id`",
3155 ),
3156 (
3157 "last_completed_refresh",
3158 "The time of the last successfully completed refresh. `NULL` if the materialized view hasn't completed any refreshes yet.",
3159 ),
3160 (
3161 "next_refresh",
3162 "The time of the next scheduled refresh. `NULL` if the materialized view has no future scheduled refreshes.",
3163 ),
3164 ]),
3165 is_retained_metrics_object: false,
3166 access: vec![PUBLIC_SELECT],
3167 ontology: None,
3168 }
3169});
3170
3171pub static MZ_SUBSCRIPTIONS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3172 name: "mz_subscriptions",
3173 schema: MZ_INTERNAL_SCHEMA,
3174 oid: oid::TABLE_MZ_SUBSCRIPTIONS_OID,
3175 desc: RelationDesc::builder()
3176 .with_column("id", SqlScalarType::String.nullable(false))
3177 .with_column("session_id", SqlScalarType::Uuid.nullable(false))
3178 .with_column("cluster_id", SqlScalarType::String.nullable(false))
3179 .with_column(
3180 "created_at",
3181 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3182 )
3183 .with_column(
3184 "referenced_object_ids",
3185 SqlScalarType::List {
3186 element_type: Box::new(SqlScalarType::String),
3187 custom_id: None,
3188 }
3189 .nullable(false),
3190 )
3191 .finish(),
3192 column_comments: BTreeMap::from_iter([
3193 ("id", "The ID of the subscription."),
3194 (
3195 "session_id",
3196 "The ID of the session that runs the subscription. Corresponds to `mz_sessions.id`.",
3197 ),
3198 (
3199 "cluster_id",
3200 "The ID of the cluster on which the subscription is running. Corresponds to `mz_clusters.id`.",
3201 ),
3202 (
3203 "created_at",
3204 "The time at which the subscription was created.",
3205 ),
3206 (
3207 "referenced_object_ids",
3208 "The IDs of objects referenced by the subscription. Corresponds to `mz_objects.id`",
3209 ),
3210 ]),
3211 is_retained_metrics_object: false,
3212 access: vec![PUBLIC_SELECT],
3213 ontology: Some(Ontology {
3214 entity_name: "subscription",
3215 description: "Active SUBSCRIBE operations",
3216 links: &const {
3217 [
3218 OntologyLink {
3219 name: "uses_session",
3220 target: "session",
3221 properties: LinkProperties::fk("session_id", "id", Cardinality::ManyToOne),
3222 },
3223 OntologyLink {
3224 name: "in_active_session",
3225 target: "active_session",
3226 properties: LinkProperties::fk_nullable(
3227 "session_id",
3228 "id",
3229 Cardinality::ManyToOne,
3230 ),
3231 },
3232 OntologyLink {
3233 name: "belongs_to_cluster",
3234 target: "cluster",
3235 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
3236 },
3237 ]
3238 },
3239 column_semantic_types: &const {
3240 [
3241 ("id", SemanticType::CatalogItemId),
3242 ("cluster_id", SemanticType::ClusterId),
3243 ]
3244 },
3245 }),
3246});
3247
3248pub static MZ_SESSIONS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3249 name: "mz_sessions",
3250 schema: MZ_INTERNAL_SCHEMA,
3251 oid: oid::TABLE_MZ_SESSIONS_OID,
3252 desc: RelationDesc::builder()
3253 .with_column("id", SqlScalarType::Uuid.nullable(false))
3254 .with_column("connection_id", SqlScalarType::UInt32.nullable(false))
3255 .with_column("role_id", SqlScalarType::String.nullable(false))
3256 .with_column("client_ip", SqlScalarType::String.nullable(true))
3257 .with_column(
3258 "connected_at",
3259 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3260 )
3261 .finish(),
3262 column_comments: BTreeMap::from_iter([
3263 ("id", "The globally unique ID of the session."),
3264 (
3265 "connection_id",
3266 "The connection ID of the session. Unique only for active sessions and can be recycled. Corresponds to `pg_backend_pid()`.",
3267 ),
3268 (
3269 "role_id",
3270 "The role ID of the role that the session is logged in as. Corresponds to `mz_catalog.mz_roles`.",
3271 ),
3272 (
3273 "client_ip",
3274 "The IP address of the client that initiated the session.",
3275 ),
3276 (
3277 "connected_at",
3278 "The time at which the session connected to the system.",
3279 ),
3280 ]),
3281 is_retained_metrics_object: false,
3282 access: vec![PUBLIC_SELECT],
3283 ontology: Some(Ontology {
3284 entity_name: "active_session",
3285 description: "Currently active sessions",
3286 links: &const {
3287 [OntologyLink {
3288 name: "logged_in_as",
3289 target: "role",
3290 properties: LinkProperties::fk("role_id", "id", Cardinality::ManyToOne),
3291 }]
3292 },
3293 column_semantic_types: &[("role_id", SemanticType::RoleId)],
3294 }),
3295});
3296
3297pub static MZ_OVERRIDDEN_SYSTEM_PARAMETERS: LazyLock<BuiltinMaterializedView> =
3298 LazyLock::new(|| BuiltinMaterializedView {
3299 name: "mz_overridden_system_parameters",
3300 schema: MZ_INTERNAL_SCHEMA,
3301 oid: oid::MV_MZ_OVERRIDDEN_SYSTEM_PARAMETERS_OID,
3302 desc: RelationDesc::builder()
3303 .with_column("name", SqlScalarType::String.nullable(false))
3304 .with_column("value", SqlScalarType::String.nullable(false))
3305 .finish(),
3306 column_comments: BTreeMap::from_iter([
3307 ("name", "The name of the system parameter."),
3308 (
3309 "value",
3310 "The environment-wide value of the system parameter.",
3311 ),
3312 ]),
3313 sql: "
3320IN CLUSTER mz_catalog_server
3321WITH (
3322 ASSERT NOT NULL name,
3323 ASSERT NOT NULL value
3324) AS
3325SELECT
3326 data->'key'->>'name' AS name,
3327 data->'value'->>'value' AS value
3328FROM mz_internal.mz_catalog_raw
3329WHERE data->>'kind' = 'ServerConfiguration'",
3330 is_retained_metrics_object: false,
3331 access: vec![PUBLIC_SELECT],
3332 ontology: Some(Ontology {
3333 entity_name: "system_parameter",
3334 description: "Environment-wide system parameter overrides",
3335 links: &const { [] },
3336 column_semantic_types: &[],
3337 }),
3338 });
3339
3340pub static MZ_CLUSTER_SYSTEM_PARAMETERS: LazyLock<BuiltinMaterializedView> =
3341 LazyLock::new(|| BuiltinMaterializedView {
3342 name: "mz_cluster_system_parameters",
3343 schema: MZ_INTERNAL_SCHEMA,
3344 oid: oid::MV_MZ_CLUSTER_SYSTEM_PARAMETERS_OID,
3345 desc: RelationDesc::builder()
3346 .with_column("cluster_id", SqlScalarType::String.nullable(false))
3347 .with_column("name", SqlScalarType::String.nullable(false))
3348 .with_column("value", SqlScalarType::String.nullable(false))
3349 .finish(),
3350 column_comments: BTreeMap::from_iter([
3351 (
3352 "cluster_id",
3353 "The ID of the cluster. Corresponds to `mz_clusters.id`.",
3354 ),
3355 ("name", "The name of the cluster-coherent system parameter."),
3356 ("value", "The cluster-scoped value of the system parameter."),
3357 ]),
3358 sql: "
3362IN CLUSTER mz_catalog_server
3363WITH (
3364 ASSERT NOT NULL cluster_id,
3365 ASSERT NOT NULL name,
3366 ASSERT NOT NULL value
3367) AS
3368SELECT
3369 mz_internal.parse_catalog_id(data->'key'->'cluster_id') AS cluster_id,
3370 data->'key'->>'name' AS name,
3371 data->'value'->>'value' AS value
3372FROM mz_internal.mz_catalog_raw
3373WHERE data->>'kind' = 'ClusterSystemConfiguration'",
3374 is_retained_metrics_object: false,
3375 access: vec![PUBLIC_SELECT],
3376 ontology: Some(Ontology {
3377 entity_name: "cluster_system_parameter",
3378 description: "Cluster-coherent system parameter overrides",
3379 links: &const {
3380 [OntologyLink {
3381 name: "scoped_to_cluster",
3382 target: "cluster",
3383 properties: LinkProperties::fk_typed(
3384 "cluster_id",
3385 "id",
3386 Cardinality::ManyToOne,
3387 mz_repr::SemanticType::ClusterId,
3388 ),
3389 }]
3390 },
3391 column_semantic_types: &[("cluster_id", SemanticType::ClusterId)],
3392 }),
3393 });
3394
3395pub static MZ_REPLICA_SYSTEM_PARAMETERS: LazyLock<BuiltinMaterializedView> =
3396 LazyLock::new(|| BuiltinMaterializedView {
3397 name: "mz_replica_system_parameters",
3398 schema: MZ_INTERNAL_SCHEMA,
3399 oid: oid::MV_MZ_REPLICA_SYSTEM_PARAMETERS_OID,
3400 desc: RelationDesc::builder()
3401 .with_column("replica_id", SqlScalarType::String.nullable(false))
3402 .with_column("name", SqlScalarType::String.nullable(false))
3403 .with_column("value", SqlScalarType::String.nullable(false))
3404 .finish(),
3405 column_comments: BTreeMap::from_iter([
3406 (
3407 "replica_id",
3408 "The ID of the cluster replica. Corresponds to `mz_cluster_replicas.id`.",
3409 ),
3410 ("name", "The name of the replica-local system parameter."),
3411 ("value", "The replica-scoped value of the system parameter."),
3412 ]),
3413 sql: "
3417IN CLUSTER mz_catalog_server
3418WITH (
3419 ASSERT NOT NULL replica_id,
3420 ASSERT NOT NULL name,
3421 ASSERT NOT NULL value
3422) AS
3423SELECT
3424 mz_internal.parse_catalog_id(data->'key'->'replica_id') AS replica_id,
3425 data->'key'->>'name' AS name,
3426 data->'value'->>'value' AS value
3427FROM mz_internal.mz_catalog_raw
3428WHERE data->>'kind' = 'ReplicaSystemConfiguration'",
3429 is_retained_metrics_object: false,
3430 access: vec![PUBLIC_SELECT],
3431 ontology: Some(Ontology {
3432 entity_name: "replica_system_parameter",
3433 description: "Replica-local system parameter overrides",
3434 links: &const {
3435 [OntologyLink {
3436 name: "scoped_to_replica",
3437 target: "replica",
3438 properties: LinkProperties::fk_typed(
3439 "replica_id",
3440 "id",
3441 Cardinality::ManyToOne,
3442 mz_repr::SemanticType::ReplicaId,
3443 ),
3444 }]
3445 },
3446 column_semantic_types: &[("replica_id", SemanticType::ReplicaId)],
3447 }),
3448 });
3449
3450pub static MZ_COMMENTS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
3451 BuiltinMaterializedView {
3452 name: "mz_comments",
3453 schema: MZ_INTERNAL_SCHEMA,
3454 oid: oid::MV_MZ_COMMENTS_OID,
3455 desc: RelationDesc::builder()
3456 .with_column("id", SqlScalarType::String.nullable(false))
3457 .with_column("object_type", SqlScalarType::String.nullable(false))
3458 .with_column("object_sub_id", SqlScalarType::Int32.nullable(true))
3459 .with_column("comment", SqlScalarType::String.nullable(false))
3460 .finish(),
3461 column_comments: BTreeMap::from_iter([
3462 (
3463 "id",
3464 "The ID of the object. Corresponds to `mz_objects.id`.",
3465 ),
3466 (
3467 "object_type",
3468 "The type of object the comment is associated with.",
3469 ),
3470 (
3471 "object_sub_id",
3472 "For a comment on a column of a relation, the column number. `NULL` for other object types.",
3473 ),
3474 ("comment", "The comment itself."),
3475 ]),
3476 sql: "
3489IN CLUSTER mz_catalog_server
3490WITH (
3491 ASSERT NOT NULL id,
3492 ASSERT NOT NULL object_type,
3493 ASSERT NOT NULL comment
3494) AS
3495WITH commented AS (
3496 SELECT data->'key'->'object' AS obj,
3497 data->'key'->'sub_component' AS sub,
3498 data->'value'->>'comment' AS comment
3499 FROM mz_internal.mz_catalog_raw
3500 WHERE data->>'kind' = 'Comment'
3501)
3502SELECT
3503 CASE
3504 WHEN obj ? 'Table' THEN mz_internal.parse_catalog_id(obj->'Table')
3505 WHEN obj ? 'View' THEN mz_internal.parse_catalog_id(obj->'View')
3506 WHEN obj ? 'MaterializedView' THEN mz_internal.parse_catalog_id(obj->'MaterializedView')
3507 WHEN obj ? 'Source' THEN mz_internal.parse_catalog_id(obj->'Source')
3508 WHEN obj ? 'Sink' THEN mz_internal.parse_catalog_id(obj->'Sink')
3509 WHEN obj ? 'Index' THEN mz_internal.parse_catalog_id(obj->'Index')
3510 WHEN obj ? 'Func' THEN mz_internal.parse_catalog_id(obj->'Func')
3511 WHEN obj ? 'Connection' THEN mz_internal.parse_catalog_id(obj->'Connection')
3512 WHEN obj ? 'Type' THEN mz_internal.parse_catalog_id(obj->'Type')
3513 WHEN obj ? 'Secret' THEN mz_internal.parse_catalog_id(obj->'Secret')
3514 WHEN obj ? 'Role' THEN mz_internal.parse_catalog_id(obj->'Role')
3515 WHEN obj ? 'Database' THEN mz_internal.parse_catalog_id(obj->'Database')
3516 WHEN obj ? 'Schema' THEN mz_internal.parse_catalog_id(obj->'Schema'->'schema'->'Id')
3517 WHEN obj ? 'Cluster' THEN mz_internal.parse_catalog_id(obj->'Cluster')
3518 WHEN obj ? 'ClusterReplica' THEN mz_internal.parse_catalog_id(obj->'ClusterReplica'->'replica_id')
3519 WHEN obj ? 'NetworkPolicy' THEN mz_internal.parse_catalog_id(obj->'NetworkPolicy')
3520 END AS id,
3521 CASE
3522 WHEN obj ? 'Table' THEN 'table'
3523 WHEN obj ? 'View' THEN 'view'
3524 WHEN obj ? 'MaterializedView' THEN 'materialized-view'
3525 WHEN obj ? 'Source' THEN 'source'
3526 WHEN obj ? 'Sink' THEN 'sink'
3527 WHEN obj ? 'Index' THEN 'index'
3528 WHEN obj ? 'Func' THEN 'func'
3529 WHEN obj ? 'Connection' THEN 'connection'
3530 WHEN obj ? 'Type' THEN 'type'
3531 WHEN obj ? 'Secret' THEN 'secret'
3532 WHEN obj ? 'Role' THEN 'role'
3533 WHEN obj ? 'Database' THEN 'database'
3534 WHEN obj ? 'Schema' THEN 'schema'
3535 WHEN obj ? 'Cluster' THEN 'cluster'
3536 WHEN obj ? 'ClusterReplica' THEN 'cluster-replica'
3537 WHEN obj ? 'NetworkPolicy' THEN 'network-policy'
3538 END AS object_type,
3539 (sub->'ColumnPos')::int4 AS object_sub_id,
3540 comment
3541FROM commented",
3542 is_retained_metrics_object: false,
3543 access: vec![PUBLIC_SELECT],
3544 ontology: Some(Ontology {
3545 entity_name: "comment",
3546 description: "A COMMENT ON annotation for a catalog object or column",
3547 links: &const {
3548 [OntologyLink {
3549 name: "comment_on",
3550 target: "object",
3551 properties: LinkProperties::fk_typed(
3552 "id",
3553 "id",
3554 Cardinality::ManyToOne,
3555 mz_repr::SemanticType::CatalogItemId,
3556 ),
3557 }]
3558 },
3559 column_semantic_types: &const {
3560 [
3561 ("id", SemanticType::CatalogItemId),
3562 ("object_type", SemanticType::ObjectType),
3563 ]
3564 },
3565 }),
3566 }
3567});
3568
3569pub static MZ_SOURCE_REFERENCES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3570 name: "mz_source_references",
3571 schema: MZ_INTERNAL_SCHEMA,
3572 oid: oid::TABLE_MZ_SOURCE_REFERENCES_OID,
3573 desc: RelationDesc::builder()
3574 .with_column("source_id", SqlScalarType::String.nullable(false))
3575 .with_column("namespace", SqlScalarType::String.nullable(true))
3576 .with_column("name", SqlScalarType::String.nullable(false))
3577 .with_column(
3578 "updated_at",
3579 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3580 )
3581 .with_column(
3582 "columns",
3583 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(true),
3584 )
3585 .finish(),
3586 column_comments: BTreeMap::new(),
3587 is_retained_metrics_object: false,
3588 access: vec![PUBLIC_SELECT],
3589 ontology: Some(Ontology {
3590 entity_name: "source_reference",
3591 description: "External references tracked by sources",
3592 links: &const {
3593 [OntologyLink {
3594 name: "references_source",
3595 target: "source",
3596 properties: LinkProperties::fk("source_id", "id", Cardinality::ManyToOne),
3597 }]
3598 },
3599 column_semantic_types: &[("source_id", SemanticType::CatalogItemId)],
3600 }),
3601});
3602
3603pub static MZ_WEBHOOKS_SOURCES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3604 name: "mz_webhook_sources",
3605 schema: MZ_INTERNAL_SCHEMA,
3606 oid: oid::TABLE_MZ_WEBHOOK_SOURCES_OID,
3607 desc: RelationDesc::builder()
3608 .with_column("id", SqlScalarType::String.nullable(false))
3609 .with_column("name", SqlScalarType::String.nullable(false))
3610 .with_column("url", SqlScalarType::String.nullable(false))
3611 .finish(),
3612 column_comments: BTreeMap::from_iter([
3613 (
3614 "id",
3615 "The ID of the webhook source. Corresponds to `mz_sources.id`.",
3616 ),
3617 ("name", "The name of the webhook source."),
3618 (
3619 "url",
3620 "The URL which can be used to send events to the source.",
3621 ),
3622 ]),
3623 is_retained_metrics_object: false,
3624 access: vec![PUBLIC_SELECT],
3625 ontology: Some(Ontology {
3626 entity_name: "webhook_source",
3627 description: "Webhook source configuration",
3628 links: &const {
3629 [OntologyLink {
3630 name: "details_of",
3631 target: "source",
3632 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
3633 }]
3634 },
3635 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3636 }),
3637});
3638
3639pub static MZ_METRIC_SINKS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
3640 BuiltinMaterializedView {
3641 name: "mz_metric_sinks",
3642 schema: MZ_INTERNAL_SCHEMA,
3643 oid: oid::MV_MZ_METRIC_SINKS_OID,
3644 desc: RelationDesc::builder()
3645 .with_column("id", SqlScalarType::String.nullable(false))
3646 .with_column("oid", SqlScalarType::Oid.nullable(false))
3647 .with_column("schema_id", SqlScalarType::String.nullable(false))
3648 .with_column("name", SqlScalarType::String.nullable(false))
3649 .with_column("from_id", SqlScalarType::String.nullable(false))
3650 .with_column("cluster_id", SqlScalarType::String.nullable(false))
3651 .with_column("owner_id", SqlScalarType::String.nullable(false))
3652 .with_key(vec![0])
3653 .with_key(vec![1])
3654 .finish(),
3655 column_comments: BTreeMap::from_iter([
3656 ("id", "Materialize's unique ID for the metric sink."),
3657 ("oid", "A PostgreSQL-compatible OID for the metric sink."),
3658 (
3659 "schema_id",
3660 "The ID of the schema to which the metric sink belongs. Corresponds to `mz_schemas.id`.",
3661 ),
3662 ("name", "The name of the metric sink."),
3663 (
3664 "from_id",
3665 "The ID of the relation the metric sink reads. Corresponds to `mz_objects.id`.",
3666 ),
3667 (
3668 "cluster_id",
3669 "The ID of the cluster maintaining the metric sink. Corresponds to `mz_clusters.id`.",
3670 ),
3671 (
3672 "owner_id",
3673 "The role ID of the owner of the metric sink. Corresponds to `mz_roles.id`.",
3674 ),
3675 ]),
3676 sql: "
3677IN CLUSTER mz_catalog_server
3678WITH (
3679 ASSERT NOT NULL id,
3680 ASSERT NOT NULL oid,
3681 ASSERT NOT NULL schema_id,
3682 ASSERT NOT NULL name,
3683 ASSERT NOT NULL from_id,
3684 ASSERT NOT NULL cluster_id,
3685 ASSERT NOT NULL owner_id
3686) AS
3687SELECT
3688 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
3689 (data->'value'->>'oid')::oid AS oid,
3690 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
3691 data->'value'->>'name' AS name,
3692 parsed->>'from_id' AS from_id,
3693 parsed->>'cluster_id' AS cluster_id,
3694 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id
3695FROM
3696 mz_internal.mz_catalog_raw
3697 CROSS JOIN LATERAL (
3698 SELECT mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')
3699 ) AS l(parsed)
3700WHERE
3701 data->>'kind' = 'Item' AND
3702 parsed->>'type' = 'metric-sink'",
3703 is_retained_metrics_object: false,
3704 access: vec![PUBLIC_SELECT],
3705 ontology: Some(Ontology {
3706 entity_name: "metric-sink",
3707 description: "A sink that exports metrics about a relation",
3708 links: &const {
3709 [
3710 OntologyLink {
3711 name: "in_schema",
3712 target: "schema",
3713 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
3714 },
3715 OntologyLink {
3716 name: "reads_relation",
3717 target: "relation",
3718 properties: LinkProperties::fk("from_id", "id", Cardinality::ManyToOne),
3719 },
3720 OntologyLink {
3721 name: "runs_on_cluster",
3722 target: "cluster",
3723 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
3724 },
3725 OntologyLink {
3726 name: "owned_by",
3727 target: "role",
3728 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
3729 },
3730 ]
3731 },
3732 column_semantic_types: &const {
3733 [
3734 ("id", SemanticType::CatalogItemId),
3735 ("oid", SemanticType::OID),
3736 ("schema_id", SemanticType::SchemaId),
3737 ("from_id", SemanticType::CatalogItemId),
3738 ("cluster_id", SemanticType::ClusterId),
3739 ("owner_id", SemanticType::RoleId),
3740 ]
3741 },
3742 }),
3743 }
3744});
3745
3746pub const MZ_METRIC_SINKS_IND: BuiltinIndex = BuiltinIndex {
3747 name: "mz_metric_sinks_ind",
3748 schema: MZ_INTERNAL_SCHEMA,
3749 oid: oid::INDEX_MZ_METRIC_SINKS_IND_OID,
3750 sql: "IN CLUSTER mz_catalog_server
3751ON mz_internal.mz_metric_sinks (id)",
3752 is_retained_metrics_object: false,
3753};
3754
3755pub static MZ_HISTORY_RETENTION_STRATEGIES: LazyLock<BuiltinTable> = LazyLock::new(|| {
3756 BuiltinTable {
3757 name: "mz_history_retention_strategies",
3758 schema: MZ_INTERNAL_SCHEMA,
3759 oid: oid::TABLE_MZ_HISTORY_RETENTION_STRATEGIES_OID,
3760 desc: RelationDesc::builder()
3761 .with_column("id", SqlScalarType::String.nullable(false))
3762 .with_column("strategy", SqlScalarType::String.nullable(false))
3763 .with_column("value", SqlScalarType::Jsonb.nullable(false))
3764 .finish(),
3765 column_comments: BTreeMap::from_iter([
3766 ("id", "The ID of the object."),
3767 (
3768 "strategy",
3769 "The strategy. `FOR` is the only strategy, and means the object's compaction window is the duration of the `value` field.",
3770 ),
3771 (
3772 "value",
3773 "The value of the strategy. For `FOR`, is a number of milliseconds.",
3774 ),
3775 ]),
3776 is_retained_metrics_object: false,
3777 access: vec![PUBLIC_SELECT],
3778 ontology: Some(Ontology {
3779 entity_name: "history_retention",
3780 description: "History retention strategy for an object",
3781 links: &const { [] },
3782 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3783 }),
3784 }
3785});
3786
3787pub static MZ_LICENSE_KEYS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3788 name: "mz_license_keys",
3789 schema: MZ_INTERNAL_SCHEMA,
3790 oid: oid::TABLE_MZ_LICENSE_KEYS_OID,
3791 desc: RelationDesc::builder()
3792 .with_column("id", SqlScalarType::String.nullable(false))
3793 .with_column("organization", SqlScalarType::String.nullable(false))
3794 .with_column("environment_id", SqlScalarType::String.nullable(false))
3795 .with_column(
3796 "expiration",
3797 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3798 )
3799 .with_column(
3800 "not_before",
3801 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3802 )
3803 .finish(),
3804 column_comments: BTreeMap::from_iter([
3805 ("id", "The identifier of the license key."),
3806 (
3807 "organization",
3808 "The name of the organization that this license key was issued to.",
3809 ),
3810 (
3811 "environment_id",
3812 "The environment ID that this license key was issued for.",
3813 ),
3814 (
3815 "expiration",
3816 "The date and time when this license key expires.",
3817 ),
3818 (
3819 "not_before",
3820 "The start of the validity period for this license key.",
3821 ),
3822 ]),
3823 is_retained_metrics_object: false,
3824 access: vec![PUBLIC_SELECT],
3825 ontology: Some(Ontology {
3826 entity_name: "license_key",
3827 description: "License key metadata",
3828 links: &const { [] },
3829 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3830 }),
3831});
3832
3833pub static MZ_REPLACEMENTS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3834 name: "mz_replacements",
3835 schema: MZ_INTERNAL_SCHEMA,
3836 oid: oid::TABLE_MZ_REPLACEMENTS_OID,
3837 desc: RelationDesc::builder()
3838 .with_column("id", SqlScalarType::String.nullable(false))
3839 .with_column("target_id", SqlScalarType::String.nullable(false))
3840 .finish(),
3841 column_comments: BTreeMap::from_iter([
3842 (
3843 "id",
3844 "The ID of the replacement object. Corresponds to `mz_objects.id`.",
3845 ),
3846 (
3847 "target_id",
3848 "The ID of the replacement target. Corresponds to `mz_objects.id`.",
3849 ),
3850 ]),
3851 is_retained_metrics_object: false,
3852 access: vec![PUBLIC_SELECT],
3853 ontology: Some(Ontology {
3854 entity_name: "replacement",
3855 description: "A record of an object replacement (ALTER ... SWAP)",
3856 links: &const {
3857 [
3858 OntologyLink {
3859 name: "replacement_object",
3860 target: "object",
3861 properties: LinkProperties::fk("id", "id", Cardinality::ManyToOne),
3862 },
3863 OntologyLink {
3864 name: "replacement_target",
3865 target: "object",
3866 properties: LinkProperties::fk("target_id", "id", Cardinality::ManyToOne),
3867 },
3868 ]
3869 },
3870 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3871 }),
3872});
3873
3874pub static MZ_SOURCE_STATISTICS_RAW: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
3877 name: "mz_source_statistics_raw",
3878 schema: MZ_INTERNAL_SCHEMA,
3879 oid: oid::SOURCE_MZ_SOURCE_STATISTICS_RAW_OID,
3880 data_source: IntrospectionType::StorageSourceStatistics.into(),
3881 desc: MZ_SOURCE_STATISTICS_RAW_DESC.clone(),
3882 column_comments: BTreeMap::new(),
3883 is_retained_metrics_object: true,
3884 access: vec![PUBLIC_SELECT],
3885 ontology: None,
3886});
3887pub static MZ_SINK_STATISTICS_RAW: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
3888 name: "mz_sink_statistics_raw",
3889 schema: MZ_INTERNAL_SCHEMA,
3890 oid: oid::SOURCE_MZ_SINK_STATISTICS_RAW_OID,
3891 data_source: IntrospectionType::StorageSinkStatistics.into(),
3892 desc: MZ_SINK_STATISTICS_RAW_DESC.clone(),
3893 column_comments: BTreeMap::new(),
3894 is_retained_metrics_object: true,
3895 access: vec![PUBLIC_SELECT],
3896 ontology: None,
3897});
3898
3899pub static MZ_STORAGE_SHARDS: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
3900 name: "mz_storage_shards",
3901 schema: MZ_INTERNAL_SCHEMA,
3902 oid: oid::SOURCE_MZ_STORAGE_SHARDS_OID,
3903 data_source: IntrospectionType::ShardMapping.into(),
3904 desc: RelationDesc::builder()
3905 .with_column("object_id", SqlScalarType::String.nullable(false))
3906 .with_column("shard_id", SqlScalarType::String.nullable(false))
3907 .finish(),
3908 column_comments: BTreeMap::new(),
3909 is_retained_metrics_object: false,
3910 access: vec![PUBLIC_SELECT],
3911 ontology: Some(Ontology {
3912 entity_name: "storage_shard",
3913 description: "Persist shards used by storage objects",
3914 links: &const {
3915 [OntologyLink {
3916 name: "shard_of",
3917 target: "object",
3918 properties: LinkProperties::fk_mapped(
3919 "object_id",
3920 "id",
3921 Cardinality::ManyToOne,
3922 mz_repr::SemanticType::GlobalId,
3923 "mz_internal.mz_object_global_ids",
3924 ),
3925 }]
3926 },
3927 column_semantic_types: &const {
3928 [
3929 ("object_id", SemanticType::GlobalId),
3930 ("shard_id", SemanticType::ShardId),
3931 ]
3932 },
3933 }),
3934});
3935
3936pub static MZ_OBJECTS_ID_NAMESPACE_TYPES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3937 name: "mz_objects_id_namespace_types",
3938 schema: MZ_INTERNAL_SCHEMA,
3939 oid: oid::VIEW_MZ_OBJECTS_ID_NAMESPACE_TYPES_OID,
3940 desc: RelationDesc::builder()
3941 .with_column("object_type", SqlScalarType::String.nullable(false))
3942 .with_key(vec![0])
3943 .finish(),
3944 column_comments: BTreeMap::new(),
3945 sql: r#"SELECT *
3946 FROM (
3947 VALUES
3948 ('table'),
3949 ('view'),
3950 ('materialized-view'),
3951 ('source'),
3952 ('sink'),
3953 ('metric-sink'),
3954 ('index'),
3955 ('connection'),
3956 ('type'),
3957 ('function'),
3958 ('secret')
3959 )
3960 AS _ (object_type)"#,
3961 access: vec![PUBLIC_SELECT],
3962 ontology: None,
3963});
3964
3965pub static MZ_OBJECT_GRAPH_EDGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3976 name: "mz_object_graph_edges",
3977 schema: MZ_INTERNAL_SCHEMA,
3978 oid: oid::VIEW_MZ_OBJECT_GRAPH_EDGES_OID,
3979 desc: RelationDesc::builder()
3980 .with_column("object_id", SqlScalarType::String.nullable(false))
3981 .with_column("dependency_id", SqlScalarType::String.nullable(false))
3982 .with_key(vec![0, 1])
3983 .finish(),
3984 column_comments: BTreeMap::from_iter([
3985 (
3986 "object_id",
3987 "The ID of the dependent object. Corresponds to `mz_objects.id`.",
3988 ),
3989 (
3990 "dependency_id",
3991 "The ID of the object it depends on. Corresponds to `mz_objects.id`.",
3992 ),
3993 ]),
3994 sql: "
3995SELECT md.object_id, md.dependency_id
3996FROM mz_internal.mz_materialization_dependencies md
3997JOIN mz_catalog.mz_objects po ON po.id = md.dependency_id
3998 AND po.type IN ('index', 'materialized-view', 'sink', 'source', 'table')
3999JOIN mz_catalog.mz_objects co ON co.id = md.object_id
4000 AND co.type IN ('index', 'materialized-view', 'sink', 'source', 'table')
4001UNION
4002-- Subsource -> parent-source edges: a subsource depends on the (user) source it
4003-- belongs to, an edge mz_materialization_dependencies doesn't carry.
4004SELECT od.object_id, od.referenced_object_id
4005FROM mz_internal.mz_object_dependencies od
4006JOIN mz_catalog.mz_sources ps ON ps.id = od.referenced_object_id
4007JOIN mz_catalog.mz_sources cs ON cs.id = od.object_id
4008-- Progress collections are deliberately left out: their dependency edge points
4009-- source -> progress, and they only exist for old-syntax sources, which the
4010-- source-table migration is removing.
4011WHERE ps.id LIKE 'u%' AND cs.type = 'subsource'
4012UNION
4013-- Select the (non-null) source id from the join rather than the nullable
4014-- mz_tables.source_id, so dependency_id is non-null across all branches.
4015SELECT t.id, ps.id
4016FROM mz_catalog.mz_tables t
4017JOIN mz_catalog.mz_sources ps ON ps.id = t.source_id",
4018 access: vec![PUBLIC_SELECT],
4019 ontology: None,
4023});
4024
4025pub static MZ_OBJECT_OID_ALIAS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4026 name: "mz_object_oid_alias",
4027 schema: MZ_INTERNAL_SCHEMA,
4028 oid: oid::VIEW_MZ_OBJECT_OID_ALIAS_OID,
4029 desc: RelationDesc::builder()
4030 .with_column("object_type", SqlScalarType::String.nullable(false))
4031 .with_column("oid_alias", SqlScalarType::String.nullable(false))
4032 .with_key(vec![0])
4033 .finish(),
4034 column_comments: BTreeMap::new(),
4035 sql: "SELECT object_type, oid_alias
4036 FROM (
4037 VALUES
4038 (
4039 'table'::pg_catalog.text,
4040 'regclass'::pg_catalog.text
4041 ),
4042 ('source', 'regclass'),
4043 ('view', 'regclass'),
4044 ('materialized-view', 'regclass'),
4045 ('index', 'regclass'),
4046 ('type', 'regtype'),
4047 ('function', 'regproc')
4048 )
4049 AS _ (object_type, oid_alias);",
4050 access: vec![PUBLIC_SELECT],
4051 ontology: None,
4052});
4053
4054pub static MZ_OBJECT_FULLY_QUALIFIED_NAMES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4055 name: "mz_object_fully_qualified_names",
4056 schema: MZ_INTERNAL_SCHEMA,
4057 oid: oid::VIEW_MZ_OBJECT_FULLY_QUALIFIED_NAMES_OID,
4058 desc: RelationDesc::builder()
4059 .with_column("id", SqlScalarType::String.nullable(false))
4060 .with_column("name", SqlScalarType::String.nullable(false))
4061 .with_column("object_type", SqlScalarType::String.nullable(false))
4062 .with_column("schema_id", SqlScalarType::String.nullable(false))
4063 .with_column("schema_name", SqlScalarType::String.nullable(false))
4064 .with_column("database_id", SqlScalarType::String.nullable(true))
4065 .with_column("database_name", SqlScalarType::String.nullable(true))
4066 .with_column("cluster_id", SqlScalarType::String.nullable(true))
4067 .finish(),
4068 column_comments: BTreeMap::from_iter([
4069 ("id", "Materialize's unique ID for the object."),
4070 ("name", "The name of the object."),
4071 (
4072 "object_type",
4073 "The type of the object: one of `table`, `source`, `view`, `materialized-view`, `sink`, `index`, `connection`, `secret`, `type`, or `function`.",
4074 ),
4075 (
4076 "schema_id",
4077 "The ID of the schema to which the object belongs. Corresponds to `mz_schemas.id`.",
4078 ),
4079 (
4080 "schema_name",
4081 "The name of the schema to which the object belongs. Corresponds to `mz_schemas.name`.",
4082 ),
4083 (
4084 "database_id",
4085 "The ID of the database to which the object belongs. Corresponds to `mz_databases.id`.",
4086 ),
4087 (
4088 "database_name",
4089 "The name of the database to which the object belongs. Corresponds to `mz_databases.name`.",
4090 ),
4091 (
4092 "cluster_id",
4093 "The ID of the cluster maintaining the source, materialized view, index, or sink. Corresponds to `mz_clusters.id`. `NULL` for other object types.",
4094 ),
4095 ]),
4096 sql: "
4097 SELECT o.id,
4098 o.name,
4099 o.type as object_type,
4100 sc.id as schema_id,
4101 sc.name as schema_name,
4102 db.id as database_id,
4103 db.name as database_name,
4104 o.cluster_id
4105 FROM mz_catalog.mz_objects o
4106 INNER JOIN mz_catalog.mz_schemas sc ON sc.id = o.schema_id
4107 -- LEFT JOIN accounts for objects in the ambient database.
4108 LEFT JOIN mz_catalog.mz_databases db ON db.id = sc.database_id",
4109 access: vec![PUBLIC_SELECT],
4110 ontology: Some(Ontology {
4111 entity_name: "object_fqn",
4112 description: "Fully qualified name (database.schema.name) for objects",
4113 links: &const {
4114 [
4115 OntologyLink {
4116 name: "details_of",
4117 target: "object",
4118 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
4119 },
4120 OntologyLink {
4121 name: "in_schema",
4122 target: "schema",
4123 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
4124 },
4125 OntologyLink {
4126 name: "in_database",
4127 target: "database",
4128 properties: LinkProperties::fk("database_id", "id", Cardinality::ManyToOne),
4129 },
4130 OntologyLink {
4131 name: "belongs_to_cluster",
4132 target: "cluster",
4133 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
4134 },
4135 ]
4136 },
4137 column_semantic_types: &const {
4138 [
4139 ("id", SemanticType::CatalogItemId),
4140 ("object_type", SemanticType::ObjectType),
4141 ("schema_id", SemanticType::SchemaId),
4142 ("database_id", SemanticType::DatabaseId),
4143 ("cluster_id", SemanticType::ClusterId),
4144 ]
4145 },
4146 }),
4147});
4148
4149pub static MZ_OBJECT_GLOBAL_IDS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
4150 name: "mz_object_global_ids",
4151 schema: MZ_INTERNAL_SCHEMA,
4152 oid: oid::VIEW_MZ_OBJECT_GLOBAL_IDS_OID,
4153 desc: RelationDesc::builder()
4154 .with_column("id", SqlScalarType::String.nullable(false))
4155 .with_column("global_id", SqlScalarType::String.nullable(false))
4156 .finish(),
4157 column_comments: BTreeMap::from_iter([
4158 (
4159 "id",
4160 "The ID of the object. Corresponds to `mz_objects.id`.",
4161 ),
4162 ("global_id", "The global ID of the object."),
4163 ]),
4164 is_retained_metrics_object: false,
4165 access: vec![PUBLIC_SELECT],
4166 ontology: Some(Ontology {
4167 entity_name: "object_global_id",
4168 description: "Mapping between CatalogItemId (SQL layer) and GlobalId (runtime layer)",
4169 links: &const {
4170 [OntologyLink {
4171 name: "id_references",
4172 target: "object",
4173 properties: LinkProperties::fk("id", "id", Cardinality::ManyToOne),
4174 }]
4175 },
4176 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
4177 }),
4178});
4179
4180pub static MZ_OBJECT_LIFETIMES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4182 name: "mz_object_lifetimes",
4183 schema: MZ_INTERNAL_SCHEMA,
4184 oid: oid::VIEW_MZ_OBJECT_LIFETIMES_OID,
4185 desc: RelationDesc::builder()
4186 .with_column("id", SqlScalarType::String.nullable(true))
4187 .with_column("previous_id", SqlScalarType::String.nullable(true))
4188 .with_column("object_type", SqlScalarType::String.nullable(false))
4189 .with_column("event_type", SqlScalarType::String.nullable(false))
4190 .with_column(
4191 "occurred_at",
4192 SqlScalarType::TimestampTz { precision: None }.nullable(false),
4193 )
4194 .finish(),
4195 column_comments: BTreeMap::from_iter([
4196 ("id", "Materialize's unique ID for the object."),
4197 ("previous_id", "The object's previous ID, if one exists."),
4198 (
4199 "object_type",
4200 "The type of the object: one of `table`, `source`, `view`, `materialized-view`, `sink`, `index`, `connection`, `secret`, `type`, or `function`.",
4201 ),
4202 (
4203 "event_type",
4204 "The lifetime event, either `create` or `drop`.",
4205 ),
4206 (
4207 "occurred_at",
4208 "Wall-clock timestamp of when the event occurred.",
4209 ),
4210 ]),
4211 sql: "
4212 SELECT
4213 CASE
4214 WHEN a.object_type = 'cluster-replica' THEN a.details ->> 'replica_id'
4215 ELSE a.details ->> 'id'
4216 END id,
4217 a.details ->> 'previous_id' as previous_id,
4218 a.object_type,
4219 a.event_type,
4220 a.occurred_at
4221 FROM mz_catalog.mz_audit_events a
4222 WHERE a.event_type = 'create' OR a.event_type = 'drop'",
4223 access: vec![PUBLIC_SELECT],
4224 ontology: Some(Ontology {
4225 entity_name: "object_lifetime_event",
4226 description: "Create or drop lifecycle event for a catalog object",
4227 links: &const {
4228 [OntologyLink {
4229 name: "lifetime_event_of",
4230 target: "object",
4231 properties: LinkProperties::fk_typed(
4232 "id",
4233 "id",
4234 Cardinality::ManyToOne,
4235 mz_repr::SemanticType::CatalogItemId,
4236 ),
4237 }]
4238 },
4239 column_semantic_types: &const {
4240 [
4241 ("id", SemanticType::CatalogItemId),
4242 ("object_type", SemanticType::ObjectType),
4243 ]
4244 },
4245 }),
4246});
4247
4248pub static MZ_OBJECT_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4249 name: "mz_object_history",
4250 schema: MZ_INTERNAL_SCHEMA,
4251 oid: oid::VIEW_MZ_OBJECT_HISTORY_OID,
4252 desc: RelationDesc::builder()
4253 .with_column("id", SqlScalarType::String.nullable(true))
4254 .with_column("cluster_id", SqlScalarType::String.nullable(true))
4255 .with_column("object_type", SqlScalarType::String.nullable(false))
4256 .with_column(
4257 "created_at",
4258 SqlScalarType::TimestampTz { precision: None }.nullable(true),
4259 )
4260 .with_column(
4261 "dropped_at",
4262 SqlScalarType::TimestampTz { precision: None }.nullable(true),
4263 )
4264 .finish(),
4265 column_comments: BTreeMap::from_iter([
4266 ("id", "Materialize's unique ID for the object."),
4267 (
4268 "cluster_id",
4269 "The object's cluster ID. `NULL` if the object has no associated cluster.",
4270 ),
4271 (
4272 "object_type",
4273 "The type of the object: one of `table`, `source`, `view`, `materialized-view`, `sink`, `index`, `connection`, `secret`, `type`, or `function`.",
4274 ),
4275 (
4276 "created_at",
4277 "Wall-clock timestamp of when the object was created. `NULL` for built in system objects.",
4278 ),
4279 (
4280 "dropped_at",
4281 "Wall-clock timestamp of when the object was dropped. `NULL` for built in system objects or if the object hasn't been dropped.",
4282 ),
4283 ]),
4284 sql: r#"
4285 WITH
4286 creates AS
4287 (
4288 SELECT
4289 details ->> 'id' AS id,
4290 -- We need to backfill cluster_id since older object create events don't include the cluster ID in the audit log
4291 COALESCE(details ->> 'cluster_id', objects.cluster_id) AS cluster_id,
4292 object_type,
4293 occurred_at
4294 FROM
4295 mz_catalog.mz_audit_events AS events
4296 LEFT JOIN mz_catalog.mz_objects AS objects ON details ->> 'id' = objects.id
4297 WHERE event_type = 'create' AND object_type IN ( SELECT object_type FROM mz_internal.mz_objects_id_namespace_types )
4298 ),
4299 drops AS
4300 (
4301 SELECT details ->> 'id' AS id, occurred_at
4302 FROM mz_catalog.mz_audit_events
4303 WHERE event_type = 'drop' AND object_type IN ( SELECT object_type FROM mz_internal.mz_objects_id_namespace_types )
4304 ),
4305 user_object_history AS
4306 (
4307 SELECT
4308 creates.id,
4309 creates.cluster_id,
4310 creates.object_type,
4311 creates.occurred_at AS created_at,
4312 drops.occurred_at AS dropped_at
4313 FROM creates LEFT JOIN drops ON creates.id = drops.id
4314 WHERE creates.id LIKE 'u%'
4315 ),
4316 -- We need to union built in objects since they aren't in the audit log
4317 built_in_objects AS
4318 (
4319 -- Functions that accept different arguments have different oids but the same id. We deduplicate in this case.
4320 SELECT DISTINCT ON (objects.id)
4321 objects.id,
4322 objects.cluster_id,
4323 objects.type AS object_type,
4324 NULL::timestamptz AS created_at,
4325 NULL::timestamptz AS dropped_at
4326 FROM mz_catalog.mz_objects AS objects
4327 WHERE objects.id LIKE 's%'
4328 )
4329 SELECT * FROM user_object_history UNION ALL (SELECT * FROM built_in_objects)"#,
4330 access: vec![PUBLIC_SELECT],
4331 ontology: Some(Ontology {
4332 entity_name: "object_history",
4333 description: "Historical record of object creation and drops",
4334 links: &const {
4335 [OntologyLink {
4336 name: "history_of",
4337 target: "object",
4338 properties: LinkProperties::fk("id", "id", Cardinality::ManyToOne),
4339 }]
4340 },
4341 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
4342 }),
4343});
4344
4345pub static MZ_OBJECT_TRANSITIVE_DEPENDENCIES: LazyLock<BuiltinView> = LazyLock::new(|| {
4346 BuiltinView {
4347 name: "mz_object_transitive_dependencies",
4348 schema: MZ_INTERNAL_SCHEMA,
4349 oid: oid::VIEW_MZ_OBJECT_TRANSITIVE_DEPENDENCIES_OID,
4350 desc: RelationDesc::builder()
4351 .with_column("object_id", SqlScalarType::String.nullable(false))
4352 .with_column(
4353 "referenced_object_id",
4354 SqlScalarType::String.nullable(false),
4355 )
4356 .with_key(vec![0, 1])
4357 .finish(),
4358 column_comments: BTreeMap::from_iter([
4359 (
4360 "object_id",
4361 "The ID of the dependent object. Corresponds to `mz_objects.id`.",
4362 ),
4363 (
4364 "referenced_object_id",
4365 "The ID of the (possibly transitively) referenced object. Corresponds to `mz_objects.id`.",
4366 ),
4367 ]),
4368 sql: "
4369WITH MUTUALLY RECURSIVE
4370 reach(object_id text, referenced_object_id text) AS (
4371 SELECT object_id, referenced_object_id FROM mz_internal.mz_object_dependencies
4372 UNION
4373 SELECT x, z FROM reach r1(x, y) JOIN reach r2(y, z) USING(y)
4374 )
4375SELECT object_id, referenced_object_id FROM reach;",
4376 access: vec![PUBLIC_SELECT],
4377 ontology: Some(Ontology {
4378 entity_name: "transitive_dependency",
4379 description: "Transitive closure of object dependencies — all direct and indirect dependencies",
4380 links: &const {
4381 [
4382 OntologyLink {
4383 name: "depends_on",
4384 target: "object",
4385 properties: LinkProperties::DependsOn {
4386 source_column: "object_id",
4387 target_column: "id",
4388 source_id_type: Some(mz_repr::SemanticType::CatalogItemId),
4389 requires_mapping: None,
4390 },
4391 },
4392 OntologyLink {
4393 name: "dependency_is",
4394 target: "object",
4395 properties: LinkProperties::DependsOn {
4396 source_column: "referenced_object_id",
4397 target_column: "id",
4398 source_id_type: Some(mz_repr::SemanticType::CatalogItemId),
4399 requires_mapping: None,
4400 },
4401 },
4402 ]
4403 },
4404 column_semantic_types: &const {
4405 [
4406 ("object_id", SemanticType::CatalogItemId),
4407 ("referenced_object_id", SemanticType::CatalogItemId),
4408 ]
4409 },
4410 }),
4411 }
4412});
4413
4414pub static PG_NAMESPACE_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4420 name: "pg_namespace_all_databases",
4421 schema: MZ_INTERNAL_SCHEMA,
4422 oid: oid::VIEW_PG_NAMESPACE_ALL_DATABASES_OID,
4423 desc: RelationDesc::builder()
4424 .with_column("oid", SqlScalarType::Oid.nullable(false))
4425 .with_column("nspname", SqlScalarType::String.nullable(false))
4426 .with_column("nspowner", SqlScalarType::Oid.nullable(false))
4427 .with_column(
4428 "nspacl",
4429 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(true),
4430 )
4431 .with_column("database_name", SqlScalarType::String.nullable(true))
4432 .finish(),
4433 column_comments: BTreeMap::new(),
4434 sql: "
4435SELECT
4436 s.oid AS oid,
4437 s.name AS nspname,
4438 role_owner.oid AS nspowner,
4439 NULL::pg_catalog.text[] AS nspacl,
4440 d.name as database_name
4441FROM mz_catalog.mz_schemas s
4442LEFT JOIN mz_catalog.mz_databases d ON d.id = s.database_id
4443JOIN mz_catalog.mz_roles role_owner ON role_owner.id = s.owner_id",
4444 access: vec![PUBLIC_SELECT],
4445 ontology: None,
4446});
4447
4448pub const PG_NAMESPACE_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4449 name: "pg_namespace_all_databases_ind",
4450 schema: MZ_INTERNAL_SCHEMA,
4451 oid: oid::INDEX_PG_NAMESPACE_ALL_DATABASES_IND_OID,
4452 sql: "IN CLUSTER mz_catalog_server
4453ON mz_internal.pg_namespace_all_databases (nspname)",
4454 is_retained_metrics_object: false,
4455};
4456
4457pub static PG_CLASS_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| {
4463 BuiltinView {
4464 name: "pg_class_all_databases",
4465 schema: MZ_INTERNAL_SCHEMA,
4466 oid: oid::VIEW_PG_CLASS_ALL_DATABASES_OID,
4467 desc: RelationDesc::builder()
4468 .with_column("oid", SqlScalarType::Oid.nullable(false))
4469 .with_column("relname", SqlScalarType::String.nullable(false))
4470 .with_column("relnamespace", SqlScalarType::Oid.nullable(false))
4471 .with_column("reloftype", SqlScalarType::Oid.nullable(false))
4472 .with_column("relowner", SqlScalarType::Oid.nullable(false))
4473 .with_column("relam", SqlScalarType::Oid.nullable(false))
4474 .with_column("reltablespace", SqlScalarType::Oid.nullable(false))
4475 .with_column("reltuples", SqlScalarType::Float32.nullable(false))
4476 .with_column("reltoastrelid", SqlScalarType::Oid.nullable(false))
4477 .with_column("relhasindex", SqlScalarType::Bool.nullable(false))
4478 .with_column("relpersistence", SqlScalarType::PgLegacyChar.nullable(false))
4479 .with_column("relkind", SqlScalarType::String.nullable(true))
4480 .with_column("relnatts", SqlScalarType::Int16.nullable(false))
4481 .with_column("relchecks", SqlScalarType::Int16.nullable(false))
4482 .with_column("relhasrules", SqlScalarType::Bool.nullable(false))
4483 .with_column("relhastriggers", SqlScalarType::Bool.nullable(false))
4484 .with_column("relhassubclass", SqlScalarType::Bool.nullable(false))
4485 .with_column("relrowsecurity", SqlScalarType::Bool.nullable(false))
4486 .with_column("relforcerowsecurity", SqlScalarType::Bool.nullable(false))
4487 .with_column("relreplident", SqlScalarType::PgLegacyChar.nullable(false))
4488 .with_column("relispartition", SqlScalarType::Bool.nullable(false))
4489 .with_column("relhasoids", SqlScalarType::Bool.nullable(false))
4490 .with_column("reloptions", SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(true))
4491 .with_column("database_name", SqlScalarType::String.nullable(true))
4492 .finish(),
4493 column_comments: BTreeMap::new(),
4494 sql: "
4495SELECT
4496 class_objects.oid,
4497 class_objects.name AS relname,
4498 mz_schemas.oid AS relnamespace,
4499 -- MZ doesn't support typed tables so reloftype is filled with 0
4500 0::pg_catalog.oid AS reloftype,
4501 role_owner.oid AS relowner,
4502 0::pg_catalog.oid AS relam,
4503 -- MZ doesn't have tablespaces so reltablespace is filled in with 0 implying the default tablespace
4504 0::pg_catalog.oid AS reltablespace,
4505 -- MZ doesn't support (estimated) row counts currently.
4506 -- Postgres defines a value of -1 as unknown.
4507 -1::float4 as reltuples,
4508 -- MZ doesn't use TOAST tables so reltoastrelid is filled with 0
4509 0::pg_catalog.oid AS reltoastrelid,
4510 EXISTS (SELECT id, oid, name, on_id, cluster_id FROM mz_catalog.mz_indexes where mz_indexes.on_id = class_objects.id) AS relhasindex,
4511 -- MZ doesn't have unlogged tables and because of (https://github.com/MaterializeInc/database-issues/issues/2689)
4512 -- temporary objects don't show up here, so relpersistence is filled with 'p' for permanent.
4513 -- TODO(jkosh44): update this column when issue is resolved.
4514 'p'::pg_catalog.\"char\" AS relpersistence,
4515 CASE
4516 WHEN class_objects.type = 'table' THEN 'r'
4517 WHEN class_objects.type = 'source' THEN 'r'
4518 WHEN class_objects.type = 'index' THEN 'i'
4519 WHEN class_objects.type = 'view' THEN 'v'
4520 WHEN class_objects.type = 'materialized-view' THEN 'm'
4521 END relkind,
4522 CASE
4523 WHEN class_objects.type = 'index' THEN COALESCE(
4524 (
4525 SELECT count(*)::pg_catalog.int2
4526 FROM mz_catalog.mz_index_columns
4527 WHERE mz_index_columns.index_id = class_objects.id
4528 ),
4529 0::pg_catalog.int2
4530 )
4531 ELSE COALESCE(
4532 (
4533 SELECT count(*)::pg_catalog.int2
4534 FROM mz_catalog.mz_columns
4535 WHERE mz_columns.id = class_objects.id
4536 ),
4537 0::pg_catalog.int2
4538 )
4539 END AS relnatts,
4540 -- MZ doesn't support CHECK constraints so relchecks is filled with 0
4541 0::pg_catalog.int2 AS relchecks,
4542 -- MZ doesn't support creating rules so relhasrules is filled with false
4543 false AS relhasrules,
4544 -- MZ doesn't support creating triggers so relhastriggers is filled with false
4545 false AS relhastriggers,
4546 -- MZ doesn't support table inheritance or partitions so relhassubclass is filled with false
4547 false AS relhassubclass,
4548 -- MZ doesn't have row level security so relrowsecurity and relforcerowsecurity is filled with false
4549 false AS relrowsecurity,
4550 false AS relforcerowsecurity,
4551 -- MZ doesn't support replication so relreplident is filled with 'd' for default
4552 'd'::pg_catalog.\"char\" AS relreplident,
4553 -- MZ doesn't support table partitioning so relispartition is filled with false
4554 false AS relispartition,
4555 -- PG removed relhasoids in v12 so it's filled with false
4556 false AS relhasoids,
4557 -- MZ doesn't support options for relations
4558 NULL::pg_catalog.text[] as reloptions,
4559 d.name as database_name
4560FROM (
4561 -- pg_class catalogs relations and indexes
4562 SELECT id, oid, schema_id, name, type, owner_id FROM mz_catalog.mz_relations
4563 UNION ALL
4564 SELECT mz_indexes.id, mz_indexes.oid, mz_relations.schema_id, mz_indexes.name, 'index' AS type, mz_indexes.owner_id
4565 FROM mz_catalog.mz_indexes
4566 JOIN mz_catalog.mz_relations ON mz_indexes.on_id = mz_relations.id
4567) AS class_objects
4568JOIN mz_catalog.mz_schemas ON mz_schemas.id = class_objects.schema_id
4569LEFT JOIN mz_catalog.mz_databases d ON d.id = mz_schemas.database_id
4570JOIN mz_catalog.mz_roles role_owner ON role_owner.id = class_objects.owner_id",
4571 access: vec![PUBLIC_SELECT],
4572 ontology: None,
4573 }
4574});
4575
4576pub const PG_CLASS_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4577 name: "pg_class_all_databases_ind",
4578 schema: MZ_INTERNAL_SCHEMA,
4579 oid: oid::INDEX_PG_CLASS_ALL_DATABASES_IND_OID,
4580 sql: "IN CLUSTER mz_catalog_server
4581ON mz_internal.pg_class_all_databases (relname)",
4582 is_retained_metrics_object: false,
4583};
4584
4585pub static PG_DESCRIPTION_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| {
4591 BuiltinView {
4592 name: "pg_description_all_databases",
4593 schema: MZ_INTERNAL_SCHEMA,
4594 oid: oid::VIEW_PG_DESCRIPTION_ALL_DATABASES_OID,
4595 desc: RelationDesc::builder()
4596 .with_column("objoid", SqlScalarType::Oid.nullable(false))
4597 .with_column("classoid", SqlScalarType::Oid.nullable(true))
4598 .with_column("objsubid", SqlScalarType::Int32.nullable(false))
4599 .with_column("description", SqlScalarType::String.nullable(false))
4600 .with_column("oid_database_name", SqlScalarType::String.nullable(true))
4601 .with_column("class_database_name", SqlScalarType::String.nullable(true))
4602 .finish(),
4603 column_comments: BTreeMap::new(),
4604 sql: "
4605(
4606 -- The classoid of a comment is the oid of the pg_catalog system catalog
4607 -- that conceptually stores the commented object: pg_class for relations,
4608 -- pg_type for types, pg_namespace for schemas. We scope the lookup to the
4609 -- pg_catalog schema; otherwise a user-created object named e.g. `pg_class`
4610 -- makes the scalar subqueries below match multiple rows and the whole view
4611 -- errors for everyone. PostgreSQL's pg_description is a real catalog table
4612 -- and is unaffected by such user objects, and so are we.
4613 WITH pg_catalog_class AS (
4614 SELECT oid, relname, database_name
4615 FROM mz_internal.pg_class_all_databases
4616 WHERE relnamespace = (
4617 SELECT oid FROM mz_internal.pg_namespace_all_databases WHERE nspname = 'pg_catalog'
4618 )
4619 ),
4620 -- Gather all of the class oid's for objects that can have comments.
4621 pg_classoids AS (
4622 SELECT oid, database_name as oid_database_name,
4623 (SELECT oid FROM pg_catalog_class WHERE relname = 'pg_class') AS classoid,
4624 (SELECT database_name FROM pg_catalog_class WHERE relname = 'pg_class') AS class_database_name
4625 FROM mz_internal.pg_class_all_databases
4626 UNION ALL
4627 SELECT oid, database_name as oid_database_name,
4628 (SELECT oid FROM pg_catalog_class WHERE relname = 'pg_type') AS classoid,
4629 (SELECT database_name FROM pg_catalog_class WHERE relname = 'pg_type') AS class_database_name
4630 FROM mz_internal.pg_type_all_databases
4631 UNION ALL
4632 SELECT oid, database_name as oid_database_name,
4633 (SELECT oid FROM pg_catalog_class WHERE relname = 'pg_namespace') AS classoid,
4634 (SELECT database_name FROM pg_catalog_class WHERE relname = 'pg_namespace') AS class_database_name
4635 FROM mz_internal.pg_namespace_all_databases
4636 ),
4637
4638 -- Gather all of the MZ ids for objects that can have comments.
4639 mz_objects AS (
4640 SELECT id, oid, type FROM mz_catalog.mz_objects
4641 UNION ALL
4642 SELECT id, oid, 'schema' AS type FROM mz_catalog.mz_schemas
4643 )
4644 SELECT
4645 pg_classoids.oid AS objoid,
4646 pg_classoids.classoid as classoid,
4647 COALESCE(cmt.object_sub_id, 0) AS objsubid,
4648 cmt.comment AS description,
4649 -- Columns added because of the peeling. (Note that there are 2 of these here.)
4650 oid_database_name,
4651 class_database_name
4652 FROM
4653 pg_classoids
4654 JOIN
4655 mz_objects ON pg_classoids.oid = mz_objects.oid
4656 JOIN
4657 mz_internal.mz_comments AS cmt ON mz_objects.id = cmt.id AND lower(mz_objects.type) = lower(cmt.object_type)
4658)",
4659 access: vec![PUBLIC_SELECT],
4660 ontology: None,
4661 }
4662});
4663
4664pub const PG_DESCRIPTION_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4665 name: "pg_description_all_databases_ind",
4666 schema: MZ_INTERNAL_SCHEMA,
4667 oid: oid::INDEX_PG_DESCRIPTION_ALL_DATABASES_IND_OID,
4668 sql: "IN CLUSTER mz_catalog_server
4669ON mz_internal.pg_description_all_databases (objoid, classoid, objsubid, description, oid_database_name, class_database_name)",
4670 is_retained_metrics_object: false,
4671};
4672
4673pub static PG_TYPE_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| {
4679 BuiltinView {
4680 name: "pg_type_all_databases",
4681 schema: MZ_INTERNAL_SCHEMA,
4682 oid: oid::VIEW_PG_TYPE_ALL_DATABASES_OID,
4683 desc: RelationDesc::builder()
4684 .with_column("oid", SqlScalarType::Oid.nullable(false))
4685 .with_column("typname", SqlScalarType::String.nullable(false))
4686 .with_column("typnamespace", SqlScalarType::Oid.nullable(false))
4687 .with_column("typowner", SqlScalarType::Oid.nullable(false))
4688 .with_column("typlen", SqlScalarType::Int16.nullable(true))
4689 .with_column("typtype", SqlScalarType::PgLegacyChar.nullable(false))
4690 .with_column("typcategory", SqlScalarType::PgLegacyChar.nullable(true))
4691 .with_column("typdelim", SqlScalarType::PgLegacyChar.nullable(false))
4692 .with_column("typrelid", SqlScalarType::Oid.nullable(false))
4693 .with_column("typelem", SqlScalarType::Oid.nullable(false))
4694 .with_column("typarray", SqlScalarType::Oid.nullable(false))
4695 .with_column("typinput", SqlScalarType::RegProc.nullable(true))
4696 .with_column("typreceive", SqlScalarType::Oid.nullable(false))
4697 .with_column("typnotnull", SqlScalarType::Bool.nullable(false))
4698 .with_column("typbasetype", SqlScalarType::Oid.nullable(false))
4699 .with_column("typtypmod", SqlScalarType::Int32.nullable(false))
4700 .with_column("typcollation", SqlScalarType::Oid.nullable(false))
4701 .with_column("typdefault", SqlScalarType::String.nullable(true))
4702 .with_column("database_name", SqlScalarType::String.nullable(true))
4703 .with_column("typsend", SqlScalarType::RegProc.nullable(false))
4704 .finish(),
4705 column_comments: BTreeMap::new(),
4706 sql: "
4707SELECT
4708 mz_types.oid,
4709 mz_types.name AS typname,
4710 mz_schemas.oid AS typnamespace,
4711 role_owner.oid AS typowner,
4712 NULL::pg_catalog.int2 AS typlen,
4713 -- 'a' is used internally to denote an array type, but in postgres they show up
4714 -- as 'b'.
4715 (CASE mztype WHEN 'a' THEN 'b' ELSE mztype END)::pg_catalog.char AS typtype,
4716 (CASE category
4717 WHEN 'array' THEN 'A'
4718 WHEN 'bit-string' THEN 'V'
4719 WHEN 'boolean' THEN 'B'
4720 WHEN 'composite' THEN 'C'
4721 WHEN 'date-time' THEN 'D'
4722 WHEN 'enum' THEN 'E'
4723 WHEN 'geometric' THEN 'G'
4724 WHEN 'list' THEN 'U' -- List types are user-defined from PostgreSQL's perspective.
4725 WHEN 'network-address' THEN 'I'
4726 WHEN 'numeric' THEN 'N'
4727 WHEN 'pseudo' THEN 'P'
4728 WHEN 'string' THEN 'S'
4729 WHEN 'timespan' THEN 'T'
4730 WHEN 'user-defined' THEN 'U'
4731 WHEN 'unknown' THEN 'X'
4732 END)::pg_catalog.char AS typcategory,
4733 -- In pg only the 'box' type is not ','.
4734 ','::pg_catalog.char AS typdelim,
4735 0::pg_catalog.oid AS typrelid,
4736 coalesce(
4737 (
4738 SELECT t.oid
4739 FROM mz_catalog.mz_array_types a
4740 JOIN mz_catalog.mz_types t ON a.element_id = t.id
4741 WHERE a.id = mz_types.id
4742 ),
4743 (
4744 SELECT t.oid
4745 FROM mz_catalog.mz_list_types l
4746 JOIN mz_catalog.mz_types t ON l.element_id = t.id
4747 WHERE l.id = mz_types.id
4748 ),
4749 0
4750 ) AS typelem,
4751 coalesce(
4752 (
4753 SELECT
4754 t.oid
4755 FROM
4756 mz_catalog.mz_array_types AS a
4757 JOIN mz_catalog.mz_types AS t ON a.id = t.id
4758 WHERE
4759 a.element_id = mz_types.id
4760 ),
4761 0
4762 )
4763 AS typarray,
4764 mz_internal.mz_type_pg_metadata.typinput::pg_catalog.regproc AS typinput,
4765 COALESCE(mz_internal.mz_type_pg_metadata.typreceive, 0) AS typreceive,
4766 false::pg_catalog.bool AS typnotnull,
4767 0::pg_catalog.oid AS typbasetype,
4768 -1::pg_catalog.int4 AS typtypmod,
4769 -- MZ doesn't support COLLATE so typcollation is filled with 0
4770 0::pg_catalog.oid AS typcollation,
4771 NULL::pg_catalog.text AS typdefault,
4772 d.name as database_name,
4773 COALESCE(mz_internal.mz_type_pg_metadata.typsend, 0)::pg_catalog.regproc AS typsend
4774FROM
4775 mz_catalog.mz_types
4776 LEFT JOIN mz_internal.mz_type_pg_metadata ON mz_catalog.mz_types.id = mz_internal.mz_type_pg_metadata.id
4777 JOIN mz_catalog.mz_schemas ON mz_schemas.id = mz_types.schema_id
4778 JOIN (
4779 -- 'a' is not a supported typtype, but we use it to denote an array. It is
4780 -- converted to the correct value above.
4781 SELECT id, 'a' AS mztype FROM mz_catalog.mz_array_types
4782 UNION ALL SELECT id, 'b' FROM mz_catalog.mz_base_types
4783 UNION ALL SELECT id, 'l' FROM mz_catalog.mz_list_types
4784 UNION ALL SELECT id, 'm' FROM mz_catalog.mz_map_types
4785 UNION ALL SELECT id, 'p' FROM mz_catalog.mz_pseudo_types
4786 )
4787 AS t ON mz_types.id = t.id
4788 LEFT JOIN mz_catalog.mz_databases d ON d.id = mz_schemas.database_id
4789 JOIN mz_catalog.mz_roles role_owner ON role_owner.id = mz_types.owner_id",
4790 access: vec![PUBLIC_SELECT],
4791 ontology: None,
4792 }
4793});
4794
4795pub const PG_TYPE_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4796 name: "pg_type_all_databases_ind",
4797 schema: MZ_INTERNAL_SCHEMA,
4798 oid: oid::INDEX_PG_TYPE_ALL_DATABASES_IND_OID,
4799 sql: "IN CLUSTER mz_catalog_server
4800ON mz_internal.pg_type_all_databases (oid)",
4801 is_retained_metrics_object: false,
4802};
4803
4804pub static PG_ATTRIBUTE_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| {
4810 BuiltinView {
4811 name: "pg_attribute_all_databases",
4812 schema: MZ_INTERNAL_SCHEMA,
4813 oid: oid::VIEW_PG_ATTRIBUTE_ALL_DATABASES_OID,
4814 desc: RelationDesc::builder()
4815 .with_column("attrelid", SqlScalarType::Oid.nullable(false))
4816 .with_column("attname", SqlScalarType::String.nullable(false))
4817 .with_column("atttypid", SqlScalarType::Oid.nullable(false))
4818 .with_column("attlen", SqlScalarType::Int16.nullable(true))
4819 .with_column("attnum", SqlScalarType::Int16.nullable(false))
4820 .with_column("atttypmod", SqlScalarType::Int32.nullable(false))
4821 .with_column("attndims", SqlScalarType::Int16.nullable(false))
4822 .with_column("attnotnull", SqlScalarType::Bool.nullable(false))
4823 .with_column("atthasdef", SqlScalarType::Bool.nullable(false))
4824 .with_column("attidentity", SqlScalarType::PgLegacyChar.nullable(false))
4825 .with_column("attgenerated", SqlScalarType::PgLegacyChar.nullable(false))
4826 .with_column("attisdropped", SqlScalarType::Bool.nullable(false))
4827 .with_column("attcollation", SqlScalarType::Oid.nullable(false))
4828 .with_column("database_name", SqlScalarType::String.nullable(true))
4829 .with_column("pg_type_database_name", SqlScalarType::String.nullable(true))
4830 .finish(),
4831 column_comments: BTreeMap::new(),
4832 sql: "
4833SELECT
4834 class_objects.oid as attrelid,
4835 mz_columns.name as attname,
4836 mz_columns.type_oid AS atttypid,
4837 pg_type_all_databases.typlen AS attlen,
4838 position::int8::int2 as attnum,
4839 mz_columns.type_mod as atttypmod,
4840 -- dummy value, just to make go-jet's workaround work for now. Discussion:
4841 -- https://github.com/MaterializeInc/materialize/pull/34649#issuecomment-3714291409
4842 0::int2 as attndims,
4843 NOT nullable as attnotnull,
4844 mz_columns.default IS NOT NULL as atthasdef,
4845 ''::pg_catalog.\"char\" as attidentity,
4846 -- MZ doesn't support generated columns so attgenerated is filled with ''
4847 ''::pg_catalog.\"char\" as attgenerated,
4848 FALSE as attisdropped,
4849 -- MZ doesn't support COLLATE so attcollation is filled with 0
4850 0::pg_catalog.oid as attcollation,
4851 -- Columns added because of the peeling. (Note that there are 2 of these here.)
4852 d.name as database_name,
4853 pg_type_all_databases.database_name as pg_type_database_name
4854FROM (
4855 -- pg_attribute catalogs columns on relations and indexes
4856 SELECT id, oid, schema_id, name, type FROM mz_catalog.mz_relations
4857 UNION ALL
4858 SELECT mz_indexes.id, mz_indexes.oid, mz_relations.schema_id, mz_indexes.name, 'index' AS type
4859 FROM mz_catalog.mz_indexes
4860 JOIN mz_catalog.mz_relations ON mz_indexes.on_id = mz_relations.id
4861) AS class_objects
4862JOIN mz_catalog.mz_columns ON class_objects.id = mz_columns.id
4863JOIN mz_internal.pg_type_all_databases ON pg_type_all_databases.oid = mz_columns.type_oid
4864JOIN mz_catalog.mz_schemas ON mz_schemas.id = class_objects.schema_id
4865LEFT JOIN mz_catalog.mz_databases d ON d.id = mz_schemas.database_id",
4866 access: vec![PUBLIC_SELECT],
4869 ontology: None,
4870 }
4871});
4872
4873pub const PG_ATTRIBUTE_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4874 name: "pg_attribute_all_databases_ind",
4875 schema: MZ_INTERNAL_SCHEMA,
4876 oid: oid::INDEX_PG_ATTRIBUTE_ALL_DATABASES_IND_OID,
4877 sql: "IN CLUSTER mz_catalog_server
4878ON mz_internal.pg_attribute_all_databases (
4879 attrelid, attname, atttypid, attlen, attnum, atttypmod, attnotnull, atthasdef, attidentity,
4880 attgenerated, attisdropped, attcollation, database_name, pg_type_database_name
4881)",
4882 is_retained_metrics_object: false,
4883};
4884
4885pub static PG_ATTRDEF_ALL_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
4889 name: "pg_attrdef_all_databases",
4890 schema: MZ_INTERNAL_SCHEMA,
4891 oid: oid::VIEW_PG_ATTRDEF_ALL_DATABASES_OID,
4892 desc: RelationDesc::builder()
4893 .with_column("oid", SqlScalarType::Oid.nullable(true))
4894 .with_column("adrelid", SqlScalarType::Oid.nullable(false))
4895 .with_column("adnum", SqlScalarType::Int64.nullable(false))
4896 .with_column("adbin", SqlScalarType::String.nullable(false))
4897 .with_column("adsrc", SqlScalarType::String.nullable(false))
4898 .finish(),
4899 column_comments: BTreeMap::new(),
4900 sql: "
4901SELECT
4902 NULL::pg_catalog.oid AS oid,
4903 mz_objects.oid AS adrelid,
4904 mz_columns.position::int8 AS adnum,
4905 mz_columns.default AS adbin,
4906 mz_columns.default AS adsrc
4907FROM mz_catalog.mz_columns
4908 JOIN mz_catalog.mz_objects ON mz_columns.id = mz_objects.id
4909WHERE default IS NOT NULL",
4910 access: vec![PUBLIC_SELECT],
4911 ontology: None,
4912});
4913
4914pub const PG_ATTRDEF_ALL_DATABASES_IND: BuiltinIndex = BuiltinIndex {
4915 name: "pg_attrdef_all_databases_ind",
4916 schema: MZ_INTERNAL_SCHEMA,
4917 oid: oid::INDEX_PG_ATTRDEF_ALL_DATABASES_IND_OID,
4918 sql: "IN CLUSTER mz_catalog_server
4919ON mz_internal.pg_attrdef_all_databases (oid, adrelid, adnum, adbin, adsrc)",
4920 is_retained_metrics_object: false,
4921};
4922
4923pub static MZ_COMPUTE_ERROR_COUNTS_RAW_UNIFIED: LazyLock<BuiltinSource> =
4924 LazyLock::new(|| BuiltinSource {
4925 name: "mz_compute_error_counts_raw_unified",
4930 schema: MZ_INTERNAL_SCHEMA,
4931 oid: oid::SOURCE_MZ_COMPUTE_ERROR_COUNTS_RAW_UNIFIED_OID,
4932 desc: RelationDesc::builder()
4933 .with_column("replica_id", SqlScalarType::String.nullable(false))
4934 .with_column("object_id", SqlScalarType::String.nullable(false))
4935 .with_column(
4936 "count",
4937 SqlScalarType::Numeric { max_scale: None }.nullable(false),
4938 )
4939 .finish(),
4940 data_source: IntrospectionType::ComputeErrorCounts.into(),
4941 column_comments: BTreeMap::new(),
4942 is_retained_metrics_object: false,
4943 access: vec![PUBLIC_SELECT],
4944 ontology: None,
4945 });
4946
4947pub static MZ_COMPUTE_HYDRATION_TIMES: LazyLock<BuiltinSource> = LazyLock::new(|| BuiltinSource {
4948 name: "mz_compute_hydration_times",
4949 schema: MZ_INTERNAL_SCHEMA,
4950 oid: oid::SOURCE_MZ_COMPUTE_HYDRATION_TIMES_OID,
4951 desc: RelationDesc::builder()
4952 .with_column("replica_id", SqlScalarType::String.nullable(false))
4953 .with_column("object_id", SqlScalarType::String.nullable(false))
4954 .with_column("time_ns", SqlScalarType::UInt64.nullable(true))
4955 .finish(),
4956 data_source: IntrospectionType::ComputeHydrationTimes.into(),
4957 column_comments: BTreeMap::new(),
4958 is_retained_metrics_object: true,
4959 access: vec![PUBLIC_SELECT],
4960 ontology: Some(Ontology {
4961 entity_name: "compute_hydration_time",
4962 description: "Time to hydrate compute objects",
4963 links: &const { [] },
4964 column_semantic_types: &const {
4965 [
4966 ("replica_id", SemanticType::ReplicaId),
4967 ("object_id", SemanticType::CatalogItemId),
4968 ]
4969 },
4970 }),
4971});
4972
4973pub static MZ_COMPUTE_HYDRATION_TIMES_IND: LazyLock<BuiltinIndex> =
4974 LazyLock::new(|| BuiltinIndex {
4975 name: "mz_compute_hydration_times_ind",
4976 schema: MZ_INTERNAL_SCHEMA,
4977 oid: oid::INDEX_MZ_COMPUTE_HYDRATION_TIMES_IND_OID,
4978 sql: "IN CLUSTER mz_catalog_server
4979 ON mz_internal.mz_compute_hydration_times (replica_id)",
4980 is_retained_metrics_object: true,
4981 });
4982
4983pub static MZ_OBJECT_ARRANGEMENT_SIZES_UNIFIED: LazyLock<BuiltinSource> = LazyLock::new(|| {
4984 BuiltinSource {
4985 name: "mz_object_arrangement_sizes",
4986 schema: MZ_INTERNAL_SCHEMA,
4987 oid: oid::SOURCE_MZ_OBJECT_ARRANGEMENT_SIZES_OID,
4988 desc: RelationDesc::builder()
4989 .with_column("replica_id", SqlScalarType::String.nullable(false))
4990 .with_column("object_id", SqlScalarType::String.nullable(false))
4991 .with_column("size", SqlScalarType::Int64.nullable(true))
4992 .finish(),
4993 data_source: IntrospectionType::ComputeObjectArrangementSizes.into(),
4994 column_comments: BTreeMap::from_iter([
4995 (
4996 "replica_id",
4997 "The ID of the cluster replica. Corresponds to `mz_cluster_replicas.id`.",
4998 ),
4999 (
5000 "object_id",
5001 "The ID of the compute object (index or materialized view). Corresponds to `mz_objects.id`.",
5002 ),
5003 (
5004 "size",
5005 "The total arrangement heap and batcher size in bytes for this object on this replica, \
5006 rounded to the nearest 10 MiB boundary to reduce per-byte churn in the differential \
5007 collection. Objects with less than 5 MiB of arrangements report a size of 0.",
5008 ),
5009 ]),
5010 is_retained_metrics_object: true,
5011 access: vec![PUBLIC_SELECT],
5012 ontology: None,
5013 }
5014});
5015
5016pub static MZ_OBJECT_ARRANGEMENT_SIZES_IND: LazyLock<BuiltinIndex> =
5017 LazyLock::new(|| BuiltinIndex {
5018 name: "mz_object_arrangement_sizes_ind",
5019 schema: MZ_INTERNAL_SCHEMA,
5020 oid: oid::INDEX_MZ_OBJECT_ARRANGEMENT_SIZES_IND_OID,
5021 sql: "IN CLUSTER mz_catalog_server
5022 ON mz_internal.mz_object_arrangement_sizes (replica_id)",
5023 is_retained_metrics_object: true,
5024 });
5025
5026pub static MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY: LazyLock<BuiltinTable> = LazyLock::new(|| {
5027 BuiltinTable {
5028 name: "mz_object_arrangement_size_history",
5029 schema: MZ_INTERNAL_SCHEMA,
5030 oid: oid::TABLE_MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_OID,
5031 desc: RelationDesc::builder()
5032 .with_column("replica_id", SqlScalarType::String.nullable(false))
5033 .with_column("object_id", SqlScalarType::String.nullable(false))
5034 .with_column("size", SqlScalarType::Int64.nullable(false))
5035 .with_column(
5036 "collection_timestamp",
5037 SqlScalarType::TimestampTz { precision: None }.nullable(false),
5038 )
5039 .with_column("hydration_complete", SqlScalarType::Bool.nullable(false))
5040 .finish(),
5041 column_comments: BTreeMap::from_iter([
5042 (
5043 "replica_id",
5044 "The ID of the cluster replica. Corresponds to `mz_cluster_replicas.id`.",
5045 ),
5046 (
5047 "object_id",
5048 "The ID of the compute object (index or materialized view). Corresponds to `mz_objects.id`.",
5049 ),
5050 (
5051 "size",
5052 "The total arrangement heap and batcher size in bytes for this object on this replica \
5053 at `collection_timestamp`, rounded to the nearest 10 MiB to reduce per-byte churn \
5054 in the underlying differential collection. Objects with less than 5 MiB of \
5055 arrangements are not recorded. May reflect a mid-build size if \
5056 `hydration_complete` is `false`.",
5057 ),
5058 (
5059 "collection_timestamp",
5060 "The timestamp when this snapshot was collected.",
5061 ),
5062 (
5063 "hydration_complete",
5064 "Whether the arrangement had finished its initial hydration on this replica when \
5065 the snapshot was collected. Filter for `true` to consider only stable, post-build \
5066 sizes.",
5067 ),
5068 ]),
5069 is_retained_metrics_object: true,
5070 access: vec![PUBLIC_SELECT],
5071 ontology: None,
5072 }
5073});
5074
5075pub static MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_OBJECT_IND: LazyLock<BuiltinIndex> =
5076 LazyLock::new(|| BuiltinIndex {
5077 name: "mz_object_arrangement_size_history_object_ind",
5078 schema: MZ_INTERNAL_SCHEMA,
5079 oid: oid::INDEX_MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_OBJECT_IND_OID,
5080 sql: "IN CLUSTER mz_catalog_server
5081 ON mz_internal.mz_object_arrangement_size_history (object_id)",
5082 is_retained_metrics_object: true,
5083 });
5084
5085pub static MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_TS_IND: LazyLock<BuiltinIndex> =
5086 LazyLock::new(|| BuiltinIndex {
5087 name: "mz_object_arrangement_size_history_ts_ind",
5088 schema: MZ_INTERNAL_SCHEMA,
5089 oid: oid::INDEX_MZ_OBJECT_ARRANGEMENT_SIZE_HISTORY_TS_IND_OID,
5090 sql: "IN CLUSTER mz_catalog_server
5091 ON mz_internal.mz_object_arrangement_size_history (collection_timestamp)",
5092 is_retained_metrics_object: true,
5093 });
5094
5095pub static MZ_OBJECT_HYDRATION_HISTORY: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
5102 name: "mz_object_hydration_history",
5103 schema: MZ_INTERNAL_SCHEMA,
5104 oid: oid::TABLE_MZ_OBJECT_HYDRATION_HISTORY_OID,
5105 desc: RelationDesc::builder()
5106 .with_column("object_id", SqlScalarType::String.nullable(false))
5107 .with_column("cluster_id", SqlScalarType::String.nullable(false))
5108 .with_column("replica_id", SqlScalarType::String.nullable(false))
5109 .with_column(
5110 "installed_at",
5111 SqlScalarType::TimestampTz { precision: None }.nullable(false),
5112 )
5113 .with_column(
5114 "started_at",
5115 SqlScalarType::TimestampTz { precision: None }.nullable(true),
5116 )
5117 .with_column(
5118 "hydrated_at",
5119 SqlScalarType::TimestampTz { precision: None }.nullable(true),
5120 )
5121 .with_column("status", SqlScalarType::String.nullable(false))
5122 .finish(),
5123 column_comments: BTreeMap::from_iter([
5124 (
5125 "object_id",
5126 "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.",
5127 ),
5128 ("cluster_id", "The ID of the object's cluster."),
5129 (
5130 "replica_id",
5131 "The ID of the cluster replica. May name a replica that no longer exists.",
5132 ),
5133 (
5134 "installed_at",
5135 "When the object's dataflow was installed on the replica.",
5136 ),
5137 (
5138 "started_at",
5139 "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.",
5140 ),
5141 ("hydrated_at", "When hydration finished."),
5142 (
5143 "status",
5144 "The terminal status. Currently always `hydrated`.",
5145 ),
5146 ]),
5147 is_retained_metrics_object: false,
5151 access: vec![PUBLIC_SELECT],
5152 ontology: Some(Ontology {
5153 entity_name: "object_hydration_event",
5154 description: "Completed hydration of an index or materialized view on a replica",
5155 links: &const {
5159 [
5160 OntologyLink {
5161 name: "hydration_of_dataflow",
5162 target: "object_global_id",
5163 properties: LinkProperties::fk_typed(
5164 "object_id",
5165 "global_id",
5166 Cardinality::ManyToOne,
5167 mz_repr::SemanticType::GlobalId,
5168 ),
5169 },
5170 OntologyLink {
5171 name: "hydrated_on_cluster",
5172 target: "cluster",
5173 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
5174 },
5175 OntologyLink {
5176 name: "hydrated_on_replica",
5177 target: "replica",
5178 properties: LinkProperties::fk_typed(
5179 "replica_id",
5180 "id",
5181 Cardinality::ManyToOne,
5182 mz_repr::SemanticType::ReplicaId,
5183 ),
5184 },
5185 ]
5186 },
5187 column_semantic_types: &[
5188 ("object_id", SemanticType::GlobalId),
5189 ("cluster_id", SemanticType::ClusterId),
5190 ("replica_id", SemanticType::ReplicaId),
5191 ],
5192 }),
5193});
5194
5195pub static MZ_REPLICA_HYDRATION_HISTORY: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
5202 name: "mz_replica_hydration_history",
5203 schema: MZ_INTERNAL_SCHEMA,
5204 oid: oid::TABLE_MZ_REPLICA_HYDRATION_HISTORY_OID,
5205 desc: RelationDesc::builder()
5206 .with_column("replica_id", SqlScalarType::String.nullable(false))
5207 .with_column("cluster_id", SqlScalarType::String.nullable(false))
5208 .with_column(
5209 "started_at",
5210 SqlScalarType::TimestampTz { precision: None }.nullable(false),
5211 )
5212 .with_column(
5213 "finished_at",
5214 SqlScalarType::TimestampTz { precision: None }.nullable(true),
5215 )
5216 .with_column("object_count", SqlScalarType::UInt64.nullable(false))
5217 .with_column("peak_memory_bytes", SqlScalarType::UInt64.nullable(true))
5218 .with_column("peak_disk_bytes", SqlScalarType::UInt64.nullable(true))
5219 .with_column("status", SqlScalarType::String.nullable(false))
5220 .finish(),
5221 column_comments: BTreeMap::from_iter([
5222 (
5223 "replica_id",
5224 "The ID of the cluster replica. May name a replica that no longer exists.",
5225 ),
5226 ("cluster_id", "The ID of the replica's cluster."),
5227 (
5228 "started_at",
5229 "The earliest maintained compute dataflow installation in the hydration episode.",
5230 ),
5231 (
5232 "finished_at",
5233 "The latest maintained compute dataflow hydration in the hydration episode.",
5234 ),
5235 (
5236 "object_count",
5237 "The number of maintained compute dataflows in the hydration episode.",
5238 ),
5239 (
5240 "peak_memory_bytes",
5241 "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.",
5242 ),
5243 (
5244 "peak_disk_bytes",
5245 "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.",
5246 ),
5247 (
5248 "status",
5249 "The hydration episode's status. Currently always `hydrated`.",
5250 ),
5251 ]),
5252 is_retained_metrics_object: false,
5256 access: vec![PUBLIC_SELECT],
5257 ontology: Some(Ontology {
5258 entity_name: "replica_hydration_episode",
5259 description: "Successful hydration episode on a cluster replica",
5260 links: &const {
5261 [
5262 OntologyLink {
5263 name: "hydrated_on_cluster",
5264 target: "cluster",
5265 properties: LinkProperties::ForeignKey {
5266 source_column: "cluster_id",
5267 target_column: "id",
5268 cardinality: Cardinality::ManyToOne,
5269 source_id_type: None,
5270 requires_mapping: None,
5271 nullable: false,
5272 note: Some(
5273 "Hydration samples can outlive their cluster, so this reference may not resolve.",
5274 ),
5275 extra_key_columns: None,
5276 },
5277 },
5278 OntologyLink {
5279 name: "hydrated_on_replica",
5280 target: "replica",
5281 properties: LinkProperties::ForeignKey {
5282 source_column: "replica_id",
5283 target_column: "id",
5284 cardinality: Cardinality::ManyToOne,
5285 source_id_type: Some(mz_repr::SemanticType::ReplicaId),
5286 requires_mapping: None,
5287 nullable: false,
5288 note: Some(
5289 "Hydration samples can outlive their replica, so this reference may not resolve.",
5290 ),
5291 extra_key_columns: None,
5292 },
5293 },
5294 ]
5295 },
5296 column_semantic_types: &[
5297 ("replica_id", SemanticType::ReplicaId),
5298 ("cluster_id", SemanticType::ClusterId),
5299 ],
5300 }),
5301});
5302
5303pub static MZ_COMPUTE_HYDRATION_STATUSES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5304 name: "mz_compute_hydration_statuses",
5305 schema: MZ_INTERNAL_SCHEMA,
5306 oid: oid::SOURCE_MZ_COMPUTE_HYDRATION_STATUSES_OID,
5307 desc: RelationDesc::builder()
5308 .with_column("object_id", SqlScalarType::String.nullable(false))
5309 .with_column("replica_id", SqlScalarType::String.nullable(false))
5310 .with_column("hydrated", SqlScalarType::Bool.nullable(false))
5311 .with_column("hydration_time", SqlScalarType::Interval.nullable(true))
5312 .finish(),
5313 column_comments: BTreeMap::from_iter([
5314 (
5315 "object_id",
5316 "The ID of a compute object. Corresponds to `mz_catalog.mz_indexes.id` or `mz_catalog.mz_materialized_views.id`",
5317 ),
5318 ("replica_id", "The ID of a cluster replica."),
5319 (
5320 "hydrated",
5321 "Whether the compute object is hydrated on the replica.",
5322 ),
5323 (
5324 "hydration_time",
5325 "The amount of time it took for the replica to hydrate the compute object.",
5326 ),
5327 ]),
5328 sql: "
5329WITH
5330 dataflows AS (
5331 SELECT
5332 object_id,
5333 replica_id,
5334 time_ns IS NOT NULL AS hydrated,
5335 ((time_ns / 1000) || 'microseconds')::interval AS hydration_time
5336 FROM mz_internal.mz_compute_hydration_times
5337 ),
5338 -- MVs that have advanced to the empty frontier don't have a dataflow installed anymore and
5339 -- therefore don't show up in `mz_compute_hydration_times`. We still want to show them here to
5340 -- avoid surprises for people joining `mz_materialized_views` against this relation (like the
5341 -- blue-green readiness query does), so we include them as 'hydrated'.
5342 complete_mvs AS (
5343 SELECT
5344 mv.id,
5345 f.replica_id,
5346 true AS hydrated,
5347 NULL::interval AS hydration_time
5348 FROM mz_materialized_views mv
5349 JOIN mz_catalog.mz_cluster_replica_frontiers f ON f.object_id = mv.id
5350 WHERE f.write_frontier IS NULL
5351 )
5352SELECT * FROM dataflows
5353UNION ALL
5354SELECT * FROM complete_mvs",
5355 access: vec![PUBLIC_SELECT],
5356 ontology: Some(Ontology {
5357 entity_name: "compute_hydration_status_view",
5358 description: "Computed hydration status per compute object",
5359 links: &const { [] },
5360 column_semantic_types: &const {
5361 [
5362 ("object_id", SemanticType::GlobalId),
5363 ("replica_id", SemanticType::ReplicaId),
5364 ]
5365 },
5366 }),
5367});
5368
5369pub static MZ_COMPUTE_OPERATOR_HYDRATION_STATUSES: LazyLock<BuiltinSource> = LazyLock::new(|| {
5370 BuiltinSource {
5371 name: "mz_compute_operator_hydration_statuses",
5372 schema: MZ_INTERNAL_SCHEMA,
5373 oid: oid::SOURCE_MZ_COMPUTE_OPERATOR_HYDRATION_STATUSES_OID,
5374 desc: RelationDesc::builder()
5375 .with_column("replica_id", SqlScalarType::String.nullable(false))
5376 .with_column("object_id", SqlScalarType::String.nullable(false))
5377 .with_column(
5378 "physical_plan_node_id",
5379 SqlScalarType::UInt64.nullable(false),
5380 )
5381 .with_column("hydrated", SqlScalarType::Bool.nullable(false))
5382 .with_key(vec![0, 1, 2])
5383 .finish(),
5384 data_source: IntrospectionType::ComputeOperatorHydrationStatus.into(),
5385 column_comments: BTreeMap::from_iter([
5386 ("replica_id", "The ID of a cluster replica."),
5387 (
5388 "object_id",
5389 "The ID of a compute object. Corresponds to `mz_catalog.mz_indexes.id` or `mz_catalog.mz_materialized_views.id`.",
5390 ),
5391 (
5392 "physical_plan_node_id",
5393 "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)`.",
5394 ),
5395 ("hydrated", "Whether the node is hydrated on the replica."),
5396 ]),
5397 is_retained_metrics_object: false,
5398 access: vec![PUBLIC_SELECT],
5399 ontology: Some(Ontology {
5400 entity_name: "compute_hydration_status",
5401 description: "Hydration status per compute operator",
5402 links: &const { [] },
5403 column_semantic_types: &const {
5404 [
5405 ("replica_id", SemanticType::ReplicaId),
5406 ("object_id", SemanticType::CatalogItemId),
5407 ]
5408 },
5409 }),
5410 }
5411});
5412
5413pub static MZ_CLUSTER_REPLICA_UTILIZATION: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5414 name: "mz_cluster_replica_utilization",
5415 schema: MZ_INTERNAL_SCHEMA,
5416 oid: oid::VIEW_MZ_CLUSTER_REPLICA_UTILIZATION_OID,
5417 desc: RelationDesc::builder()
5418 .with_column("replica_id", SqlScalarType::String.nullable(false))
5419 .with_column("process_id", SqlScalarType::UInt64.nullable(false))
5420 .with_column("cpu_percent", SqlScalarType::Float64.nullable(true))
5421 .with_column("memory_percent", SqlScalarType::Float64.nullable(true))
5422 .with_column("disk_percent", SqlScalarType::Float64.nullable(true))
5423 .with_column("heap_percent", SqlScalarType::Float64.nullable(true))
5424 .finish(),
5425 column_comments: BTreeMap::from_iter([
5426 ("replica_id", "The ID of a cluster replica."),
5427 ("process_id", "The ID of a process within the replica."),
5428 (
5429 "cpu_percent",
5430 "Approximate CPU usage, in percent of the total allocation.",
5431 ),
5432 (
5433 "memory_percent",
5434 "Approximate RAM usage, in percent of the total allocation.",
5435 ),
5436 (
5437 "disk_percent",
5438 "Approximate disk usage, in percent of the total allocation.",
5439 ),
5440 (
5441 "heap_percent",
5442 "Approximate heap (RAM + swap) usage, in percent of the total allocation.",
5443 ),
5444 ]),
5445 sql: "
5446SELECT
5447 r.id AS replica_id,
5448 m.process_id,
5449 m.cpu_nano_cores::float8 / NULLIF(s.cpu_nano_cores, 0) * 100 AS cpu_percent,
5450 m.memory_bytes::float8 / NULLIF(s.memory_bytes, 0) * 100 AS memory_percent,
5451 m.disk_bytes::float8 / NULLIF(s.disk_bytes, 0) * 100 AS disk_percent,
5452 m.heap_bytes::float8 / NULLIF(m.heap_limit, 0) * 100 AS heap_percent
5453FROM
5454 mz_catalog.mz_cluster_replicas AS r
5455 JOIN mz_catalog.mz_cluster_replica_sizes AS s ON r.size = s.size
5456 JOIN mz_internal.mz_cluster_replica_metrics AS m ON m.replica_id = r.id",
5457 access: vec![PUBLIC_SELECT],
5458 ontology: Some(Ontology {
5459 entity_name: "replica_utilization",
5460 description: "Computed utilization metrics per replica",
5461 links: &const {
5462 [OntologyLink {
5463 name: "utilization_of_replica",
5464 target: "replica",
5465 properties: LinkProperties::fk_typed(
5466 "replica_id",
5467 "id",
5468 Cardinality::OneToOne,
5469 mz_repr::SemanticType::CatalogItemId,
5470 ),
5471 }]
5472 },
5473 column_semantic_types: &[("replica_id", SemanticType::ReplicaId)],
5474 }),
5475});
5476
5477pub static MZ_CLUSTER_REPLICA_UTILIZATION_HISTORY: LazyLock<BuiltinView> =
5478 LazyLock::new(|| BuiltinView {
5479 name: "mz_cluster_replica_utilization_history",
5480 schema: MZ_INTERNAL_SCHEMA,
5481 oid: oid::VIEW_MZ_CLUSTER_REPLICA_UTILIZATION_HISTORY_OID,
5482 desc: RelationDesc::builder()
5483 .with_column("replica_id", SqlScalarType::String.nullable(false))
5484 .with_column("process_id", SqlScalarType::UInt64.nullable(false))
5485 .with_column("cpu_percent", SqlScalarType::Float64.nullable(true))
5486 .with_column("memory_percent", SqlScalarType::Float64.nullable(true))
5487 .with_column("disk_percent", SqlScalarType::Float64.nullable(true))
5488 .with_column("heap_percent", SqlScalarType::Float64.nullable(true))
5489 .with_column(
5490 "occurred_at",
5491 SqlScalarType::TimestampTz { precision: None }.nullable(false),
5492 )
5493 .finish(),
5494 column_comments: BTreeMap::from_iter([
5495 ("replica_id", "The ID of a cluster replica."),
5496 ("process_id", "The ID of a process within the replica."),
5497 (
5498 "cpu_percent",
5499 "Approximate CPU usage, in percent of the total allocation.",
5500 ),
5501 (
5502 "memory_percent",
5503 "Approximate RAM usage, in percent of the total allocation.",
5504 ),
5505 (
5506 "disk_percent",
5507 "Approximate disk usage, in percent of the total allocation.",
5508 ),
5509 (
5510 "heap_percent",
5511 "Approximate heap (RAM + swap) usage, in percent of the total allocation.",
5512 ),
5513 (
5514 "occurred_at",
5515 "Wall-clock timestamp at which the event occurred.",
5516 ),
5517 ]),
5518 sql: "
5519SELECT
5520 r.id AS replica_id,
5521 m.process_id,
5522 m.cpu_nano_cores::float8 / NULLIF(s.cpu_nano_cores, 0) * 100 AS cpu_percent,
5523 m.memory_bytes::float8 / NULLIF(s.memory_bytes, 0) * 100 AS memory_percent,
5524 m.disk_bytes::float8 / NULLIF(s.disk_bytes, 0) * 100 AS disk_percent,
5525 m.heap_bytes::float8 / NULLIF(m.heap_limit, 0) * 100 AS heap_percent,
5526 m.occurred_at
5527FROM
5528 mz_catalog.mz_cluster_replicas AS r
5529 JOIN mz_catalog.mz_cluster_replica_sizes AS s ON r.size = s.size
5530 JOIN mz_internal.mz_cluster_replica_metrics_history AS m ON m.replica_id = r.id",
5531 access: vec![PUBLIC_SELECT],
5532 ontology: None,
5533 });
5534
5535pub static MZ_INDEX_ADVICE: LazyLock<BuiltinView> = LazyLock::new(|| {
5536 BuiltinView {
5537 name: "mz_index_advice",
5538 schema: MZ_INTERNAL_SCHEMA,
5539 oid: oid::VIEW_MZ_INDEX_ADVICE_OID,
5540 desc: RelationDesc::builder()
5541 .with_column("object_id", SqlScalarType::String.nullable(true))
5542 .with_column("hint", SqlScalarType::String.nullable(false))
5543 .with_column("details", SqlScalarType::String.nullable(false))
5544 .with_column("referenced_object_ids", SqlScalarType::List { element_type: Box::new(SqlScalarType::String), custom_id: None }.nullable(true))
5545 .finish(),
5546 column_comments: BTreeMap::from_iter([
5547 ("object_id", "The ID of the object. Corresponds to mz_objects.id."),
5548 ("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."),
5549 ("details", "Additional details on why the `hint` was proposed based on the dependencies of the object."),
5550 ("referenced_object_ids", "The IDs of objects referenced by `details`. Corresponds to mz_objects.id."),
5551 ]),
5552 sql: "
5553-- To avoid confusion with sources and sinks in the materialize sense,
5554-- the following uses the terms leafs (instead of sinks) and roots (instead of sources)
5555-- when referring to the object dependency graph.
5556--
5557-- The basic idea is to walk up the dependency graph to propagate the transitive dependencies
5558-- of maintained objected upwards. The leaves of the dependency graph are maintained objects
5559-- that are not depended on by other maintained objects and have a justification why they must
5560-- be maintained (e.g. a materialized view that is depended on by a sink).
5561-- Starting from these leaves, the dependencies are propagated upwards towards the roots according
5562-- to the object dependencies. Whenever there is a node that is being depended on by multiple
5563-- downstream objects, that node is marked to be converted into a maintained object and this
5564-- node is then propagated further up. Once completed, the list of objects that are marked as
5565-- maintained is checked against all objects to generate appropriate recommendations.
5566--
5567-- Note that the recommendations only incorporate dependencies between objects.
5568-- This can lead to bad recommendations, e.g. filters can no longer be pushed into (or close to)
5569-- a sink if an index is added in between the sink and the filter. For very selective filters,
5570-- this can lead to redundant work: the index is computing stuff only to discarded by the selective
5571-- filter later on. But these kind of aspects cannot be understood by merely looking at the
5572-- dependencies.
5573WITH MUTUALLY RECURSIVE
5574 -- for all objects, understand if they have an index on them and on which cluster they are running
5575 -- this avoids having different cases for views with an index and materialized views later on
5576 objects(id text, type text, cluster_id text, indexes text list) AS (
5577 -- views and materialized views without an index
5578 SELECT
5579 o.id,
5580 o.type,
5581 o.cluster_id,
5582 '{}'::text list AS indexes
5583 FROM mz_catalog.mz_objects o
5584 WHERE o.id LIKE 'u%' AND o.type IN ('materialized-view', 'view') AND NOT EXISTS (
5585 SELECT FROM mz_internal.mz_object_dependencies d
5586 JOIN mz_catalog.mz_objects AS i
5587 ON (i.id = d.object_id AND i.type = 'index')
5588 WHERE (o.id = d.referenced_object_id)
5589 )
5590
5591 UNION ALL
5592
5593 -- views and materialized views with an index
5594 SELECT
5595 o.id,
5596 o.type,
5597 -- o.cluster_id is always NULL for views, so use the cluster of the index instead
5598 COALESCE(o.cluster_id, i.cluster_id) AS cluster_id,
5599 list_agg(i.id) AS indexes
5600 FROM mz_catalog.mz_objects o
5601 JOIN mz_internal.mz_object_dependencies AS d
5602 ON (o.id = d.referenced_object_id)
5603 JOIN mz_catalog.mz_objects AS i
5604 ON (i.id = d.object_id AND i.type = 'index')
5605 WHERE o.id LIKE 'u%' AND o.type IN ('materialized-view', 'view', 'source')
5606 GROUP BY o.id, o.type, o.cluster_id, i.cluster_id
5607 ),
5608
5609 -- maintained objects that are at the leafs of the dependency graph with respect to a specific cluster
5610 maintained_leafs(id text, justification text) AS (
5611 -- materialized views that are connected to a sink
5612 SELECT
5613 m.id,
5614 s.id AS justification
5615 FROM objects AS m
5616 JOIN mz_internal.mz_object_dependencies AS d
5617 ON (m.id = d.referenced_object_id)
5618 JOIN mz_catalog.mz_objects AS s
5619 ON (s.id = d.object_id AND s.type = 'sink')
5620 WHERE m.type = 'materialized-view'
5621
5622 UNION ALL
5623
5624 -- (materialized) views with an index that are not transitively depend on by maintained objects on the same cluster
5625 SELECT
5626 v.id,
5627 unnest(v.indexes) AS justification
5628 FROM objects AS v
5629 WHERE v.type IN ('view', 'materialized-view', 'source') AND NOT EXISTS (
5630 SELECT FROM mz_internal.mz_object_transitive_dependencies AS d
5631 INNER JOIN mz_catalog.mz_objects AS child
5632 ON (d.object_id = child.id)
5633 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]
5634 )
5635 ),
5636
5637 -- this is just a helper cte to union multiple lists as part of an aggregation, which is not directly possible in SQL
5638 agg_maintained_children(id text, maintained_children text list) AS (
5639 SELECT
5640 parent_id AS id,
5641 list_agg(maintained_child) AS maintained_leafs
5642 FROM (
5643 SELECT DISTINCT
5644 d.referenced_object_id AS parent_id,
5645 -- it's not possible to union lists in an aggregation, so we have to unnest the list first
5646 unnest(child.maintained_children) AS maintained_child
5647 FROM propagate_dependencies AS child
5648 INNER JOIN mz_internal.mz_object_dependencies AS d
5649 ON (child.id = d.object_id)
5650 )
5651 GROUP BY parent_id
5652 ),
5653
5654 -- propagate dependencies of maintained objects from the leafs to the roots of the dependency graph and
5655 -- record a justification when an object should be maintained, e.g. when it is depended on by more than one maintained object
5656 -- 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
5657 propagate_dependencies(id text, maintained_children text list, justification text list) AS (
5658 -- base case: start with the leafs
5659 SELECT DISTINCT
5660 id,
5661 LIST[id] AS maintained_children,
5662 list_agg(justification) AS justification
5663 FROM maintained_leafs
5664 GROUP BY id
5665
5666 UNION
5667
5668 -- recursive case: if there is a child with the same dependencies as the parent,
5669 -- the parent is only reused by a single child
5670 SELECT
5671 parent.id,
5672 child.maintained_children,
5673 NULL::text list AS justification
5674 FROM agg_maintained_children AS parent
5675 INNER JOIN mz_internal.mz_object_dependencies AS d
5676 ON (parent.id = d.referenced_object_id)
5677 INNER JOIN propagate_dependencies AS child
5678 ON (d.object_id = child.id)
5679 WHERE parent.maintained_children = child.maintained_children
5680
5681 UNION
5682
5683 -- recursive case: if there is NO child with the same dependencies as the parent,
5684 -- different children are reusing the parent so maintaining the object is justified by itself
5685 SELECT DISTINCT
5686 parent.id,
5687 LIST[parent.id] AS maintained_children,
5688 parent.maintained_children AS justification
5689 FROM agg_maintained_children AS parent
5690 WHERE NOT EXISTS (
5691 SELECT FROM mz_internal.mz_object_dependencies AS d
5692 INNER JOIN propagate_dependencies AS child
5693 ON (d.object_id = child.id AND d.referenced_object_id = parent.id)
5694 WHERE parent.maintained_children = child.maintained_children
5695 )
5696 ),
5697
5698 objects_with_justification(id text, type text, cluster_id text, maintained_children text list, justification text list, indexes text list) AS (
5699 SELECT
5700 p.id,
5701 o.type,
5702 o.cluster_id,
5703 p.maintained_children,
5704 p.justification,
5705 o.indexes
5706 FROM propagate_dependencies p
5707 JOIN objects AS o
5708 ON (p.id = o.id)
5709 ),
5710
5711 hints(id text, hint text, details text, justification text list) AS (
5712 -- materialized views that are not required
5713 SELECT
5714 id,
5715 'convert to a view' AS hint,
5716 'no dependencies from sinks nor from objects on different clusters' AS details,
5717 justification
5718 FROM objects_with_justification
5719 WHERE type = 'materialized-view' AND justification IS NULL
5720
5721 UNION ALL
5722
5723 -- materialized views that are required because a sink or a maintained object from a different cluster depends on them
5724 SELECT
5725 id,
5726 'keep' AS hint,
5727 'dependencies from sinks or objects on different clusters: ' AS details,
5728 justification
5729 FROM objects_with_justification AS m
5730 WHERE type = 'materialized-view' AND justification IS NOT NULL AND EXISTS (
5731 SELECT FROM unnest(justification) AS dependency
5732 JOIN mz_catalog.mz_objects s ON (s.type = 'sink' AND s.id = dependency)
5733
5734 UNION ALL
5735
5736 SELECT FROM unnest(justification) AS dependency
5737 JOIN mz_catalog.mz_objects AS d ON (d.id = dependency)
5738 WHERE d.cluster_id != m.cluster_id
5739 )
5740
5741 UNION ALL
5742
5743 -- 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
5744 SELECT
5745 id,
5746 'convert to a view with an index' AS hint,
5747 'no dependencies from sinks nor from objects on different clusters, but maintained dependencies on the same cluster: ' AS details,
5748 justification
5749 FROM objects_with_justification AS m
5750 WHERE type = 'materialized-view' AND justification IS NOT NULL AND NOT EXISTS (
5751 SELECT FROM unnest(justification) AS dependency
5752 JOIN mz_catalog.mz_objects s ON (s.type = 'sink' AND s.id = dependency)
5753
5754 UNION ALL
5755
5756 SELECT FROM unnest(justification) AS dependency
5757 JOIN mz_catalog.mz_objects AS d ON (d.id = dependency)
5758 WHERE d.cluster_id != m.cluster_id
5759 )
5760
5761 UNION ALL
5762
5763 -- views that have indexes on different clusters should be a materialized view
5764 SELECT
5765 o.id,
5766 'convert to materialized view' AS hint,
5767 'dependencies on multiple clusters: ' AS details,
5768 o.justification
5769 FROM objects_with_justification o,
5770 LATERAL unnest(o.justification) j
5771 LEFT JOIN mz_catalog.mz_objects AS m
5772 ON (m.id = j AND m.type IN ('index', 'materialized-view'))
5773 WHERE o.type = 'view' AND o.justification IS NOT NULL
5774 GROUP BY o.id, o.justification
5775 HAVING count(DISTINCT m.cluster_id) >= 2
5776
5777 UNION ALL
5778
5779 -- views without an index that should be maintained
5780 SELECT
5781 id,
5782 'add index' AS hint,
5783 'multiple downstream dependencies: ' AS details,
5784 justification
5785 FROM objects_with_justification
5786 WHERE type = 'view' AND justification IS NOT NULL AND indexes = '{}'::text list
5787
5788 UNION ALL
5789
5790 -- index inside the dependency graph (not a leaf)
5791 SELECT
5792 unnest(indexes) AS id,
5793 'drop unless queried directly' AS hint,
5794 'fewer than two downstream dependencies: ' AS details,
5795 maintained_children AS justification
5796 FROM objects_with_justification
5797 WHERE type = 'view' AND NOT indexes = '{}'::text list AND justification IS NULL
5798
5799 UNION ALL
5800
5801 -- index on a leaf of the dependency graph
5802 SELECT
5803 unnest(indexes) AS id,
5804 'drop unless queried directly' AS hint,
5805 'associated object does not have any dependencies (maintained or not maintained)' AS details,
5806 NULL::text list AS justification
5807 FROM objects_with_justification
5808 -- indexes can only be part of justification for leaf nodes
5809 WHERE type IN ('view', 'materialized-view') AND NOT indexes = '{}'::text list AND justification @> indexes
5810
5811 UNION ALL
5812
5813 -- index on a source
5814 SELECT
5815 unnest(indexes) AS id,
5816 'drop unless queried directly' AS hint,
5817 'sources do not transform data and can expose data directly' AS details,
5818 NULL::text list AS justification
5819 FROM objects_with_justification
5820 -- indexes can only be part of justification for leaf nodes
5821 WHERE type = 'source' AND NOT indexes = '{}'::text list
5822
5823 UNION ALL
5824
5825 -- indexes on views inside the dependency graph
5826 SELECT
5827 unnest(indexes) AS id,
5828 'keep' AS hint,
5829 'multiple downstream dependencies: ' AS details,
5830 justification
5831 FROM objects_with_justification
5832 -- indexes can only be part of justification for leaf nodes
5833 WHERE type = 'view' AND justification IS NOT NULL AND NOT indexes = '{}'::text list AND NOT justification @> indexes
5834 ),
5835
5836 hints_resolved_ids(id text, hint text, details text, justification text list) AS (
5837 SELECT
5838 h.id,
5839 h.hint,
5840 h.details || list_agg(o.name)::text AS details,
5841 h.justification
5842 FROM hints AS h,
5843 LATERAL unnest(h.justification) j
5844 JOIN mz_catalog.mz_objects AS o
5845 ON (o.id = j)
5846 GROUP BY h.id, h.hint, h.details, h.justification
5847
5848 UNION ALL
5849
5850 SELECT
5851 id,
5852 hint,
5853 details,
5854 justification
5855 FROM hints
5856 WHERE justification IS NULL
5857 )
5858
5859SELECT
5860 h.id AS object_id,
5861 h.hint AS hint,
5862 h.details,
5863 h.justification AS referenced_object_ids
5864FROM hints_resolved_ids AS h",
5865 access: vec![PUBLIC_SELECT],
5866 ontology: None,
5867 }
5868});
5869
5870pub static PG_AUTHID_CORE: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5873 name: "pg_authid_core",
5874 schema: MZ_INTERNAL_SCHEMA,
5875 oid: oid::VIEW_PG_AUTHID_CORE_OID,
5876 desc: RelationDesc::builder()
5877 .with_column("oid", SqlScalarType::Oid.nullable(false))
5878 .with_column("rolname", SqlScalarType::String.nullable(false))
5879 .with_column("rolsuper", SqlScalarType::Bool.nullable(true))
5880 .with_column("rolinherit", SqlScalarType::Bool.nullable(false))
5881 .with_column("rolcanlogin", SqlScalarType::Bool.nullable(false))
5882 .with_column("rolreplication", SqlScalarType::Bool.nullable(false))
5883 .with_column("rolbypassrls", SqlScalarType::Bool.nullable(false))
5884 .with_column("rolconnlimit", SqlScalarType::Int32.nullable(false))
5885 .with_column("rolpassword", SqlScalarType::String.nullable(true))
5886 .with_column(
5887 "rolvaliduntil",
5888 SqlScalarType::TimestampTz { precision: None }.nullable(true),
5889 )
5890 .finish(),
5891 column_comments: BTreeMap::new(),
5892 sql: r#"
5893SELECT
5894 r.oid AS oid,
5895 r.name AS rolname,
5896 rolsuper,
5897 inherit AS rolinherit,
5898 COALESCE(r.rolcanlogin, false) AS rolcanlogin,
5899 -- MZ doesn't support replication in the same way Postgres does
5900 false AS rolreplication,
5901 -- MZ doesn't how row level security
5902 false AS rolbypassrls,
5903 -- MZ doesn't have a connection limit
5904 -1 AS rolconnlimit,
5905 a.password_hash AS rolpassword,
5906 NULL::pg_catalog.timestamptz AS rolvaliduntil
5907FROM mz_catalog.mz_roles r
5908LEFT JOIN mz_catalog.mz_role_auth a ON r.oid = a.role_oid"#,
5909 access: vec![rbac::owner_privilege(ObjectType::Table, MZ_SYSTEM_ROLE_ID)],
5910 ontology: None,
5911});
5912
5913pub const PG_AUTHID_CORE_IND: BuiltinIndex = BuiltinIndex {
5914 name: "pg_authid_core_ind",
5915 schema: MZ_INTERNAL_SCHEMA,
5916 oid: oid::INDEX_PG_AUTHID_CORE_IND_OID,
5917 sql: "IN CLUSTER mz_catalog_server
5918ON mz_internal.pg_authid_core (rolname)",
5919 is_retained_metrics_object: false,
5920};
5921
5922pub static MZ_SHOW_ALL_OBJECTS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
5923 name: "mz_show_all_objects",
5924 schema: MZ_INTERNAL_SCHEMA,
5925 oid: oid::VIEW_MZ_SHOW_ALL_OBJECTS_OID,
5926 desc: RelationDesc::builder()
5927 .with_column("schema_id", SqlScalarType::String.nullable(false))
5928 .with_column("name", SqlScalarType::String.nullable(false))
5929 .with_column("type", SqlScalarType::String.nullable(false))
5930 .with_column("comment", SqlScalarType::String.nullable(false))
5931 .finish(),
5932 column_comments: BTreeMap::new(),
5933 sql: "WITH comments AS (
5934 SELECT id, object_type, comment
5935 FROM mz_internal.mz_comments
5936 WHERE object_sub_id IS NULL
5937 )
5938 SELECT schema_id, name, type, COALESCE(comment, '') AS comment
5939 FROM mz_catalog.mz_objects AS objs
5940 LEFT JOIN comments ON objs.id = comments.id AND comments.object_type = objs.type",
5941 access: vec![PUBLIC_SELECT],
5942 ontology: None,
5943});
5944
5945pub static MZ_SHOW_CLUSTERS: LazyLock<BuiltinView> = LazyLock::new(|| {
5946 BuiltinView {
5947 name: "mz_show_clusters",
5948 schema: MZ_INTERNAL_SCHEMA,
5949 oid: oid::VIEW_MZ_SHOW_CLUSTERS_OID,
5950 desc: RelationDesc::builder()
5951 .with_column("name", SqlScalarType::String.nullable(false))
5952 .with_column("replicas", SqlScalarType::String.nullable(true))
5953 .with_column("activity", SqlScalarType::String.nullable(true))
5956 .with_column("comment", SqlScalarType::String.nullable(false))
5957 .finish(),
5958 column_comments: BTreeMap::new(),
5959 sql: "
5969 WITH clusters AS (
5970 SELECT
5971 mc.id,
5972 mc.name,
5973 pg_catalog.string_agg(mcr.name || ' (' || mcr.size || ')', ', ' ORDER BY mcr.name) AS replicas
5974 FROM mz_catalog.mz_clusters mc
5975 LEFT JOIN mz_catalog.mz_cluster_replicas mcr
5976 ON mc.id = mcr.cluster_id
5977 GROUP BY mc.id, mc.name
5978 ),
5979 comments AS (
5980 SELECT id, comment
5981 FROM mz_internal.mz_comments
5982 WHERE object_type = 'cluster' AND object_sub_id IS NULL
5983 ),
5984 reconfigurations AS (
5985 SELECT
5986 cluster_id,
5987 'reconfiguring ' || NULLIF(array_to_string(ARRAY[
5988 'size to ' || (changes->>'size'),
5989 'replication factor to ' || (changes->>'replication_factor'),
5990 CASE WHEN changes->'availability_zones' IS NOT NULL THEN 'availability zones' END,
5991 CASE WHEN changes->'logging' IS NOT NULL THEN 'introspection settings' END,
5992 CASE WHEN changes->'arrangement_compression' IS NOT NULL THEN 'arrangement compression' END
5993 ], ', '), '') AS summary
5994 FROM mz_internal.mz_cluster_reconfigurations
5995 WHERE status = 'in-progress'
5996 )
5997 SELECT
5998 name,
5999 replicas,
6000 CASE
6001 WHEN recon.summary IS NOT NULL AND scaling.state IS NOT NULL
6002 THEN recon.summary
6003 || '; hydration burst at ' || (scaling.state->'burst'->>'burst_size')
6004 WHEN recon.summary IS NOT NULL
6005 THEN recon.summary
6006 WHEN scaling.state IS NOT NULL
6007 THEN 'hydration burst at ' || (scaling.state->'burst'->>'burst_size')
6008 ELSE NULL
6009 END AS activity,
6010 COALESCE(comment, '') as comment
6011 FROM clusters
6012 LEFT JOIN comments ON clusters.id = comments.id
6013 LEFT JOIN reconfigurations recon
6014 ON clusters.id = recon.cluster_id
6015 LEFT JOIN mz_internal.mz_cluster_auto_scaling_strategies scaling ON clusters.id = scaling.cluster_id",
6016 access: vec![PUBLIC_SELECT],
6017 ontology: None,
6018}
6019});
6020
6021pub static MZ_SHOW_SECRETS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6022 name: "mz_show_secrets",
6023 schema: MZ_INTERNAL_SCHEMA,
6024 oid: oid::VIEW_MZ_SHOW_SECRETS_OID,
6025 desc: RelationDesc::builder()
6026 .with_column("schema_id", SqlScalarType::String.nullable(false))
6027 .with_column("name", SqlScalarType::String.nullable(false))
6028 .with_column("comment", SqlScalarType::String.nullable(false))
6029 .finish(),
6030 column_comments: BTreeMap::new(),
6031 sql: "WITH comments AS (
6032 SELECT id, comment
6033 FROM mz_internal.mz_comments
6034 WHERE object_type = 'secret' AND object_sub_id IS NULL
6035 )
6036 SELECT schema_id, name, COALESCE(comment, '') as comment
6037 FROM mz_catalog.mz_secrets secrets
6038 LEFT JOIN comments ON secrets.id = comments.id",
6039 access: vec![PUBLIC_SELECT],
6040 ontology: None,
6041});
6042
6043pub static MZ_SHOW_COLUMNS: LazyLock<BuiltinView> = LazyLock::new(|| {
6044 BuiltinView {
6045 name: "mz_show_columns",
6046 schema: MZ_INTERNAL_SCHEMA,
6047 oid: oid::VIEW_MZ_SHOW_COLUMNS_OID,
6048 desc: RelationDesc::builder()
6049 .with_column("id", SqlScalarType::String.nullable(false))
6050 .with_column("name", SqlScalarType::String.nullable(false))
6051 .with_column("nullable", SqlScalarType::Bool.nullable(false))
6052 .with_column("type", SqlScalarType::String.nullable(false))
6053 .with_column("position", SqlScalarType::UInt64.nullable(false))
6054 .with_column("comment", SqlScalarType::String.nullable(false))
6055 .finish(),
6056 column_comments: BTreeMap::new(),
6057 sql: "
6063 SELECT columns.id, columns.name, columns.nullable, columns.type, columns.position, COALESCE(comment, '') as comment
6064 FROM mz_catalog.mz_columns columns
6065 LEFT JOIN mz_catalog.mz_objects obj ON obj.id = columns.id
6066 LEFT JOIN mz_internal.mz_comments comments
6067 ON columns.id = comments.id
6068 AND columns.position = comments.object_sub_id
6069 AND comments.object_type = obj.type",
6070 access: vec![PUBLIC_SELECT],
6071 ontology: None,
6072}
6073});
6074
6075pub static MZ_SHOW_DATABASES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6076 name: "mz_show_databases",
6077 schema: MZ_INTERNAL_SCHEMA,
6078 oid: oid::VIEW_MZ_SHOW_DATABASES_OID,
6079 desc: RelationDesc::builder()
6080 .with_column("name", SqlScalarType::String.nullable(false))
6081 .with_column("comment", SqlScalarType::String.nullable(false))
6082 .finish(),
6083 column_comments: BTreeMap::new(),
6084 sql: "WITH comments AS (
6085 SELECT id, comment
6086 FROM mz_internal.mz_comments
6087 WHERE object_type = 'database' AND object_sub_id IS NULL
6088 )
6089 SELECT name, COALESCE(comment, '') as comment
6090 FROM mz_catalog.mz_databases databases
6091 LEFT JOIN comments ON databases.id = comments.id",
6092 access: vec![PUBLIC_SELECT],
6093 ontology: None,
6094});
6095
6096pub static MZ_SHOW_SCHEMAS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6097 name: "mz_show_schemas",
6098 schema: MZ_INTERNAL_SCHEMA,
6099 oid: oid::VIEW_MZ_SHOW_SCHEMAS_OID,
6100 desc: RelationDesc::builder()
6101 .with_column("database_id", SqlScalarType::String.nullable(true))
6102 .with_column("name", SqlScalarType::String.nullable(false))
6103 .with_column("comment", SqlScalarType::String.nullable(false))
6104 .finish(),
6105 column_comments: BTreeMap::new(),
6106 sql: "WITH comments AS (
6107 SELECT id, comment
6108 FROM mz_internal.mz_comments
6109 WHERE object_type = 'schema' AND object_sub_id IS NULL
6110 )
6111 SELECT database_id, name, COALESCE(comment, '') as comment
6112 FROM mz_catalog.mz_schemas schemas
6113 LEFT JOIN comments ON schemas.id = comments.id",
6114 access: vec![PUBLIC_SELECT],
6115 ontology: None,
6116});
6117
6118pub static MZ_SHOW_ROLES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6119 name: "mz_show_roles",
6120 schema: MZ_INTERNAL_SCHEMA,
6121 oid: oid::VIEW_MZ_SHOW_ROLES_OID,
6122 desc: RelationDesc::builder()
6123 .with_column("name", SqlScalarType::String.nullable(false))
6124 .with_column("comment", SqlScalarType::String.nullable(false))
6125 .finish(),
6126 column_comments: BTreeMap::new(),
6127 sql: "WITH comments AS (
6128 SELECT id, comment
6129 FROM mz_internal.mz_comments
6130 WHERE object_type = 'role' AND object_sub_id IS NULL
6131 )
6132 SELECT name, COALESCE(comment, '') as comment
6133 FROM mz_catalog.mz_roles roles
6134 LEFT JOIN comments ON roles.id = comments.id
6135 WHERE roles.id NOT LIKE 's%'
6136 AND roles.id NOT LIKE 'g%'",
6137 access: vec![PUBLIC_SELECT],
6138 ontology: None,
6139});
6140
6141pub static MZ_SHOW_TABLES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6142 name: "mz_show_tables",
6143 schema: MZ_INTERNAL_SCHEMA,
6144 oid: oid::VIEW_MZ_SHOW_TABLES_OID,
6145 desc: RelationDesc::builder()
6146 .with_column("schema_id", SqlScalarType::String.nullable(false))
6147 .with_column("name", SqlScalarType::String.nullable(false))
6148 .with_column("comment", SqlScalarType::String.nullable(false))
6149 .with_column("source_id", SqlScalarType::String.nullable(true))
6150 .finish(),
6151 column_comments: BTreeMap::new(),
6152 sql: "WITH comments AS (
6153 SELECT id, comment
6154 FROM mz_internal.mz_comments
6155 WHERE object_type = 'table' AND object_sub_id IS NULL
6156 )
6157 SELECT schema_id, name, COALESCE(comment, '') as comment, source_id
6158 FROM mz_catalog.mz_tables tables
6159 LEFT JOIN comments ON tables.id = comments.id",
6160 access: vec![PUBLIC_SELECT],
6161 ontology: None,
6162});
6163
6164pub static MZ_SHOW_VIEWS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6165 name: "mz_show_views",
6166 schema: MZ_INTERNAL_SCHEMA,
6167 oid: oid::VIEW_MZ_SHOW_VIEWS_OID,
6168 desc: RelationDesc::builder()
6169 .with_column("schema_id", SqlScalarType::String.nullable(false))
6170 .with_column("name", SqlScalarType::String.nullable(false))
6171 .with_column("comment", SqlScalarType::String.nullable(false))
6172 .finish(),
6173 column_comments: BTreeMap::new(),
6174 sql: "WITH comments AS (
6175 SELECT id, comment
6176 FROM mz_internal.mz_comments
6177 WHERE object_type = 'view' AND object_sub_id IS NULL
6178 )
6179 SELECT schema_id, name, COALESCE(comment, '') as comment
6180 FROM mz_catalog.mz_views views
6181 LEFT JOIN comments ON views.id = comments.id",
6182 access: vec![PUBLIC_SELECT],
6183 ontology: None,
6184});
6185
6186pub static MZ_SHOW_TYPES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6187 name: "mz_show_types",
6188 schema: MZ_INTERNAL_SCHEMA,
6189 oid: oid::VIEW_MZ_SHOW_TYPES_OID,
6190 desc: RelationDesc::builder()
6191 .with_column("schema_id", SqlScalarType::String.nullable(false))
6192 .with_column("name", SqlScalarType::String.nullable(false))
6193 .with_column("comment", SqlScalarType::String.nullable(false))
6194 .finish(),
6195 column_comments: BTreeMap::new(),
6196 sql: "WITH comments AS (
6197 SELECT id, comment
6198 FROM mz_internal.mz_comments
6199 WHERE object_type = 'type' AND object_sub_id IS NULL
6200 )
6201 SELECT schema_id, name, COALESCE(comment, '') as comment
6202 FROM mz_catalog.mz_types types
6203 LEFT JOIN comments ON types.id = comments.id",
6204 access: vec![PUBLIC_SELECT],
6205 ontology: None,
6206});
6207
6208pub static MZ_SHOW_CONNECTIONS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6209 name: "mz_show_connections",
6210 schema: MZ_INTERNAL_SCHEMA,
6211 oid: oid::VIEW_MZ_SHOW_CONNECTIONS_OID,
6212 desc: RelationDesc::builder()
6213 .with_column("schema_id", SqlScalarType::String.nullable(false))
6214 .with_column("name", SqlScalarType::String.nullable(false))
6215 .with_column("type", SqlScalarType::String.nullable(false))
6216 .with_column("comment", SqlScalarType::String.nullable(false))
6217 .finish(),
6218 column_comments: BTreeMap::new(),
6219 sql: "WITH comments AS (
6220 SELECT id, comment
6221 FROM mz_internal.mz_comments
6222 WHERE object_type = 'connection' AND object_sub_id IS NULL
6223 )
6224 SELECT schema_id, name, type, COALESCE(comment, '') as comment
6225 FROM mz_catalog.mz_connections connections
6226 LEFT JOIN comments ON connections.id = comments.id",
6227 access: vec![PUBLIC_SELECT],
6228 ontology: None,
6229});
6230
6231pub static MZ_SHOW_SOURCES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6232 name: "mz_show_sources",
6233 schema: MZ_INTERNAL_SCHEMA,
6234 oid: oid::VIEW_MZ_SHOW_SOURCES_OID,
6235 desc: RelationDesc::builder()
6236 .with_column("id", SqlScalarType::String.nullable(false))
6237 .with_column("name", SqlScalarType::String.nullable(false))
6238 .with_column("type", SqlScalarType::String.nullable(false))
6239 .with_column("cluster", SqlScalarType::String.nullable(true))
6240 .with_column("schema_id", SqlScalarType::String.nullable(false))
6241 .with_column("cluster_id", SqlScalarType::String.nullable(true))
6242 .with_column("comment", SqlScalarType::String.nullable(false))
6243 .finish(),
6244 column_comments: BTreeMap::new(),
6245 sql: "
6246WITH comments AS (
6247 SELECT id, comment
6248 FROM mz_internal.mz_comments
6249 WHERE object_type = 'source' AND object_sub_id IS NULL
6250)
6251SELECT
6252 sources.id,
6253 sources.name,
6254 sources.type,
6255 clusters.name AS cluster,
6256 schema_id,
6257 cluster_id,
6258 COALESCE(comments.comment, '') as comment
6259FROM
6260 mz_catalog.mz_sources AS sources
6261 LEFT JOIN
6262 mz_catalog.mz_clusters AS clusters
6263 ON clusters.id = sources.cluster_id
6264 LEFT JOIN comments ON sources.id = comments.id",
6265 access: vec![PUBLIC_SELECT],
6266 ontology: None,
6267});
6268
6269pub static MZ_SHOW_SINKS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6270 name: "mz_show_sinks",
6271 schema: MZ_INTERNAL_SCHEMA,
6272 oid: oid::VIEW_MZ_SHOW_SINKS_OID,
6273 desc: RelationDesc::builder()
6274 .with_column("id", SqlScalarType::String.nullable(false))
6275 .with_column("name", SqlScalarType::String.nullable(false))
6276 .with_column("type", SqlScalarType::String.nullable(false))
6277 .with_column("cluster", SqlScalarType::String.nullable(false))
6278 .with_column("schema_id", SqlScalarType::String.nullable(false))
6279 .with_column("cluster_id", SqlScalarType::String.nullable(false))
6280 .with_column("comment", SqlScalarType::String.nullable(false))
6281 .finish(),
6282 column_comments: BTreeMap::new(),
6283 sql: "
6284WITH comments AS (
6285 SELECT id, comment
6286 FROM mz_internal.mz_comments
6287 WHERE object_type = 'sink' AND object_sub_id IS NULL
6288)
6289SELECT
6290 sinks.id,
6291 sinks.name,
6292 sinks.type,
6293 clusters.name AS cluster,
6294 schema_id,
6295 cluster_id,
6296 COALESCE(comments.comment, '') as comment
6297FROM
6298 mz_catalog.mz_sinks AS sinks
6299 JOIN
6300 mz_catalog.mz_clusters AS clusters
6301 ON clusters.id = sinks.cluster_id
6302 LEFT JOIN comments ON sinks.id = comments.id",
6303 access: vec![PUBLIC_SELECT],
6304 ontology: None,
6305});
6306
6307pub static MZ_SHOW_MATERIALIZED_VIEWS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6308 name: "mz_show_materialized_views",
6309 schema: MZ_INTERNAL_SCHEMA,
6310 oid: oid::VIEW_MZ_SHOW_MATERIALIZED_VIEWS_OID,
6311 desc: RelationDesc::builder()
6312 .with_column("id", SqlScalarType::String.nullable(false))
6313 .with_column("name", SqlScalarType::String.nullable(false))
6314 .with_column("cluster", SqlScalarType::String.nullable(false))
6315 .with_column("schema_id", SqlScalarType::String.nullable(false))
6316 .with_column("cluster_id", SqlScalarType::String.nullable(false))
6317 .with_column("comment", SqlScalarType::String.nullable(false))
6318 .finish(),
6319 column_comments: BTreeMap::new(),
6320 sql: "
6321WITH
6322 comments AS (
6323 SELECT id, comment
6324 FROM mz_internal.mz_comments
6325 WHERE object_type = 'materialized-view' AND object_sub_id IS NULL
6326 )
6327SELECT
6328 mviews.id as id,
6329 mviews.name,
6330 clusters.name AS cluster,
6331 schema_id,
6332 cluster_id,
6333 COALESCE(comments.comment, '') as comment
6334FROM
6335 mz_catalog.mz_materialized_views AS mviews
6336 JOIN mz_catalog.mz_clusters AS clusters ON clusters.id = mviews.cluster_id
6337 LEFT JOIN comments ON mviews.id = comments.id",
6338 access: vec![PUBLIC_SELECT],
6339 ontology: None,
6340});
6341
6342pub static MZ_SHOW_INDEXES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6343 name: "mz_show_indexes",
6344 schema: MZ_INTERNAL_SCHEMA,
6345 oid: oid::VIEW_MZ_SHOW_INDEXES_OID,
6346 desc: RelationDesc::builder()
6347 .with_column("id", SqlScalarType::String.nullable(false))
6348 .with_column("name", SqlScalarType::String.nullable(false))
6349 .with_column("on", SqlScalarType::String.nullable(false))
6350 .with_column("cluster", SqlScalarType::String.nullable(false))
6351 .with_column(
6352 "key",
6353 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
6354 )
6355 .with_column("on_id", SqlScalarType::String.nullable(false))
6356 .with_column("schema_id", SqlScalarType::String.nullable(false))
6357 .with_column("cluster_id", SqlScalarType::String.nullable(false))
6358 .with_column("comment", SqlScalarType::String.nullable(false))
6359 .finish(),
6360 column_comments: BTreeMap::new(),
6361 sql: "
6362WITH comments AS (
6363 SELECT id, comment
6364 FROM mz_internal.mz_comments
6365 WHERE object_type = 'index' AND object_sub_id IS NULL
6366)
6367SELECT
6368 idxs.id AS id,
6369 idxs.name AS name,
6370 objs.name AS on,
6371 clusters.name AS cluster,
6372 COALESCE(keys.key, '{}'::_text) AS key,
6373 idxs.on_id AS on_id,
6374 objs.schema_id AS schema_id,
6375 clusters.id AS cluster_id,
6376 COALESCE(comments.comment, '') as comment
6377FROM
6378 mz_catalog.mz_indexes AS idxs
6379 JOIN mz_catalog.mz_objects AS objs ON idxs.on_id = objs.id
6380 JOIN mz_catalog.mz_clusters AS clusters ON clusters.id = idxs.cluster_id
6381 LEFT JOIN
6382 (SELECT
6383 idxs.id,
6384 ARRAY_AGG(
6385 CASE
6386 WHEN idx_cols.on_expression IS NULL THEN obj_cols.name
6387 ELSE idx_cols.on_expression
6388 END
6389 ORDER BY idx_cols.index_position ASC
6390 ) AS key
6391 FROM
6392 mz_catalog.mz_indexes AS idxs
6393 JOIN mz_catalog.mz_index_columns idx_cols ON idxs.id = idx_cols.index_id
6394 LEFT JOIN mz_catalog.mz_columns obj_cols ON
6395 idxs.on_id = obj_cols.id AND idx_cols.on_position = obj_cols.position
6396 GROUP BY idxs.id) AS keys
6397 ON idxs.id = keys.id
6398 LEFT JOIN comments ON idxs.id = comments.id",
6399 access: vec![PUBLIC_SELECT],
6400 ontology: None,
6401});
6402
6403pub static MZ_SHOW_CLUSTER_REPLICAS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6404 name: "mz_show_cluster_replicas",
6405 schema: MZ_INTERNAL_SCHEMA,
6406 oid: oid::VIEW_MZ_SHOW_CLUSTER_REPLICAS_OID,
6407 desc: RelationDesc::builder()
6408 .with_column("cluster", SqlScalarType::String.nullable(false))
6409 .with_column("replica", SqlScalarType::String.nullable(false))
6410 .with_column("replica_id", SqlScalarType::String.nullable(false))
6411 .with_column("size", SqlScalarType::String.nullable(true))
6412 .with_column("ready", SqlScalarType::Bool.nullable(false))
6413 .with_column("comment", SqlScalarType::String.nullable(false))
6414 .finish(),
6415 column_comments: BTreeMap::new(),
6416 sql: r#"SELECT
6417 mz_catalog.mz_clusters.name AS cluster,
6418 mz_catalog.mz_cluster_replicas.name AS replica,
6419 mz_catalog.mz_cluster_replicas.id as replica_id,
6420 mz_catalog.mz_cluster_replicas.size AS size,
6421 coalesce(statuses.ready, FALSE) AS ready,
6422 coalesce(comments.comment, '') as comment
6423FROM
6424 mz_catalog.mz_cluster_replicas
6425 JOIN mz_catalog.mz_clusters
6426 ON mz_catalog.mz_cluster_replicas.cluster_id = mz_catalog.mz_clusters.id
6427 LEFT JOIN
6428 (
6429 SELECT
6430 replica_id,
6431 bool_and(hydrated) AS ready
6432 FROM mz_internal.mz_hydration_statuses
6433 WHERE replica_id is not null
6434 GROUP BY replica_id
6435 ) AS statuses
6436 ON mz_catalog.mz_cluster_replicas.id = statuses.replica_id
6437 LEFT JOIN mz_internal.mz_comments comments
6438 ON mz_catalog.mz_cluster_replicas.id = comments.id
6439 AND comments.object_type = 'cluster-replica'
6440ORDER BY 1, 2"#,
6441 access: vec![PUBLIC_SELECT],
6442 ontology: None,
6443});
6444
6445pub static MZ_MCP_DATA_PRODUCTS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6454 name: "mz_mcp_data_products",
6455 schema: MZ_INTERNAL_SCHEMA,
6456 oid: oid::VIEW_MZ_MCP_DATA_PRODUCTS_OID,
6457 desc: RelationDesc::builder()
6458 .with_column("object_name", SqlScalarType::String.nullable(false))
6459 .with_column("cluster", SqlScalarType::String.nullable(true))
6460 .with_column("description", SqlScalarType::String.nullable(true))
6461 .with_key(vec![0, 1, 2])
6462 .finish(),
6463 column_comments: BTreeMap::from_iter([
6464 (
6465 "object_name",
6466 "Fully qualified object name (database.schema.name).",
6467 ),
6468 (
6469 "cluster",
6470 "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).",
6471 ),
6472 (
6473 "description",
6474 "Index comment if available, otherwise object comment. Used as data product description.",
6475 ),
6476 ]),
6477 sql: r#"
6486SELECT DISTINCT
6487 '"' || op.database || '"."' || op.schema || '"."' || op.name || '"' AS object_name,
6488 CASE WHEN cp.name IS NOT NULL THEN COALESCE(c_idx.name, c_obj.name) END AS cluster,
6489 COALESCE(cts_idx.comment, cts_obj.comment) AS description
6490FROM mz_internal.mz_show_my_object_privileges op
6491JOIN mz_objects o ON op.name = o.name AND op.object_type = o.type
6492JOIN mz_schemas s ON s.name = op.schema AND s.id = o.schema_id
6493JOIN mz_databases d ON d.name = op.database AND d.id = s.database_id
6494LEFT JOIN mz_indexes i ON i.on_id = o.id
6495LEFT JOIN mz_clusters c_idx ON c_idx.id = i.cluster_id
6496LEFT JOIN mz_clusters c_obj ON c_obj.id = o.cluster_id
6497LEFT JOIN mz_internal.mz_show_my_cluster_privileges cp
6498 ON cp.name = COALESCE(c_idx.name, c_obj.name) AND cp.privilege_type = 'USAGE'
6499LEFT 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
6500LEFT 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
6501WHERE op.privilege_type = 'SELECT'
6502 AND (o.type = 'materialized-view'
6503 OR (o.type = 'view' AND i.id IS NOT NULL AND cp.name IS NOT NULL))
6504 AND s.name NOT IN ('mz_catalog', 'mz_internal', 'pg_catalog', 'information_schema', 'mz_introspection')
6505"#,
6506 access: vec![PUBLIC_SELECT],
6507 ontology: None,
6508});
6509
6510pub static MZ_MCP_DATA_PRODUCT_DETAILS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6519 name: "mz_mcp_data_product_details",
6520 schema: MZ_INTERNAL_SCHEMA,
6521 oid: oid::VIEW_MZ_MCP_DATA_PRODUCT_DETAILS_OID,
6522 desc: RelationDesc::builder()
6529 .with_column("object_name", SqlScalarType::String.nullable(false))
6530 .with_column("cluster", SqlScalarType::String.nullable(true))
6531 .with_column("description", SqlScalarType::String.nullable(true))
6532 .with_column("schema", SqlScalarType::Jsonb.nullable(false))
6533 .with_column("hydration", SqlScalarType::Jsonb.nullable(false))
6534 .finish(),
6535 column_comments: BTreeMap::from_iter([
6536 (
6537 "object_name",
6538 "Fully qualified object name (database.schema.name).",
6539 ),
6540 (
6541 "cluster",
6542 "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).",
6543 ),
6544 (
6545 "description",
6546 "Index comment if available, otherwise object comment. Used as data product description.",
6547 ),
6548 (
6549 "schema",
6550 "JSON Schema describing the object's columns and types.",
6551 ),
6552 (
6553 "hydration",
6554 "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.",
6555 ),
6556 ]),
6557 sql: r#"
6558WITH details_raw AS (
6559 SELECT
6560 '"' || op.database || '"."' || op.schema || '"."' || op.name || '"' AS object_name,
6561 COALESCE(c_idx.name, c_obj.name) AS cluster,
6562 COALESCE(cts_idx.comment, cts_obj.comment) AS description,
6563 COALESCE(jsonb_build_object(
6564 'type', 'object',
6565 'indexedColumns', jsonb_agg(distinct ccol.name) FILTER (WHERE ccol.position = ic.on_position),
6566 'properties', jsonb_strip_nulls(jsonb_object_agg(
6567 ccol.name,
6568 CASE
6569 WHEN ccol.type IN (
6570 'uint2', 'uint4','uint8', 'int', 'integer', 'smallint',
6571 'double', 'double precision', 'bigint', 'float',
6572 'numeric', 'real'
6573 ) THEN jsonb_build_object(
6574 'type', 'number',
6575 'description', cts_col.comment
6576 )
6577 WHEN ccol.type = 'boolean' THEN jsonb_build_object(
6578 'type', 'boolean',
6579 'description', cts_col.comment
6580 )
6581 WHEN ccol.type = 'bytea' THEN jsonb_build_object(
6582 'type', 'string',
6583 'description', cts_col.comment,
6584 'contentEncoding', 'base64',
6585 'contentMediaType', 'application/octet-stream'
6586 )
6587 WHEN ccol.type = 'date' THEN jsonb_build_object(
6588 'type', 'string',
6589 'format', 'date',
6590 'description', cts_col.comment
6591 )
6592 WHEN ccol.type = 'time' THEN jsonb_build_object(
6593 'type', 'string',
6594 'format', 'time',
6595 'description', cts_col.comment
6596 )
6597 WHEN ccol.type ilike 'timestamp%%' THEN jsonb_build_object(
6598 'type', 'string',
6599 'format', 'date-time',
6600 'description', cts_col.comment
6601 )
6602 WHEN ccol.type = 'jsonb' THEN jsonb_build_object(
6603 'type', 'object',
6604 'description', cts_col.comment
6605 )
6606 WHEN ccol.type = 'uuid' THEN jsonb_build_object(
6607 'type', 'string',
6608 'format', 'uuid',
6609 'description', cts_col.comment
6610 )
6611 ELSE jsonb_build_object(
6612 'type', 'string',
6613 'description', cts_col.comment
6614 )
6615 END
6616 ))
6617 ), '{"type": "object", "properties": {}}'::jsonb) AS schema
6618FROM mz_internal.mz_show_my_object_privileges op
6619JOIN mz_objects o ON op.name = o.name AND op.object_type = o.type
6620JOIN mz_schemas s ON s.name = op.schema AND s.id = o.schema_id
6621JOIN mz_databases d ON d.name = op.database AND d.id = s.database_id
6622JOIN mz_columns ccol ON ccol.id = o.id
6623LEFT JOIN mz_indexes i ON i.on_id = o.id
6624LEFT JOIN mz_index_columns ic ON i.id = ic.index_id
6625LEFT JOIN mz_clusters c_idx ON c_idx.id = i.cluster_id
6626LEFT JOIN mz_clusters c_obj ON c_obj.id = o.cluster_id
6627LEFT JOIN mz_internal.mz_show_my_cluster_privileges cp
6628 ON cp.name = COALESCE(c_idx.name, c_obj.name) AND cp.privilege_type = 'USAGE'
6629LEFT 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
6630LEFT 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
6631LEFT 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
6632WHERE op.privilege_type = 'SELECT'
6633 AND (o.type = 'materialized-view'
6634 OR (o.type = 'view' AND i.id IS NOT NULL AND cp.name IS NOT NULL))
6635 AND s.name NOT IN ('mz_catalog', 'mz_internal', 'pg_catalog', 'information_schema', 'mz_introspection')
6636GROUP BY 1, 2, 3
6637),
6638-- Pick the right (object_id, cluster_id) for hydration: the index's id +
6639-- cluster when an index exists (its arrangement is what the data product
6640-- reads from), otherwise the materialized view's own id + cluster.
6641hydration_meta AS (
6642 SELECT DISTINCT
6643 '"' || db.name || '"."' || s.name || '"."' || o.name || '"' AS object_name,
6644 COALESCE(c_idx.name, c_obj.name) AS cluster,
6645 COALESCE(i.id, o.id) AS hydration_object_id,
6646 COALESCE(i.cluster_id, o.cluster_id) AS cluster_id
6647 FROM mz_objects o
6648 JOIN mz_schemas s ON s.id = o.schema_id
6649 JOIN mz_databases db ON db.id = s.database_id
6650 LEFT JOIN mz_indexes i ON i.on_id = o.id
6651 LEFT JOIN mz_clusters c_idx ON c_idx.id = i.cluster_id
6652 LEFT JOIN mz_clusters c_obj ON c_obj.id = o.cluster_id
6653 WHERE (o.type = 'materialized-view' OR (o.type = 'view' AND i.id IS NOT NULL))
6654 AND s.name NOT IN ('mz_catalog', 'mz_internal', 'pg_catalog', 'information_schema', 'mz_introspection')
6655),
6656-- Dedupe by replica before counting: an MV with multiple indexes on the
6657-- same cluster has multiple rows in `hydration_meta`, and joining each
6658-- of them against `mz_cluster_replicas` would otherwise inflate the
6659-- counts by the number of indexes. A replica is "hydrated" only when
6660-- every index dataflow for this data product is hydrated on it.
6661hydration_per_replica AS (
6662 SELECT
6663 m.object_name,
6664 m.cluster,
6665 r.id AS replica_id,
6666 bool_and(COALESCE(h.hydrated, false)) AS replica_hydrated
6667 FROM hydration_meta m
6668 LEFT JOIN mz_catalog.mz_cluster_replicas r ON r.cluster_id = m.cluster_id
6669 LEFT JOIN mz_internal.mz_hydration_statuses h
6670 ON h.replica_id = r.id AND h.object_id = m.hydration_object_id
6671 GROUP BY m.object_name, m.cluster, r.id
6672),
6673hydration AS (
6674 SELECT
6675 object_name,
6676 cluster,
6677 COUNT(replica_id)::int AS replica_count,
6678 COUNT(replica_id) FILTER (WHERE replica_hydrated)::int AS hydrated_replica_count
6679 FROM hydration_per_replica
6680 GROUP BY object_name, cluster
6681)
6682SELECT
6683 d.object_name,
6684 -- Null the advertised cluster unless the role has USAGE on it (DEX-66),
6685 -- matching mz_mcp_data_products. Hydration below still joins on the real
6686 -- d.cluster, so readiness is reported accurately even when the name is
6687 -- hidden.
6688 CASE WHEN EXISTS (
6689 SELECT 1 FROM mz_internal.mz_show_my_cluster_privileges cp
6690 WHERE cp.name = d.cluster AND cp.privilege_type = 'USAGE'
6691 ) THEN d.cluster END AS cluster,
6692 d.description,
6693 d.schema,
6694 jsonb_build_object(
6695 'hydrated',
6696 COALESCE(h.replica_count > 0 AND h.hydrated_replica_count = h.replica_count, false),
6697 'replica_count', COALESCE(h.replica_count, 0),
6698 'hydrated_replica_count', COALESCE(h.hydrated_replica_count, 0)
6699 ) AS hydration
6700FROM details_raw d
6701LEFT JOIN hydration h
6702 ON h.object_name = d.object_name
6703 AND h.cluster IS NOT DISTINCT FROM d.cluster
6704"#,
6705 access: vec![PUBLIC_SELECT],
6706 ontology: None,
6707});
6708
6709pub static MZ_SHOW_ROLE_MEMBERS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6710 name: "mz_show_role_members",
6711 schema: MZ_INTERNAL_SCHEMA,
6712 oid: oid::VIEW_MZ_SHOW_ROLE_MEMBERS_OID,
6713 desc: RelationDesc::builder()
6714 .with_column("role", SqlScalarType::String.nullable(false))
6715 .with_column("member", SqlScalarType::String.nullable(false))
6716 .with_column("grantor", SqlScalarType::String.nullable(false))
6717 .finish(),
6718 column_comments: BTreeMap::from_iter([
6719 ("role", "The role that `member` is a member of."),
6720 ("member", "The role that is a member of `role`."),
6721 (
6722 "grantor",
6723 "The role that granted membership of `member` to `role`.",
6724 ),
6725 ]),
6726 sql: r#"SELECT
6727 r1.name AS role,
6728 r2.name AS member,
6729 r3.name AS grantor
6730FROM mz_catalog.mz_role_members rm
6731JOIN mz_catalog.mz_roles r1 ON r1.id = rm.role_id
6732JOIN mz_catalog.mz_roles r2 ON r2.id = rm.member
6733JOIN mz_catalog.mz_roles r3 ON r3.id = rm.grantor
6734ORDER BY role"#,
6735 access: vec![PUBLIC_SELECT],
6736 ontology: None,
6737});
6738
6739pub static MZ_SHOW_MY_ROLE_MEMBERS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6740 name: "mz_show_my_role_members",
6741 schema: MZ_INTERNAL_SCHEMA,
6742 oid: oid::VIEW_MZ_SHOW_MY_ROLE_MEMBERS_OID,
6743 desc: RelationDesc::builder()
6744 .with_column("role", SqlScalarType::String.nullable(false))
6745 .with_column("member", SqlScalarType::String.nullable(false))
6746 .with_column("grantor", SqlScalarType::String.nullable(false))
6747 .finish(),
6748 column_comments: BTreeMap::from_iter([
6749 ("role", "The role that `member` is a member of."),
6750 ("member", "The role that is a member of `role`."),
6751 (
6752 "grantor",
6753 "The role that granted membership of `member` to `role`.",
6754 ),
6755 ]),
6756 sql: r#"SELECT role, member, grantor
6757FROM mz_internal.mz_show_role_members
6758WHERE pg_has_role(member, 'USAGE')"#,
6759 access: vec![PUBLIC_SELECT],
6760 ontology: None,
6761});
6762
6763pub static MZ_SHOW_SYSTEM_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6764 name: "mz_show_system_privileges",
6765 schema: MZ_INTERNAL_SCHEMA,
6766 oid: oid::VIEW_MZ_SHOW_SYSTEM_PRIVILEGES_OID,
6767 desc: RelationDesc::builder()
6768 .with_column("grantor", SqlScalarType::String.nullable(true))
6769 .with_column("grantee", SqlScalarType::String.nullable(true))
6770 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6771 .finish(),
6772 column_comments: BTreeMap::from_iter([
6773 ("grantor", "The role that granted the privilege."),
6774 ("grantee", "The role that the privilege was granted to."),
6775 ("privilege_type", "They type of privilege granted."),
6776 ]),
6777 sql: r#"SELECT
6778 grantor.name AS grantor,
6779 CASE privileges.grantee
6780 WHEN 'p' THEN 'PUBLIC'
6781 ELSE grantee.name
6782 END AS grantee,
6783 privileges.privilege_type AS privilege_type
6784FROM
6785 (SELECT mz_internal.mz_aclexplode(ARRAY[privileges]).*
6786 FROM mz_catalog.mz_system_privileges) AS privileges
6787LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
6788LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
6789WHERE privileges.grantee NOT LIKE 's%'"#,
6790 access: vec![PUBLIC_SELECT],
6791 ontology: None,
6792});
6793
6794pub static MZ_SHOW_MY_SYSTEM_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6795 name: "mz_show_my_system_privileges",
6796 schema: MZ_INTERNAL_SCHEMA,
6797 oid: oid::VIEW_MZ_SHOW_MY_SYSTEM_PRIVILEGES_OID,
6798 desc: RelationDesc::builder()
6799 .with_column("grantor", SqlScalarType::String.nullable(true))
6800 .with_column("grantee", SqlScalarType::String.nullable(true))
6801 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6802 .finish(),
6803 column_comments: BTreeMap::from_iter([
6804 ("grantor", "The role that granted the privilege."),
6805 ("grantee", "The role that the privilege was granted to."),
6806 ("privilege_type", "They type of privilege granted."),
6807 ]),
6808 sql: r#"SELECT grantor, grantee, privilege_type
6809FROM mz_internal.mz_show_system_privileges
6810WHERE
6811 CASE
6812 WHEN grantee = 'PUBLIC' THEN true
6813 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6814 -- whether the current user holds role `grantee`. For a nonexistent grantee
6815 -- name, both return false. We use mz_session_role_memberships() instead
6816 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6817 -- loads the full system role graph and is blocked in restricted sessions.
6818 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6819 END"#,
6820 access: vec![PUBLIC_SELECT],
6821 ontology: None,
6822});
6823
6824pub static MZ_SHOW_CLUSTER_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6825 name: "mz_show_cluster_privileges",
6826 schema: MZ_INTERNAL_SCHEMA,
6827 oid: oid::VIEW_MZ_SHOW_CLUSTER_PRIVILEGES_OID,
6828 desc: RelationDesc::builder()
6829 .with_column("grantor", SqlScalarType::String.nullable(true))
6830 .with_column("grantee", SqlScalarType::String.nullable(true))
6831 .with_column("name", SqlScalarType::String.nullable(false))
6832 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6833 .finish(),
6834 column_comments: BTreeMap::from_iter([
6835 ("grantor", "The role that granted the privilege."),
6836 ("grantee", "The role that the privilege was granted to."),
6837 ("name", "The name of the cluster."),
6838 ("privilege_type", "They type of privilege granted."),
6839 ]),
6840 sql: r#"SELECT
6841 grantor.name AS grantor,
6842 CASE privileges.grantee
6843 WHEN 'p' THEN 'PUBLIC'
6844 ELSE grantee.name
6845 END AS grantee,
6846 privileges.name AS name,
6847 privileges.privilege_type AS privilege_type
6848FROM
6849 (SELECT mz_internal.mz_aclexplode(privileges).*, name
6850 FROM mz_catalog.mz_clusters
6851 WHERE id NOT LIKE 's%') AS privileges
6852LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
6853LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
6854WHERE privileges.grantee NOT LIKE 's%'"#,
6855 access: vec![PUBLIC_SELECT],
6856 ontology: None,
6857});
6858
6859pub static MZ_SHOW_MY_CLUSTER_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6860 name: "mz_show_my_cluster_privileges",
6861 schema: MZ_INTERNAL_SCHEMA,
6862 oid: oid::VIEW_MZ_SHOW_MY_CLUSTER_PRIVILEGES_OID,
6863 desc: RelationDesc::builder()
6864 .with_column("grantor", SqlScalarType::String.nullable(true))
6865 .with_column("grantee", SqlScalarType::String.nullable(true))
6866 .with_column("name", SqlScalarType::String.nullable(false))
6867 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6868 .finish(),
6869 column_comments: BTreeMap::from_iter([
6870 ("grantor", "The role that granted the privilege."),
6871 ("grantee", "The role that the privilege was granted to."),
6872 ("name", "The name of the cluster."),
6873 ("privilege_type", "They type of privilege granted."),
6874 ]),
6875 sql: r#"SELECT grantor, grantee, name, privilege_type
6876FROM mz_internal.mz_show_cluster_privileges
6877WHERE
6878 CASE
6879 WHEN grantee = 'PUBLIC' THEN true
6880 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6881 -- whether the current user holds role `grantee`. For a nonexistent grantee
6882 -- name, both return false. We use mz_session_role_memberships() instead
6883 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6884 -- loads the full system role graph and is blocked in restricted sessions.
6885 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6886 END"#,
6887 access: vec![PUBLIC_SELECT],
6888 ontology: None,
6889});
6890
6891pub static MZ_SHOW_DATABASE_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6892 name: "mz_show_database_privileges",
6893 schema: MZ_INTERNAL_SCHEMA,
6894 oid: oid::VIEW_MZ_SHOW_DATABASE_PRIVILEGES_OID,
6895 desc: RelationDesc::builder()
6896 .with_column("grantor", SqlScalarType::String.nullable(true))
6897 .with_column("grantee", SqlScalarType::String.nullable(true))
6898 .with_column("name", SqlScalarType::String.nullable(false))
6899 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6900 .finish(),
6901 column_comments: BTreeMap::from_iter([
6902 ("grantor", "The role that granted the privilege."),
6903 ("grantee", "The role that the privilege was granted to."),
6904 ("name", "The name of the database."),
6905 ("privilege_type", "They type of privilege granted."),
6906 ]),
6907 sql: r#"SELECT
6908 grantor.name AS grantor,
6909 CASE privileges.grantee
6910 WHEN 'p' THEN 'PUBLIC'
6911 ELSE grantee.name
6912 END AS grantee,
6913 privileges.name AS name,
6914 privileges.privilege_type AS privilege_type
6915FROM
6916 (SELECT mz_internal.mz_aclexplode(privileges).*, name
6917 FROM mz_catalog.mz_databases
6918 WHERE id NOT LIKE 's%') AS privileges
6919LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
6920LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
6921WHERE privileges.grantee NOT LIKE 's%'"#,
6922 access: vec![PUBLIC_SELECT],
6923 ontology: None,
6924});
6925
6926pub static MZ_SHOW_MY_DATABASE_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6927 name: "mz_show_my_database_privileges",
6928 schema: MZ_INTERNAL_SCHEMA,
6929 oid: oid::VIEW_MZ_SHOW_MY_DATABASE_PRIVILEGES_OID,
6930 desc: RelationDesc::builder()
6931 .with_column("grantor", SqlScalarType::String.nullable(true))
6932 .with_column("grantee", SqlScalarType::String.nullable(true))
6933 .with_column("name", SqlScalarType::String.nullable(false))
6934 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6935 .finish(),
6936 column_comments: BTreeMap::from_iter([
6937 ("grantor", "The role that granted the privilege."),
6938 ("grantee", "The role that the privilege was granted to."),
6939 ("name", "The name of the cluster."),
6940 ("privilege_type", "They type of privilege granted."),
6941 ]),
6942 sql: r#"SELECT grantor, grantee, name, privilege_type
6943FROM mz_internal.mz_show_database_privileges
6944WHERE
6945 CASE
6946 WHEN grantee = 'PUBLIC' THEN true
6947 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
6948 -- whether the current user holds role `grantee`. For a nonexistent grantee
6949 -- name, both return false. We use mz_session_role_memberships() instead
6950 -- because pg_has_role internally calls mz_role_oid_memberships(), which
6951 -- loads the full system role graph and is blocked in restricted sessions.
6952 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
6953 END"#,
6954 access: vec![PUBLIC_SELECT],
6955 ontology: None,
6956});
6957
6958pub static MZ_SHOW_SCHEMA_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
6959 name: "mz_show_schema_privileges",
6960 schema: MZ_INTERNAL_SCHEMA,
6961 oid: oid::VIEW_MZ_SHOW_SCHEMA_PRIVILEGES_OID,
6962 desc: RelationDesc::builder()
6963 .with_column("grantor", SqlScalarType::String.nullable(true))
6964 .with_column("grantee", SqlScalarType::String.nullable(true))
6965 .with_column("database", SqlScalarType::String.nullable(true))
6966 .with_column("name", SqlScalarType::String.nullable(false))
6967 .with_column("privilege_type", SqlScalarType::String.nullable(false))
6968 .finish(),
6969 column_comments: BTreeMap::from_iter([
6970 ("grantor", "The role that granted the privilege."),
6971 ("grantee", "The role that the privilege was granted to."),
6972 (
6973 "database",
6974 "The name of the database containing the schema.",
6975 ),
6976 ("name", "The name of the schema."),
6977 ("privilege_type", "They type of privilege granted."),
6978 ]),
6979 sql: r#"SELECT
6980 grantor.name AS grantor,
6981 CASE privileges.grantee
6982 WHEN 'p' THEN 'PUBLIC'
6983 ELSE grantee.name
6984 END AS grantee,
6985 databases.name AS database,
6986 privileges.name AS name,
6987 privileges.privilege_type AS privilege_type
6988FROM
6989 (SELECT mz_internal.mz_aclexplode(privileges).*, database_id, name
6990 FROM mz_catalog.mz_schemas
6991 WHERE id NOT LIKE 's%') AS privileges
6992LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
6993LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
6994LEFT JOIN mz_catalog.mz_databases databases ON privileges.database_id = databases.id
6995WHERE privileges.grantee NOT LIKE 's%'"#,
6996 access: vec![PUBLIC_SELECT],
6997 ontology: None,
6998});
6999
7000pub static MZ_SHOW_MY_SCHEMA_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7001 name: "mz_show_my_schema_privileges",
7002 schema: MZ_INTERNAL_SCHEMA,
7003 oid: oid::VIEW_MZ_SHOW_MY_SCHEMA_PRIVILEGES_OID,
7004 desc: RelationDesc::builder()
7005 .with_column("grantor", SqlScalarType::String.nullable(true))
7006 .with_column("grantee", SqlScalarType::String.nullable(true))
7007 .with_column("database", SqlScalarType::String.nullable(true))
7008 .with_column("name", SqlScalarType::String.nullable(false))
7009 .with_column("privilege_type", SqlScalarType::String.nullable(false))
7010 .finish(),
7011 column_comments: BTreeMap::from_iter([
7012 ("grantor", "The role that granted the privilege."),
7013 ("grantee", "The role that the privilege was granted to."),
7014 (
7015 "database",
7016 "The name of the database containing the schema.",
7017 ),
7018 ("name", "The name of the schema."),
7019 ("privilege_type", "They type of privilege granted."),
7020 ]),
7021 sql: r#"SELECT grantor, grantee, database, name, privilege_type
7022FROM mz_internal.mz_show_schema_privileges
7023WHERE
7024 CASE
7025 WHEN grantee = 'PUBLIC' THEN true
7026 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
7027 -- whether the current user holds role `grantee`. For a nonexistent grantee
7028 -- name, both return false. We use mz_session_role_memberships() instead
7029 -- because pg_has_role internally calls mz_role_oid_memberships(), which
7030 -- loads the full system role graph and is blocked in restricted sessions.
7031 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
7032 END"#,
7033 access: vec![PUBLIC_SELECT],
7034 ontology: None,
7035});
7036
7037pub static MZ_SHOW_OBJECT_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7038 name: "mz_show_object_privileges",
7039 schema: MZ_INTERNAL_SCHEMA,
7040 oid: oid::VIEW_MZ_SHOW_OBJECT_PRIVILEGES_OID,
7041 desc: RelationDesc::builder()
7042 .with_column("grantor", SqlScalarType::String.nullable(true))
7043 .with_column("grantee", SqlScalarType::String.nullable(true))
7044 .with_column("database", SqlScalarType::String.nullable(true))
7045 .with_column("schema", SqlScalarType::String.nullable(true))
7046 .with_column("name", SqlScalarType::String.nullable(false))
7047 .with_column("object_type", SqlScalarType::String.nullable(false))
7048 .with_column("privilege_type", SqlScalarType::String.nullable(false))
7049 .finish(),
7050 column_comments: BTreeMap::from_iter([
7051 ("grantor", "The role that granted the privilege."),
7052 ("grantee", "The role that the privilege was granted to."),
7053 (
7054 "database",
7055 "The name of the database containing the object.",
7056 ),
7057 ("schema", "The name of the schema containing the object."),
7058 ("name", "The name of the object."),
7059 (
7060 "object_type",
7061 "The type of object the privilege is granted on.",
7062 ),
7063 ("privilege_type", "They type of privilege granted."),
7064 ]),
7065 sql: r#"SELECT
7066 grantor.name AS grantor,
7067 CASE privileges.grantee
7068 WHEN 'p' THEN 'PUBLIC'
7069 ELSE grantee.name
7070 END AS grantee,
7071 databases.name AS database,
7072 schemas.name AS schema,
7073 privileges.name AS name,
7074 privileges.type AS object_type,
7075 privileges.privilege_type AS privilege_type
7076FROM
7077 (SELECT mz_internal.mz_aclexplode(privileges).*, schema_id, name, type
7078 FROM mz_catalog.mz_objects
7079 WHERE id NOT LIKE 's%') AS privileges
7080LEFT JOIN mz_catalog.mz_roles grantor ON privileges.grantor = grantor.id
7081LEFT JOIN mz_catalog.mz_roles grantee ON privileges.grantee = grantee.id
7082LEFT JOIN mz_catalog.mz_schemas schemas ON privileges.schema_id = schemas.id
7083LEFT JOIN mz_catalog.mz_databases databases ON schemas.database_id = databases.id
7084WHERE privileges.grantee NOT LIKE 's%'"#,
7085 access: vec![PUBLIC_SELECT],
7086 ontology: None,
7087});
7088
7089pub static MZ_SHOW_MY_OBJECT_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7090 name: "mz_show_my_object_privileges",
7091 schema: MZ_INTERNAL_SCHEMA,
7092 oid: oid::VIEW_MZ_SHOW_MY_OBJECT_PRIVILEGES_OID,
7093 desc: RelationDesc::builder()
7094 .with_column("grantor", SqlScalarType::String.nullable(true))
7095 .with_column("grantee", SqlScalarType::String.nullable(true))
7096 .with_column("database", SqlScalarType::String.nullable(true))
7097 .with_column("schema", SqlScalarType::String.nullable(true))
7098 .with_column("name", SqlScalarType::String.nullable(false))
7099 .with_column("object_type", SqlScalarType::String.nullable(false))
7100 .with_column("privilege_type", SqlScalarType::String.nullable(false))
7101 .finish(),
7102 column_comments: BTreeMap::from_iter([
7103 ("grantor", "The role that granted the privilege."),
7104 ("grantee", "The role that the privilege was granted to."),
7105 (
7106 "database",
7107 "The name of the database containing the object.",
7108 ),
7109 ("schema", "The name of the schema containing the object."),
7110 ("name", "The name of the object."),
7111 (
7112 "object_type",
7113 "The type of object the privilege is granted on.",
7114 ),
7115 ("privilege_type", "They type of privilege granted."),
7116 ]),
7117 sql: r#"SELECT grantor, grantee, database, schema, name, object_type, privilege_type
7118FROM mz_internal.mz_show_object_privileges
7119WHERE
7120 CASE
7121 WHEN grantee = 'PUBLIC' THEN true
7122 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
7123 -- whether the current user holds role `grantee`. For a nonexistent grantee
7124 -- name, both return false. We use mz_session_role_memberships() instead
7125 -- because pg_has_role internally calls mz_role_oid_memberships(), which
7126 -- loads the full system role graph and is blocked in restricted sessions.
7127 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
7128 END"#,
7129 access: vec![PUBLIC_SELECT],
7130 ontology: None,
7131});
7132
7133pub static MZ_SHOW_ALL_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7134 name: "mz_show_all_privileges",
7135 schema: MZ_INTERNAL_SCHEMA,
7136 oid: oid::VIEW_MZ_SHOW_ALL_PRIVILEGES_OID,
7137 desc: RelationDesc::builder()
7138 .with_column("grantor", SqlScalarType::String.nullable(true))
7139 .with_column("grantee", SqlScalarType::String.nullable(true))
7140 .with_column("database", SqlScalarType::String.nullable(true))
7141 .with_column("schema", SqlScalarType::String.nullable(true))
7142 .with_column("name", SqlScalarType::String.nullable(true))
7143 .with_column("object_type", SqlScalarType::String.nullable(false))
7144 .with_column("privilege_type", SqlScalarType::String.nullable(false))
7145 .finish(),
7146 column_comments: BTreeMap::from_iter([
7147 ("grantor", "The role that granted the privilege."),
7148 ("grantee", "The role that the privilege was granted to."),
7149 (
7150 "database",
7151 "The name of the database containing the object.",
7152 ),
7153 ("schema", "The name of the schema containing the object."),
7154 ("name", "The name of the privilege target."),
7155 (
7156 "object_type",
7157 "The type of object the privilege is granted on.",
7158 ),
7159 ("privilege_type", "They type of privilege granted."),
7160 ]),
7161 sql: r#"SELECT grantor, grantee, NULL AS database, NULL AS schema, NULL AS name, 'system' AS object_type, privilege_type
7162FROM mz_internal.mz_show_system_privileges
7163UNION ALL
7164SELECT grantor, grantee, NULL AS database, NULL AS schema, name, 'cluster' AS object_type, privilege_type
7165FROM mz_internal.mz_show_cluster_privileges
7166UNION ALL
7167SELECT grantor, grantee, NULL AS database, NULL AS schema, name, 'database' AS object_type, privilege_type
7168FROM mz_internal.mz_show_database_privileges
7169UNION ALL
7170SELECT grantor, grantee, database, NULL AS schema, name, 'schema' AS object_type, privilege_type
7171FROM mz_internal.mz_show_schema_privileges
7172UNION ALL
7173SELECT grantor, grantee, database, schema, name, object_type, privilege_type
7174FROM mz_internal.mz_show_object_privileges"#,
7175 access: vec![PUBLIC_SELECT],
7176 ontology: None,
7177});
7178
7179pub static MZ_SHOW_ALL_MY_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7180 name: "mz_show_all_my_privileges",
7181 schema: MZ_INTERNAL_SCHEMA,
7182 oid: oid::VIEW_MZ_SHOW_ALL_MY_PRIVILEGES_OID,
7183 desc: RelationDesc::builder()
7184 .with_column("grantor", SqlScalarType::String.nullable(true))
7185 .with_column("grantee", SqlScalarType::String.nullable(true))
7186 .with_column("database", SqlScalarType::String.nullable(true))
7187 .with_column("schema", SqlScalarType::String.nullable(true))
7188 .with_column("name", SqlScalarType::String.nullable(true))
7189 .with_column("object_type", SqlScalarType::String.nullable(false))
7190 .with_column("privilege_type", SqlScalarType::String.nullable(false))
7191 .finish(),
7192 column_comments: BTreeMap::from_iter([
7193 ("grantor", "The role that granted the privilege."),
7194 ("grantee", "The role that the privilege was granted to."),
7195 (
7196 "database",
7197 "The name of the database containing the object.",
7198 ),
7199 ("schema", "The name of the schema containing the object."),
7200 ("name", "The name of the privilege target."),
7201 (
7202 "object_type",
7203 "The type of object the privilege is granted on.",
7204 ),
7205 ("privilege_type", "They type of privilege granted."),
7206 ]),
7207 sql: r#"SELECT grantor, grantee, database, schema, name, object_type, privilege_type
7208FROM mz_internal.mz_show_all_privileges
7209WHERE
7210 CASE
7211 WHEN grantee = 'PUBLIC' THEN true
7212 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
7213 -- whether the current user holds role `grantee`. For a nonexistent grantee
7214 -- name, both return false. We use mz_session_role_memberships() instead
7215 -- because pg_has_role internally calls mz_role_oid_memberships(), which
7216 -- loads the full system role graph and is blocked in restricted sessions.
7217 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
7218 END"#,
7219 access: vec![PUBLIC_SELECT],
7220 ontology: None,
7221});
7222
7223pub static MZ_SHOW_DEFAULT_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7224 name: "mz_show_default_privileges",
7225 schema: MZ_INTERNAL_SCHEMA,
7226 oid: oid::VIEW_MZ_SHOW_DEFAULT_PRIVILEGES_OID,
7227 desc: RelationDesc::builder()
7228 .with_column("object_owner", SqlScalarType::String.nullable(true))
7229 .with_column("database", SqlScalarType::String.nullable(true))
7230 .with_column("schema", SqlScalarType::String.nullable(true))
7231 .with_column("object_type", SqlScalarType::String.nullable(false))
7232 .with_column("grantee", SqlScalarType::String.nullable(true))
7233 .with_column("privilege_type", SqlScalarType::String.nullable(true))
7234 .finish(),
7235 column_comments: BTreeMap::from_iter([
7236 (
7237 "object_owner",
7238 "Privileges described in this row will be granted on objects created by `object_owner`.",
7239 ),
7240 (
7241 "database",
7242 "Privileges described in this row will be granted only on objects created in `database` if non-null.",
7243 ),
7244 (
7245 "schema",
7246 "Privileges described in this row will be granted only on objects created in `schema` if non-null.",
7247 ),
7248 (
7249 "object_type",
7250 "Privileges described in this row will be granted only on objects of type `object_type`.",
7251 ),
7252 (
7253 "grantee",
7254 "Privileges described in this row will be granted to `grantee`.",
7255 ),
7256 ("privilege_type", "They type of privilege to be granted."),
7257 ]),
7258 sql: r#"SELECT
7259 CASE defaults.role_id
7260 WHEN 'p' THEN 'PUBLIC'
7261 ELSE object_owner.name
7262 END AS object_owner,
7263 databases.name AS database,
7264 schemas.name AS schema,
7265 object_type,
7266 CASE defaults.grantee
7267 WHEN 'p' THEN 'PUBLIC'
7268 ELSE grantee.name
7269 END AS grantee,
7270 unnest(mz_internal.mz_format_privileges(defaults.privileges)) AS privilege_type
7271FROM mz_catalog.mz_default_privileges defaults
7272LEFT JOIN mz_catalog.mz_roles AS object_owner ON defaults.role_id = object_owner.id
7273LEFT JOIN mz_catalog.mz_roles AS grantee ON defaults.grantee = grantee.id
7274LEFT JOIN mz_catalog.mz_databases AS databases ON defaults.database_id = databases.id
7275LEFT JOIN mz_catalog.mz_schemas AS schemas ON defaults.schema_id = schemas.id
7276WHERE defaults.grantee NOT LIKE 's%'
7277 AND defaults.database_id IS NULL OR defaults.database_id NOT LIKE 's%'
7278 AND defaults.schema_id IS NULL OR defaults.schema_id NOT LIKE 's%'"#,
7279 access: vec![PUBLIC_SELECT],
7280 ontology: None,
7281});
7282
7283pub static MZ_SHOW_MY_DEFAULT_PRIVILEGES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7284 name: "mz_show_my_default_privileges",
7285 schema: MZ_INTERNAL_SCHEMA,
7286 oid: oid::VIEW_MZ_SHOW_MY_DEFAULT_PRIVILEGES_OID,
7287 desc: RelationDesc::builder()
7288 .with_column("object_owner", SqlScalarType::String.nullable(true))
7289 .with_column("database", SqlScalarType::String.nullable(true))
7290 .with_column("schema", SqlScalarType::String.nullable(true))
7291 .with_column("object_type", SqlScalarType::String.nullable(false))
7292 .with_column("grantee", SqlScalarType::String.nullable(true))
7293 .with_column("privilege_type", SqlScalarType::String.nullable(true))
7294 .finish(),
7295 column_comments: BTreeMap::from_iter([
7296 (
7297 "object_owner",
7298 "Privileges described in this row will be granted on objects created by `object_owner`.",
7299 ),
7300 (
7301 "database",
7302 "Privileges described in this row will be granted only on objects created in `database` if non-null.",
7303 ),
7304 (
7305 "schema",
7306 "Privileges described in this row will be granted only on objects created in `schema` if non-null.",
7307 ),
7308 (
7309 "object_type",
7310 "Privileges described in this row will be granted only on objects of type `object_type`.",
7311 ),
7312 (
7313 "grantee",
7314 "Privileges described in this row will be granted to `grantee`.",
7315 ),
7316 ("privilege_type", "They type of privilege to be granted."),
7317 ]),
7318 sql: r#"SELECT object_owner, database, schema, object_type, grantee, privilege_type
7319FROM mz_internal.mz_show_default_privileges
7320WHERE
7321 CASE
7322 WHEN grantee = 'PUBLIC' THEN true
7323 -- Semantically equivalent to pg_has_role(grantee, 'USAGE'), which checks
7324 -- whether the current user holds role `grantee`. For a nonexistent grantee
7325 -- name, both return false. We use mz_session_role_memberships() instead
7326 -- because pg_has_role internally calls mz_role_oid_memberships(), which
7327 -- loads the full system role graph and is blocked in restricted sessions.
7328 ELSE grantee = ANY(mz_internal.mz_session_role_memberships())
7329 END"#,
7330 access: vec![PUBLIC_SELECT],
7331 ontology: None,
7332});
7333
7334pub static MZ_SHOW_NETWORK_POLICIES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7335 name: "mz_show_network_policies",
7336 schema: MZ_INTERNAL_SCHEMA,
7337 oid: oid::VIEW_MZ_SHOW_NETWORK_POLICIES_OID,
7338 desc: RelationDesc::builder()
7339 .with_column("name", SqlScalarType::String.nullable(false))
7340 .with_column("rules", SqlScalarType::String.nullable(true))
7341 .with_column("comment", SqlScalarType::String.nullable(false))
7342 .finish(),
7343 column_comments: BTreeMap::new(),
7344 sql: "
7345WITH comments AS (
7346 SELECT id, comment
7347 FROM mz_internal.mz_comments
7348 WHERE object_type = 'network-policy' AND object_sub_id IS NULL
7349)
7350SELECT
7351 policy.name,
7352 pg_catalog.string_agg(rule.name,',' ORDER BY rule.name) as rules,
7353 COALESCE(comment, '') as comment
7354FROM
7355 mz_internal.mz_network_policies as policy
7356LEFT JOIN
7357 mz_internal.mz_network_policy_rules as rule ON policy.id = rule.policy_id
7358LEFT JOIN
7359 comments ON policy.id = comments.id
7360WHERE
7361 policy.id NOT LIKE 's%'
7362AND
7363 policy.id NOT LIKE 'g%'
7364GROUP BY policy.name, comments.comment;",
7365 access: vec![PUBLIC_SELECT],
7366 ontology: None,
7367});
7368
7369pub static MZ_CLUSTER_REPLICA_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7370 name: "mz_cluster_replica_history",
7371 schema: MZ_INTERNAL_SCHEMA,
7372 oid: oid::VIEW_MZ_CLUSTER_REPLICA_HISTORY_OID,
7373 desc: RelationDesc::builder()
7374 .with_column("replica_id", SqlScalarType::String.nullable(true))
7375 .with_column("size", SqlScalarType::String.nullable(true))
7376 .with_column("cluster_id", SqlScalarType::String.nullable(true))
7377 .with_column("cluster_name", SqlScalarType::String.nullable(true))
7378 .with_column("replica_name", SqlScalarType::String.nullable(true))
7379 .with_column(
7380 "created_at",
7381 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7382 )
7383 .with_column(
7384 "dropped_at",
7385 SqlScalarType::TimestampTz { precision: None }.nullable(true),
7386 )
7387 .with_column(
7388 "credits_per_hour",
7389 SqlScalarType::Numeric { max_scale: None }.nullable(true),
7390 )
7391 .finish(),
7392 column_comments: BTreeMap::from_iter([
7393 ("replica_id", "The ID of a cluster replica."),
7394 (
7395 "size",
7396 "The size of the cluster replica. Corresponds to `mz_cluster_replica_sizes.size`.",
7397 ),
7398 (
7399 "cluster_id",
7400 "The ID of the cluster associated with the replica.",
7401 ),
7402 (
7403 "cluster_name",
7404 "The name of the cluster associated with the replica.",
7405 ),
7406 ("replica_name", "The name of the replica."),
7407 ("created_at", "The time at which the replica was created."),
7408 (
7409 "dropped_at",
7410 "The time at which the replica was dropped, or `NULL` if it still exists.",
7411 ),
7412 (
7413 "credits_per_hour",
7414 "The number of compute credits consumed per hour. Corresponds to `mz_cluster_replica_sizes.credits_per_hour`.",
7415 ),
7416 ]),
7417 sql: r#"
7418 WITH
7419 creates AS
7420 (
7421 SELECT
7422 details ->> 'logical_size' AS size,
7423 details ->> 'replica_id' AS replica_id,
7424 details ->> 'replica_name' AS replica_name,
7425 details ->> 'cluster_name' AS cluster_name,
7426 details ->> 'cluster_id' AS cluster_id,
7427 occurred_at
7428 FROM mz_catalog.mz_audit_events
7429 WHERE
7430 object_type = 'cluster-replica' AND event_type = 'create'
7431 AND
7432 details ->> 'replica_id' IS NOT NULL
7433 AND
7434 details ->> 'cluster_id' !~~ 's%'
7435 ),
7436 drops AS
7437 (
7438 SELECT details ->> 'replica_id' AS replica_id, occurred_at
7439 FROM mz_catalog.mz_audit_events
7440 WHERE object_type = 'cluster-replica' AND event_type = 'drop'
7441 )
7442 SELECT
7443 creates.replica_id,
7444 creates.size,
7445 creates.cluster_id,
7446 creates.cluster_name,
7447 creates.replica_name,
7448 creates.occurred_at AS created_at,
7449 drops.occurred_at AS dropped_at,
7450 mz_cluster_replica_sizes.credits_per_hour as credits_per_hour
7451 FROM
7452 creates
7453 LEFT JOIN drops ON creates.replica_id = drops.replica_id
7454 LEFT JOIN
7455 mz_catalog.mz_cluster_replica_sizes
7456 ON mz_cluster_replica_sizes.size = creates.size"#,
7457 access: vec![PUBLIC_SELECT],
7458 ontology: Some(Ontology {
7459 entity_name: "replica_history",
7460 description: "Historical record of replica creation/drops",
7461 links: &const { [] },
7462 column_semantic_types: &[],
7463 }),
7464});
7465
7466pub static MZ_CLUSTER_REPLICA_NAME_HISTORY: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7467 name: "mz_cluster_replica_name_history",
7468 schema: MZ_INTERNAL_SCHEMA,
7469 oid: oid::VIEW_MZ_CLUSTER_REPLICA_NAME_HISTORY_OID,
7470 desc: RelationDesc::builder()
7471 .with_column(
7472 "occurred_at",
7473 SqlScalarType::TimestampTz { precision: None }.nullable(true),
7474 )
7475 .with_column("id", SqlScalarType::String.nullable(true))
7476 .with_column("previous_name", SqlScalarType::String.nullable(true))
7477 .with_column("new_name", SqlScalarType::String.nullable(true))
7478 .finish(),
7479 column_comments: BTreeMap::from_iter([
7480 (
7481 "occurred_at",
7482 "The time at which the cluster replica was created or renamed. `NULL` if it's a built in system cluster replica.",
7483 ),
7484 ("id", "The ID of the cluster replica."),
7485 (
7486 "previous_name",
7487 "The previous name of the cluster replica. `NULL` if there was no previous name.",
7488 ),
7489 ("new_name", "The new name of the cluster replica."),
7490 ]),
7491 sql: r#"WITH user_replica_alter_history AS (
7492 SELECT occurred_at,
7493 audit_events.details->>'replica_id' AS id,
7494 audit_events.details->>'old_name' AS previous_name,
7495 audit_events.details->>'new_name' AS new_name
7496 FROM mz_catalog.mz_audit_events AS audit_events
7497 WHERE object_type = 'cluster-replica'
7498 AND audit_events.event_type = 'alter'
7499 AND audit_events.details->>'replica_id' like 'u%'
7500),
7501user_replica_create_history AS (
7502 SELECT occurred_at,
7503 audit_events.details->>'replica_id' AS id,
7504 NULL AS previous_name,
7505 audit_events.details->>'replica_name' AS new_name
7506 FROM mz_catalog.mz_audit_events AS audit_events
7507 WHERE object_type = 'cluster-replica'
7508 AND audit_events.event_type = 'create'
7509 AND audit_events.details->>'replica_id' like 'u%'
7510),
7511-- Because built in system cluster replicas don't have audit events, we need to manually add them
7512system_replicas AS (
7513 -- We assume that the system cluster replicas were created at the beginning of time
7514 SELECT NULL::timestamptz AS occurred_at,
7515 id,
7516 NULL AS previous_name,
7517 name AS new_name
7518 FROM mz_catalog.mz_cluster_replicas
7519 WHERE id LIKE 's%'
7520)
7521SELECT *
7522FROM user_replica_alter_history
7523UNION ALL
7524SELECT *
7525FROM user_replica_create_history
7526UNION ALL
7527SELECT *
7528FROM system_replicas"#,
7529 access: vec![PUBLIC_SELECT],
7530 ontology: Some(Ontology {
7531 entity_name: "replica_name_history",
7532 description: "Historical replica names",
7533 links: &const { [] },
7534 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
7535 }),
7536});
7537
7538pub static MZ_HYDRATION_STATUSES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7539 name: "mz_hydration_statuses",
7540 schema: MZ_INTERNAL_SCHEMA,
7541 oid: oid::VIEW_MZ_HYDRATION_STATUSES_OID,
7542 desc: RelationDesc::builder()
7543 .with_column("object_id", SqlScalarType::String.nullable(false))
7544 .with_column("replica_id", SqlScalarType::String.nullable(true))
7545 .with_column("hydrated", SqlScalarType::Bool.nullable(true))
7546 .finish(),
7547 column_comments: BTreeMap::from_iter([
7548 (
7549 "object_id",
7550 "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`.",
7551 ),
7552 ("replica_id", "The ID of a cluster replica."),
7553 ("hydrated", "Whether the object is hydrated on the replica."),
7554 ]),
7555 sql: r#"WITH
7556-- Joining against the linearizable catalog tables ensures that this view
7557-- always contains the set of installed objects, even when it depends
7558-- on introspection relations that may received delayed updates.
7559--
7560-- Note that this view only includes objects that are maintained by dataflows.
7561-- In particular, some source types (webhook, introspection, ...) are not and
7562-- are therefore omitted.
7563indexes AS (
7564 SELECT
7565 i.id AS object_id,
7566 h.replica_id,
7567 COALESCE(h.hydrated, false) AS hydrated
7568 FROM mz_catalog.mz_indexes i
7569 LEFT JOIN mz_internal.mz_compute_hydration_statuses h
7570 ON (h.object_id = i.id)
7571),
7572materialized_views AS (
7573 SELECT
7574 i.id AS object_id,
7575 h.replica_id,
7576 COALESCE(h.hydrated, false) AS hydrated
7577 FROM mz_catalog.mz_materialized_views i
7578 LEFT JOIN mz_internal.mz_compute_hydration_statuses h
7579 ON (h.object_id = i.id)
7580),
7581-- Hydration is a dataflow concept and not all sources are maintained by
7582-- dataflows, so we need to find the ones that are. Generally, sources that
7583-- have a cluster ID are maintained by a dataflow running on that cluster.
7584-- Webhook sources are an exception to this rule.
7585sources_with_clusters AS (
7586 SELECT id, cluster_id
7587 FROM mz_catalog.mz_sources
7588 WHERE cluster_id IS NOT NULL AND type != 'webhook'
7589),
7590sources AS (
7591 SELECT
7592 s.id AS object_id,
7593 ss.replica_id AS replica_id,
7594 ss.rehydration_latency IS NOT NULL AS hydrated
7595 FROM sources_with_clusters s
7596 LEFT JOIN mz_internal.mz_source_statistics ss USING (id)
7597),
7598-- We don't yet report sink hydration status (database-issues#8331), so we do a best effort attempt here and
7599-- define a sink as hydrated when it's both "running" and has a frontier greater than the minimum.
7600-- There is likely still a possibility of FPs.
7601sinks AS (
7602 SELECT
7603 s.id AS object_id,
7604 r.id AS replica_id,
7605 ss.status = 'running' AND COALESCE(f.write_frontier, 0) > 0 AS hydrated
7606 FROM mz_catalog.mz_sinks s
7607 LEFT JOIN mz_internal.mz_sink_statuses ss USING (id)
7608 JOIN mz_catalog.mz_cluster_replicas r
7609 ON (r.cluster_id = s.cluster_id)
7610 LEFT JOIN mz_catalog.mz_cluster_replica_frontiers f
7611 ON (f.object_id = s.id AND f.replica_id = r.id)
7612)
7613SELECT * FROM indexes
7614UNION ALL
7615SELECT * FROM materialized_views
7616UNION ALL
7617SELECT * FROM sources
7618UNION ALL
7619SELECT * FROM sinks"#,
7620 access: vec![PUBLIC_SELECT],
7621 ontology: Some(Ontology {
7622 entity_name: "hydration_status",
7623 description: "Overall hydration status per object",
7624 links: &const {
7625 [
7626 OntologyLink {
7627 name: "hydration_of",
7628 target: "object",
7629 properties: LinkProperties::fk_typed(
7630 "object_id",
7631 "id",
7632 Cardinality::OneToOne,
7633 mz_repr::SemanticType::CatalogItemId,
7634 ),
7635 },
7636 OntologyLink {
7637 name: "hydration_on_replica",
7638 target: "replica",
7639 properties: LinkProperties::fk("replica_id", "id", Cardinality::ManyToOne),
7640 },
7641 ]
7642 },
7643 column_semantic_types: &const {
7644 [
7645 ("object_id", SemanticType::CatalogItemId),
7646 ("replica_id", SemanticType::ReplicaId),
7647 ]
7648 },
7649 }),
7650});
7651
7652pub const MZ_HYDRATION_STATUSES_IND: BuiltinIndex = BuiltinIndex {
7653 name: "mz_hydration_statuses_ind",
7654 schema: MZ_INTERNAL_SCHEMA,
7655 oid: oid::INDEX_MZ_HYDRATION_STATUSES_IND_OID,
7656 sql: "IN CLUSTER mz_catalog_server
7657ON mz_internal.mz_hydration_statuses (object_id, replica_id)",
7658 is_retained_metrics_object: false,
7659};
7660
7661pub static MZ_MATERIALIZATION_DEPENDENCIES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7662 name: "mz_materialization_dependencies",
7663 schema: MZ_INTERNAL_SCHEMA,
7664 oid: oid::VIEW_MZ_MATERIALIZATION_DEPENDENCIES_OID,
7665 desc: RelationDesc::builder()
7666 .with_column("object_id", SqlScalarType::String.nullable(false))
7667 .with_column("dependency_id", SqlScalarType::String.nullable(false))
7668 .finish(),
7669 column_comments: BTreeMap::from_iter([
7670 (
7671 "object_id",
7672 "The ID of a materialization. Corresponds to `mz_catalog.mz_indexes.id`, `mz_catalog.mz_materialized_views.id`, or `mz_catalog.mz_sinks.id`.",
7673 ),
7674 (
7675 "dependency_id",
7676 "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`.",
7677 ),
7678 ]),
7679 sql: "
7680SELECT object_id, dependency_id
7681FROM mz_internal.mz_compute_dependencies
7682UNION ALL
7683SELECT s.id, d.referenced_object_id AS dependency_id
7684FROM mz_internal.mz_object_dependencies d
7685JOIN mz_catalog.mz_sinks s ON (s.id = d.object_id)
7686JOIN mz_catalog.mz_relations r ON (r.id = d.referenced_object_id)",
7687 access: vec![PUBLIC_SELECT],
7688 ontology: Some(Ontology {
7689 entity_name: "materialization_dep",
7690 description: "Dependencies between materializations",
7691 links: &const {
7692 [
7693 OntologyLink {
7694 name: "depends_on",
7695 target: "object",
7696 properties: LinkProperties::DependsOn {
7697 source_column: "object_id",
7698 target_column: "id",
7699 source_id_type: Some(mz_repr::SemanticType::CatalogItemId),
7700 requires_mapping: None,
7701 },
7702 },
7703 OntologyLink {
7704 name: "dependency_is",
7705 target: "object",
7706 properties: LinkProperties::fk("dependency_id", "id", Cardinality::ManyToOne),
7707 },
7708 ]
7709 },
7710 column_semantic_types: &const {
7711 [
7712 ("object_id", SemanticType::CatalogItemId),
7713 ("dependency_id", SemanticType::CatalogItemId),
7714 ]
7715 },
7716 }),
7717});
7718
7719pub static MZ_MATERIALIZATION_LAG: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
7720 name: "mz_materialization_lag",
7721 schema: MZ_INTERNAL_SCHEMA,
7722 oid: oid::VIEW_MZ_MATERIALIZATION_LAG_OID,
7723 desc: RelationDesc::builder()
7724 .with_column("object_id", SqlScalarType::String.nullable(false))
7725 .with_column("local_lag", SqlScalarType::Interval.nullable(true))
7726 .with_column("global_lag", SqlScalarType::Interval.nullable(true))
7727 .with_column(
7728 "slowest_local_input_id",
7729 SqlScalarType::String.nullable(false),
7730 )
7731 .with_column(
7732 "slowest_global_input_id",
7733 SqlScalarType::String.nullable(false),
7734 )
7735 .finish(),
7736 column_comments: BTreeMap::from_iter([
7737 (
7738 "object_id",
7739 "The ID of the materialized view, index, or sink.",
7740 ),
7741 (
7742 "local_lag",
7743 "The amount of time the materialization lags behind its direct inputs.",
7744 ),
7745 (
7746 "global_lag",
7747 "The amount of time the materialization lags behind its root inputs (sources and tables).",
7748 ),
7749 (
7750 "slowest_local_input_id",
7751 "The ID of the slowest direct input.",
7752 ),
7753 (
7754 "slowest_global_input_id",
7755 "The ID of the slowest root input.",
7756 ),
7757 ]),
7758 sql: "
7759WITH MUTUALLY RECURSIVE
7760 -- IDs of objects for which we want to know the lag.
7761 materializations (id text) AS (
7762 SELECT id FROM mz_catalog.mz_indexes
7763 UNION ALL
7764 SELECT id FROM mz_catalog.mz_materialized_views
7765 UNION ALL
7766 SELECT id FROM mz_catalog.mz_sinks
7767 ),
7768 -- Direct dependencies of materializations.
7769 direct_dependencies (id text, dep_id text) AS (
7770 SELECT m.id, d.dependency_id
7771 FROM materializations m
7772 JOIN mz_internal.mz_materialization_dependencies d ON (m.id = d.object_id)
7773 ),
7774 -- All transitive dependencies of materializations.
7775 transitive_dependencies (id text, dep_id text) AS (
7776 SELECT id, dep_id FROM direct_dependencies
7777 UNION
7778 SELECT td.id, dd.dep_id
7779 FROM transitive_dependencies td
7780 JOIN direct_dependencies dd ON (dd.id = td.dep_id)
7781 ),
7782 -- Root dependencies of materializations (sources and tables).
7783 root_dependencies (id text, dep_id text) AS (
7784 SELECT *
7785 FROM transitive_dependencies td
7786 WHERE NOT EXISTS (
7787 SELECT 1
7788 FROM direct_dependencies dd
7789 WHERE dd.id = td.dep_id
7790 )
7791 ),
7792 -- Write progress times of materializations.
7793 materialization_times (id text, time timestamptz) AS (
7794 SELECT m.id, to_timestamp(f.write_frontier::text::double / 1000)
7795 FROM materializations m
7796 JOIN mz_internal.mz_frontiers f ON (m.id = f.object_id)
7797 ),
7798 -- Write progress times of direct dependencies of materializations.
7799 input_times (id text, slowest_dep text, time timestamptz) AS (
7800 SELECT DISTINCT ON (d.id)
7801 d.id,
7802 d.dep_id,
7803 to_timestamp(f.write_frontier::text::double / 1000)
7804 FROM direct_dependencies d
7805 JOIN mz_internal.mz_frontiers f ON (d.dep_id = f.object_id)
7806 ORDER BY d.id, f.write_frontier ASC
7807 ),
7808 -- Write progress times of root dependencies of materializations.
7809 root_times (id text, slowest_dep text, time timestamptz) AS (
7810 SELECT DISTINCT ON (d.id)
7811 d.id,
7812 d.dep_id,
7813 to_timestamp(f.write_frontier::text::double / 1000)
7814 FROM root_dependencies d
7815 JOIN mz_internal.mz_frontiers f ON (d.dep_id = f.object_id)
7816 ORDER BY d.id, f.write_frontier ASC
7817 )
7818SELECT
7819 id AS object_id,
7820 -- Ensure that lag values are always NULL for materializations that have reached the empty
7821 -- frontier, as those have processed all their input data.
7822 -- Also make sure that lag values are never negative, even when input frontiers are before
7823 -- output frontiers (as can happen during hydration).
7824 CASE
7825 WHEN m.time IS NULL THEN INTERVAL '0'
7826 WHEN i.time IS NULL THEN NULL
7827 ELSE greatest(i.time - m.time, INTERVAL '0')
7828 END AS local_lag,
7829 CASE
7830 WHEN m.time IS NULL THEN INTERVAL '0'
7831 WHEN r.time IS NULL THEN NULL
7832 ELSE greatest(r.time - m.time, INTERVAL '0')
7833 END AS global_lag,
7834 i.slowest_dep AS slowest_local_input_id,
7835 r.slowest_dep AS slowest_global_input_id
7836FROM materialization_times m
7837JOIN input_times i USING (id)
7838JOIN root_times r USING (id)",
7839 access: vec![PUBLIC_SELECT],
7840 ontology: Some(Ontology {
7841 entity_name: "materialization_lag",
7842 description: "Lag between a materialization and its inputs",
7843 links: &const {
7844 [
7845 OntologyLink {
7846 name: "measures_materialization_lag",
7847 target: "object",
7848 properties: LinkProperties::measures("object_id", "id", "materialization_lag"),
7849 },
7850 OntologyLink {
7851 name: "slowest_local_input",
7852 target: "object",
7853 properties: LinkProperties::fk(
7854 "slowest_local_input_id",
7855 "id",
7856 Cardinality::ManyToOne,
7857 ),
7858 },
7859 OntologyLink {
7860 name: "slowest_global_input",
7861 target: "object",
7862 properties: LinkProperties::fk(
7863 "slowest_global_input_id",
7864 "id",
7865 Cardinality::ManyToOne,
7866 ),
7867 },
7868 ]
7869 },
7870 column_semantic_types: &const {
7871 [
7872 ("object_id", SemanticType::CatalogItemId),
7873 ("slowest_local_input_id", SemanticType::CatalogItemId),
7874 ("slowest_global_input_id", SemanticType::CatalogItemId),
7875 ]
7876 },
7877 }),
7878});
7879fn console_cluster_utilization_overview_desc() -> RelationDesc {
7883 RelationDesc::builder()
7884 .with_column(
7885 "bucket_start",
7886 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7887 )
7888 .with_column("replica_id", SqlScalarType::String.nullable(false))
7889 .with_column("memory_percent", SqlScalarType::Float64.nullable(true))
7890 .with_column(
7891 "max_memory_at",
7892 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7893 )
7894 .with_column("disk_percent", SqlScalarType::Float64.nullable(true))
7895 .with_column(
7896 "max_disk_at",
7897 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7898 )
7899 .with_column(
7900 "memory_and_disk_percent",
7901 SqlScalarType::Float64.nullable(true),
7902 )
7903 .with_column(
7904 "max_memory_and_disk_memory_percent",
7905 SqlScalarType::Float64.nullable(true),
7906 )
7907 .with_column(
7908 "max_memory_and_disk_disk_percent",
7909 SqlScalarType::Float64.nullable(true),
7910 )
7911 .with_column(
7912 "max_memory_and_disk_at",
7913 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7914 )
7915 .with_column("heap_percent", SqlScalarType::Float64.nullable(true))
7916 .with_column(
7917 "max_heap_at",
7918 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7919 )
7920 .with_column("max_cpu_percent", SqlScalarType::Float64.nullable(true))
7921 .with_column(
7922 "max_cpu_at",
7923 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7924 )
7925 .with_column("offline_events", SqlScalarType::Jsonb.nullable(true))
7926 .with_column(
7927 "bucket_end",
7928 SqlScalarType::TimestampTz { precision: None }.nullable(false),
7929 )
7930 .with_column("name", SqlScalarType::String.nullable(true))
7931 .with_column("cluster_id", SqlScalarType::String.nullable(true))
7932 .with_column("size", SqlScalarType::String.nullable(true))
7933 .finish()
7934}
7935
7936fn console_cluster_utilization_overview_sql(bin: &str, retention: &str, group_size: u32) -> String {
7953 format!(
7954 r#"WITH replica_history AS (
7955 SELECT replica_id, size, cluster_id
7956 FROM mz_internal.mz_cluster_replica_history
7957 UNION
7958 -- We union the current set of cluster replicas since mz_cluster_replica_history doesn't include system clusters.
7959 SELECT id AS replica_id, size, cluster_id
7960 FROM mz_catalog.mz_cluster_replicas
7961),
7962replica_metrics_history AS (
7963 SELECT
7964 m.occurred_at,
7965 m.replica_id,
7966 r.size,
7967 (SUM(m.cpu_nano_cores::float8) / NULLIF(s.cpu_nano_cores, 0) / NULLIF(s.processes, 0)) AS cpu_percent,
7968 (SUM(m.memory_bytes::float8) / NULLIF(s.memory_bytes, 0) / NULLIF(s.processes, 0)) AS memory_percent,
7969 (SUM(m.disk_bytes::float8) / NULLIF(s.disk_bytes, 0) / NULLIF(s.processes, 0)) AS disk_percent,
7970 SUM(m.disk_bytes::float8) AS disk_bytes,
7971 SUM(m.memory_bytes::float8) AS memory_bytes,
7972 s.disk_bytes::float8 * s.processes AS total_disk_bytes,
7973 s.memory_bytes::float8 * s.processes AS total_memory_bytes,
7974 MAX(m.heap_bytes::float8) AS heap_bytes,
7975 MAX(m.heap_limit) AS heap_limit,
7976 -- heap_limit is NULL when clusterd isn't launched with --heap-limit (e.g.
7977 -- the emulator's process orchestrator). Fall back to the size-based memory
7978 -- percent so the chart still renders.
7979 COALESCE(
7980 MAX(m.heap_bytes::float8 / NULLIF(m.heap_limit, 0)),
7981 SUM(m.memory_bytes::float8) / NULLIF(s.memory_bytes, 0) / NULLIF(s.processes, 0)
7982 ) AS heap_percent
7983 FROM
7984 replica_history AS r
7985 INNER JOIN mz_catalog.mz_cluster_replica_sizes AS s ON r.size = s.size
7986 INNER JOIN mz_internal.mz_cluster_replica_metrics_history AS m ON m.replica_id = r.replica_id
7987 GROUP BY
7988 m.occurred_at,
7989 m.replica_id,
7990 r.size,
7991 s.cpu_nano_cores,
7992 s.memory_bytes,
7993 s.disk_bytes,
7994 s.processes
7995),
7996replica_utilization_history_binned AS (
7997 -- NOTE: we read directly from replica_metrics_history rather than re-joining
7998 -- replica_history; every replica_id here already came from replica_history,
7999 -- so the join was redundant (and could fan out a replica that changed size).
8000 SELECT
8001 m.occurred_at,
8002 m.replica_id,
8003 m.cpu_percent,
8004 m.memory_percent,
8005 m.memory_bytes,
8006 m.disk_percent,
8007 m.disk_bytes,
8008 m.total_disk_bytes,
8009 m.total_memory_bytes,
8010 m.heap_bytes,
8011 m.heap_percent,
8012 m.size,
8013 date_bin('{bin}', m.occurred_at, '1970-01-01'::timestamp) AS bucket_start
8014 FROM replica_metrics_history AS m
8015 WHERE mz_now() <= date_bin('{bin}', m.occurred_at, '1970-01-01'::timestamp) + INTERVAL '{retention}'
8016),
8017-- For each (replica, bucket), take the sample with the highest memory.
8018max_memory AS (
8019 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, memory_percent, occurred_at
8020 FROM replica_utilization_history_binned
8021 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
8022 ORDER BY bucket_start, replica_id, COALESCE(memory_bytes, 0) DESC
8023),
8024-- For each (replica, bucket), take the sample with the highest disk.
8025max_disk AS (
8026 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, disk_percent, occurred_at
8027 FROM replica_utilization_history_binned
8028 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
8029 ORDER BY bucket_start, replica_id, COALESCE(disk_bytes, 0) DESC
8030),
8031-- For each (replica, bucket), take the sample with the highest cpu.
8032max_cpu AS (
8033 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, cpu_percent, occurred_at
8034 FROM replica_utilization_history_binned
8035 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
8036 ORDER BY bucket_start, replica_id, COALESCE(cpu_percent, 0) DESC
8037),
8038/*
8039 For each (replica, bucket), take the sample with the highest combined memory
8040 and disk. This is different from adding max_memory and max_disk per bucket
8041 because both values may not occur at the same time if the bucket interval is
8042 large.
8043*/
8044max_memory_and_disk AS (
8045 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, memory_percent, disk_percent, memory_and_disk_percent, occurred_at
8046 FROM (
8047 SELECT *,
8048 CASE
8049 WHEN disk_bytes IS NULL AND memory_bytes IS NULL THEN NULL
8050 ELSE (COALESCE(memory_bytes, 0) + COALESCE(disk_bytes, 0)) / NULLIF((total_memory_bytes + total_disk_bytes), 0)
8051 END AS memory_and_disk_percent
8052 FROM replica_utilization_history_binned
8053 ) AS max_memory_and_disk_inner
8054 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
8055 ORDER BY bucket_start, replica_id, COALESCE(memory_and_disk_percent, 0) DESC
8056),
8057-- For each (replica, bucket), take the sample with the highest heap.
8058max_heap AS (
8059 SELECT DISTINCT ON (bucket_start, replica_id) bucket_start, replica_id, heap_percent, occurred_at
8060 FROM replica_utilization_history_binned
8061 OPTIONS (DISTINCT ON INPUT GROUP SIZE = {group_size})
8062 ORDER BY bucket_start, replica_id, COALESCE(heap_bytes, 0) DESC
8063),
8064-- For each (replica, bucket), collect its offline events at that time.
8065replica_offline_event_history AS (
8066 SELECT
8067 date_bin('{bin}', occurred_at, '1970-01-01'::timestamp) AS bucket_start,
8068 replica_id,
8069 jsonb_agg(
8070 jsonb_build_object(
8071 'replicaId', rsh.replica_id,
8072 'occurredAt', rsh.occurred_at,
8073 'status', rsh.status,
8074 'reason', rsh.reason
8075 )
8076 ) AS offline_events
8077 FROM mz_internal.mz_cluster_replica_status_history AS rsh
8078 -- We assume the statuses for process 0 are the same as all processes.
8079 WHERE process_id = '0'
8080 AND status = 'offline'
8081 AND mz_now() <= date_bin('{bin}', occurred_at, '1970-01-01'::timestamp) + INTERVAL '{retention}'
8082 GROUP BY bucket_start, replica_id
8083)
8084SELECT
8085 bucket_start,
8086 replica_id,
8087 max_memory.memory_percent,
8088 max_memory.occurred_at AS max_memory_at,
8089 max_disk.disk_percent,
8090 max_disk.occurred_at AS max_disk_at,
8091 max_memory_and_disk.memory_and_disk_percent AS memory_and_disk_percent,
8092 max_memory_and_disk.memory_percent AS max_memory_and_disk_memory_percent,
8093 max_memory_and_disk.disk_percent AS max_memory_and_disk_disk_percent,
8094 max_memory_and_disk.occurred_at AS max_memory_and_disk_at,
8095 max_heap.heap_percent,
8096 max_heap.occurred_at AS max_heap_at,
8097 max_cpu.cpu_percent AS max_cpu_percent,
8098 max_cpu.occurred_at AS max_cpu_at,
8099 replica_offline_event_history.offline_events,
8100 bucket_start + INTERVAL '{bin}' AS bucket_end,
8101 replica_name_history.new_name AS name,
8102 replica_history.cluster_id,
8103 replica_history.size
8104FROM max_memory
8105JOIN max_disk USING (bucket_start, replica_id)
8106JOIN max_cpu USING (bucket_start, replica_id)
8107JOIN max_memory_and_disk USING (bucket_start, replica_id)
8108JOIN max_heap USING (bucket_start, replica_id)
8109JOIN replica_history USING (replica_id)
8110/*
8111 TOP k=1 over the name history via a LATERAL subquery + LIMIT: for each bucket,
8112 get the most recent replica name as of the end of the bucket.
8113*/
8114CROSS JOIN LATERAL (
8115 SELECT new_name
8116 FROM mz_internal.mz_cluster_replica_name_history AS replica_name_history
8117 WHERE replica_id = replica_name_history.id
8118 -- We treat NULLs as the beginning of time.
8119 AND bucket_start + INTERVAL '{bin}' >= COALESCE(replica_name_history.occurred_at, '1970-01-01'::timestamp)
8120 ORDER BY replica_name_history.occurred_at DESC
8121 LIMIT 1
8122) AS replica_name_history
8123LEFT JOIN replica_offline_event_history USING (bucket_start, replica_id)"#,
8124 bin = bin,
8125 retention = retention,
8126 group_size = group_size,
8127 )
8128}
8129
8130fn console_cluster_utilization_unbinned_3h_desc() -> RelationDesc {
8134 RelationDesc::builder()
8135 .with_column("replica_id", SqlScalarType::String.nullable(false))
8136 .with_column("cluster_id", SqlScalarType::String.nullable(true))
8137 .with_column("size", SqlScalarType::String.nullable(false))
8138 .with_column("name", SqlScalarType::String.nullable(true))
8139 .with_column(
8140 "occurred_at",
8141 SqlScalarType::TimestampTz { precision: None }.nullable(false),
8142 )
8143 .with_column("cpu_percent", SqlScalarType::Float64.nullable(true))
8144 .with_column("memory_percent", SqlScalarType::Float64.nullable(true))
8145 .with_column("disk_percent", SqlScalarType::Float64.nullable(true))
8146 .with_column("heap_percent", SqlScalarType::Float64.nullable(true))
8147 .with_column(
8148 "memory_and_disk_percent",
8149 SqlScalarType::Float64.nullable(true),
8150 )
8151 .finish()
8152}
8153
8154fn console_cluster_utilization_unbinned_3h_sql(retention: &str) -> String {
8162 format!(
8163 r#"WITH replica_history AS (
8164 -- Dedup to one row per replica (prefer the current size). Size is fixed per
8165 -- replica so this is normally a no-op, but a stray duplicate size in history
8166 -- would fan out the metrics join; with no Top-1 dedup here that would emit two
8167 -- rows per (replica_id, occurred_at) and break the Console SUBSCRIBE upsert key.
8168 SELECT DISTINCT ON (replica_id) replica_id, size, cluster_id
8169 FROM (
8170 -- We union the current set of cluster replicas since mz_cluster_replica_history doesn't include system clusters.
8171 SELECT id AS replica_id, size, cluster_id, 0 AS source_rank
8172 FROM mz_catalog.mz_cluster_replicas
8173 UNION ALL
8174 SELECT replica_id, size, cluster_id, 1 AS source_rank
8175 FROM mz_internal.mz_cluster_replica_history
8176 ) all_replicas
8177 ORDER BY replica_id, source_rank
8178),
8179replica_metrics AS (
8180 SELECT
8181 m.occurred_at,
8182 m.replica_id,
8183 r.cluster_id,
8184 r.size,
8185 (SUM(m.cpu_nano_cores::float8) / NULLIF(s.cpu_nano_cores, 0) / NULLIF(s.processes, 0)) AS cpu_percent,
8186 (SUM(m.memory_bytes::float8) / NULLIF(s.memory_bytes, 0) / NULLIF(s.processes, 0)) AS memory_percent,
8187 (SUM(m.disk_bytes::float8) / NULLIF(s.disk_bytes, 0) / NULLIF(s.processes, 0)) AS disk_percent,
8188 COALESCE(
8189 MAX(m.heap_bytes::float8 / NULLIF(m.heap_limit, 0)),
8190 SUM(m.memory_bytes::float8) / NULLIF(s.memory_bytes, 0) / NULLIF(s.processes, 0)
8191 ) AS heap_percent,
8192 CASE
8193 WHEN SUM(m.disk_bytes::float8) IS NULL AND SUM(m.memory_bytes::float8) IS NULL THEN NULL
8194 ELSE (COALESCE(SUM(m.memory_bytes::float8), 0) + COALESCE(SUM(m.disk_bytes::float8), 0))
8195 / NULLIF((s.memory_bytes::float8 + s.disk_bytes::float8) * s.processes, 0)
8196 END AS memory_and_disk_percent
8197 FROM replica_history AS r
8198 INNER JOIN mz_catalog.mz_cluster_replica_sizes AS s ON r.size = s.size
8199 INNER JOIN mz_internal.mz_cluster_replica_metrics_history AS m ON m.replica_id = r.replica_id
8200 -- No aggregation over time: one row per (replica, sample) so the Console bins
8201 -- client-side. The temporal mz_now() filter keeps the maintained arrangement
8202 -- bounded to the retention window.
8203 WHERE mz_now() <= m.occurred_at + INTERVAL '{retention}'
8204 GROUP BY
8205 m.occurred_at,
8206 m.replica_id,
8207 r.cluster_id,
8208 r.size,
8209 s.cpu_nano_cores,
8210 s.memory_bytes,
8211 s.disk_bytes,
8212 s.processes
8213)
8214SELECT
8215 m.replica_id,
8216 m.cluster_id,
8217 m.size,
8218 replica_name_history.new_name AS name,
8219 m.occurred_at,
8220 m.cpu_percent,
8221 m.memory_percent,
8222 m.disk_percent,
8223 m.heap_percent,
8224 m.memory_and_disk_percent
8225FROM replica_metrics AS m
8226/* Most recent replica name as of the sample time. */
8227CROSS JOIN LATERAL (
8228 SELECT new_name
8229 FROM mz_internal.mz_cluster_replica_name_history AS replica_name_history
8230 WHERE m.replica_id = replica_name_history.id
8231 -- We treat NULLs as the beginning of time.
8232 AND m.occurred_at >= COALESCE(replica_name_history.occurred_at, '1970-01-01'::timestamp)
8233 ORDER BY replica_name_history.occurred_at DESC
8234 LIMIT 1
8235) AS replica_name_history"#,
8236 retention = retention,
8237 )
8238}
8239
8240pub static MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW: LazyLock<BuiltinView> =
8247 LazyLock::new(|| BuiltinView {
8248 name: "mz_console_cluster_utilization_overview",
8249 schema: MZ_INTERNAL_SCHEMA,
8250 oid: oid::VIEW_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_OID,
8251 desc: console_cluster_utilization_overview_desc(),
8252 column_comments: BTreeMap::new(),
8253 sql: Box::leak(
8254 console_cluster_utilization_overview_sql("1 HOUR", "14 DAYS", 60).into_boxed_str(),
8255 ),
8256 access: vec![PUBLIC_SELECT],
8257 ontology: None,
8258 });
8259
8260pub static MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_3H: LazyLock<BuiltinView> =
8267 LazyLock::new(|| BuiltinView {
8268 name: "mz_console_cluster_utilization_overview_3h",
8269 schema: MZ_INTERNAL_SCHEMA,
8270 oid: oid::VIEW_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_3H_OID,
8271 desc: console_cluster_utilization_unbinned_3h_desc(),
8272 column_comments: BTreeMap::new(),
8273 sql: Box::leak(console_cluster_utilization_unbinned_3h_sql("3 HOURS").into_boxed_str()),
8274 access: vec![PUBLIC_SELECT],
8275 ontology: None,
8276 });
8277
8278pub static MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_24H: LazyLock<BuiltinView> =
8284 LazyLock::new(|| BuiltinView {
8285 name: "mz_console_cluster_utilization_overview_24h",
8286 schema: MZ_INTERNAL_SCHEMA,
8287 oid: oid::VIEW_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_24H_OID,
8288 desc: console_cluster_utilization_overview_desc(),
8289 column_comments: BTreeMap::new(),
8290 sql: Box::leak(
8291 console_cluster_utilization_overview_sql("5 MINUTES", "24 HOURS", 5).into_boxed_str(),
8292 ),
8293 access: vec![PUBLIC_SELECT],
8294 ontology: None,
8295 });
8296pub static MZ_CLUSTER_DEPLOYMENT_LINEAGE: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
8318 name: "mz_cluster_deployment_lineage",
8319 schema: MZ_INTERNAL_SCHEMA,
8320 oid: oid::VIEW_MZ_CLUSTER_DEPLOYMENT_LINEAGE_OID,
8321 desc: RelationDesc::builder()
8322 .with_column("cluster_id", SqlScalarType::String.nullable(true))
8323 .with_column(
8324 "current_deployment_cluster_id",
8325 SqlScalarType::String.nullable(false),
8326 )
8327 .with_column("cluster_name", SqlScalarType::String.nullable(false))
8328 .with_key(vec![0, 1, 2])
8329 .finish(),
8330 column_comments: BTreeMap::from_iter([
8331 (
8332 "cluster_id",
8333 "The ID of the cluster. Corresponds to `mz_clusters.id` (though the cluster may no longer exist).",
8334 ),
8335 (
8336 "current_deployment_cluster_id",
8337 "The cluster ID of the last cluster in `cluster_id`'s blue/green lineage (the cluster is guaranteed to exist).",
8338 ),
8339 ("cluster_name", "The name of the cluster"),
8340 ]),
8341 sql: r#"WITH MUTUALLY RECURSIVE cluster_events (
8342 cluster_id text,
8343 cluster_name text,
8344 event_type text,
8345 occurred_at timestamptz
8346) AS (
8347 SELECT coalesce(details->>'id', details->>'cluster_id') AS cluster_id,
8348 coalesce(details->>'name', details->>'new_name') AS cluster_name,
8349 event_type,
8350 occurred_at
8351 FROM mz_audit_events
8352 WHERE (
8353 event_type IN ('create', 'drop')
8354 OR (
8355 event_type = 'alter'
8356 AND details ? 'new_name'
8357 )
8358 )
8359 AND object_type = 'cluster'
8360 AND mz_now() < occurred_at + INTERVAL '30 days'
8361),
8362mz_cluster_deployment_lineage (
8363 cluster_id text,
8364 current_deployment_cluster_id text,
8365 cluster_name text
8366) AS (
8367 SELECT c.id,
8368 c.id,
8369 c.name
8370 FROM mz_clusters c
8371 WHERE c.id LIKE 'u%'
8372 UNION
8373 SELECT *
8374 FROM dropped_clusters
8375),
8376-- Closest create or rename event based on the current clusters in the result set
8377most_recent_create_or_rename (
8378 cluster_id text,
8379 current_deployment_cluster_id text,
8380 cluster_name text,
8381 occurred_at timestamptz
8382) AS (
8383 SELECT DISTINCT ON (e.cluster_id) e.cluster_id,
8384 c.current_deployment_cluster_id,
8385 e.cluster_name,
8386 e.occurred_at
8387 FROM mz_cluster_deployment_lineage c
8388 JOIN cluster_events e ON c.cluster_id = e.cluster_id
8389 AND c.cluster_name = e.cluster_name
8390 WHERE e.event_type <> 'drop'
8391 ORDER BY e.cluster_id,
8392 e.occurred_at DESC
8393),
8394-- Clusters that were dropped most recently within 1 minute of most_recent_create_or_rename
8395dropped_clusters (
8396 cluster_id text,
8397 current_deployment_cluster_id text,
8398 cluster_name text
8399) AS (
8400 SELECT DISTINCT ON (cr.cluster_id) e.cluster_id,
8401 cr.current_deployment_cluster_id,
8402 cr.cluster_name
8403 FROM most_recent_create_or_rename cr
8404 JOIN cluster_events e ON e.occurred_at BETWEEN cr.occurred_at - interval '1 minute'
8405 AND cr.occurred_at + interval '1 minute'
8406 AND (
8407 e.cluster_name = cr.cluster_name
8408 OR e.cluster_name = cr.cluster_name || '_dbt_deploy'
8409 )
8410 WHERE e.event_type = 'drop'
8411 ORDER BY cr.cluster_id,
8412 abs(
8413 extract(
8414 epoch
8415 FROM cr.occurred_at - e.occurred_at
8416 )
8417 )
8418)
8419SELECT *
8420FROM mz_cluster_deployment_lineage"#,
8421 access: vec![PUBLIC_SELECT],
8422 ontology: Some(Ontology {
8423 entity_name: "cluster_deployment",
8424 description: "Cluster deployment lineage information",
8425 links: &const {
8426 [
8427 OntologyLink {
8428 name: "deployment_of",
8429 target: "cluster",
8430 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
8431 },
8432 OntologyLink {
8433 name: "current_deployment",
8434 target: "cluster",
8435 properties: LinkProperties::fk(
8436 "current_deployment_cluster_id",
8437 "id",
8438 Cardinality::ManyToOne,
8439 ),
8440 },
8441 ]
8442 },
8443 column_semantic_types: &[],
8444 }),
8445});
8446
8447pub const MZ_SHOW_DATABASES_IND: BuiltinIndex = BuiltinIndex {
8448 name: "mz_show_databases_ind",
8449 schema: MZ_INTERNAL_SCHEMA,
8450 oid: oid::INDEX_MZ_SHOW_DATABASES_IND_OID,
8451 sql: "IN CLUSTER mz_catalog_server
8452ON mz_internal.mz_show_databases (name)",
8453 is_retained_metrics_object: false,
8454};
8455
8456pub const MZ_SHOW_SCHEMAS_IND: BuiltinIndex = BuiltinIndex {
8457 name: "mz_show_schemas_ind",
8458 schema: MZ_INTERNAL_SCHEMA,
8459 oid: oid::INDEX_MZ_SHOW_SCHEMAS_IND_OID,
8460 sql: "IN CLUSTER mz_catalog_server
8461ON mz_internal.mz_show_schemas (database_id)",
8462 is_retained_metrics_object: false,
8463};
8464
8465pub const MZ_SHOW_CONNECTIONS_IND: BuiltinIndex = BuiltinIndex {
8466 name: "mz_show_connections_ind",
8467 schema: MZ_INTERNAL_SCHEMA,
8468 oid: oid::INDEX_MZ_SHOW_CONNECTIONS_IND_OID,
8469 sql: "IN CLUSTER mz_catalog_server
8470ON mz_internal.mz_show_connections (schema_id)",
8471 is_retained_metrics_object: false,
8472};
8473
8474pub const MZ_SHOW_TABLES_IND: BuiltinIndex = BuiltinIndex {
8475 name: "mz_show_tables_ind",
8476 schema: MZ_INTERNAL_SCHEMA,
8477 oid: oid::INDEX_MZ_SHOW_TABLES_IND_OID,
8478 sql: "IN CLUSTER mz_catalog_server
8479ON mz_internal.mz_show_tables (schema_id)",
8480 is_retained_metrics_object: false,
8481};
8482
8483pub const MZ_SHOW_SOURCES_IND: BuiltinIndex = BuiltinIndex {
8484 name: "mz_show_sources_ind",
8485 schema: MZ_INTERNAL_SCHEMA,
8486 oid: oid::INDEX_MZ_SHOW_SOURCES_IND_OID,
8487 sql: "IN CLUSTER mz_catalog_server
8488ON mz_internal.mz_show_sources (schema_id)",
8489 is_retained_metrics_object: false,
8490};
8491
8492pub const MZ_SHOW_VIEWS_IND: BuiltinIndex = BuiltinIndex {
8493 name: "mz_show_views_ind",
8494 schema: MZ_INTERNAL_SCHEMA,
8495 oid: oid::INDEX_MZ_SHOW_VIEWS_IND_OID,
8496 sql: "IN CLUSTER mz_catalog_server
8497ON mz_internal.mz_show_views (schema_id)",
8498 is_retained_metrics_object: false,
8499};
8500
8501pub const MZ_SHOW_MATERIALIZED_VIEWS_IND: BuiltinIndex = BuiltinIndex {
8502 name: "mz_show_materialized_views_ind",
8503 schema: MZ_INTERNAL_SCHEMA,
8504 oid: oid::INDEX_MZ_SHOW_MATERIALIZED_VIEWS_IND_OID,
8505 sql: "IN CLUSTER mz_catalog_server
8506ON mz_internal.mz_show_materialized_views (schema_id)",
8507 is_retained_metrics_object: false,
8508};
8509
8510pub const MZ_SHOW_SINKS_IND: BuiltinIndex = BuiltinIndex {
8511 name: "mz_show_sinks_ind",
8512 schema: MZ_INTERNAL_SCHEMA,
8513 oid: oid::INDEX_MZ_SHOW_SINKS_IND_OID,
8514 sql: "IN CLUSTER mz_catalog_server
8515ON mz_internal.mz_show_sinks (schema_id)",
8516 is_retained_metrics_object: false,
8517};
8518
8519pub const MZ_SHOW_TYPES_IND: BuiltinIndex = BuiltinIndex {
8520 name: "mz_show_types_ind",
8521 schema: MZ_INTERNAL_SCHEMA,
8522 oid: oid::INDEX_MZ_SHOW_TYPES_IND_OID,
8523 sql: "IN CLUSTER mz_catalog_server
8524ON mz_internal.mz_show_types (schema_id)",
8525 is_retained_metrics_object: false,
8526};
8527
8528pub const MZ_SHOW_ROLES_IND: BuiltinIndex = BuiltinIndex {
8529 name: "mz_show_roles_ind",
8530 schema: MZ_INTERNAL_SCHEMA,
8531 oid: oid::INDEX_MZ_SHOW_ROLES_IND_OID,
8532 sql: "IN CLUSTER mz_catalog_server
8533ON mz_internal.mz_show_roles (name)",
8534 is_retained_metrics_object: false,
8535};
8536
8537pub const MZ_SHOW_ALL_OBJECTS_IND: BuiltinIndex = BuiltinIndex {
8538 name: "mz_show_all_objects_ind",
8539 schema: MZ_INTERNAL_SCHEMA,
8540 oid: oid::INDEX_MZ_SHOW_ALL_OBJECTS_IND_OID,
8541 sql: "IN CLUSTER mz_catalog_server
8542ON mz_internal.mz_show_all_objects (schema_id)",
8543 is_retained_metrics_object: false,
8544};
8545
8546pub const MZ_SHOW_INDEXES_IND: BuiltinIndex = BuiltinIndex {
8547 name: "mz_show_indexes_ind",
8548 schema: MZ_INTERNAL_SCHEMA,
8549 oid: oid::INDEX_MZ_SHOW_INDEXES_IND_OID,
8550 sql: "IN CLUSTER mz_catalog_server
8551ON mz_internal.mz_show_indexes (schema_id)",
8552 is_retained_metrics_object: false,
8553};
8554
8555pub const MZ_SHOW_COLUMNS_IND: BuiltinIndex = BuiltinIndex {
8556 name: "mz_show_columns_ind",
8557 schema: MZ_INTERNAL_SCHEMA,
8558 oid: oid::INDEX_MZ_SHOW_COLUMNS_IND_OID,
8559 sql: "IN CLUSTER mz_catalog_server
8560ON mz_internal.mz_show_columns (id)",
8561 is_retained_metrics_object: false,
8562};
8563
8564pub const MZ_SHOW_CLUSTERS_IND: BuiltinIndex = BuiltinIndex {
8565 name: "mz_show_clusters_ind",
8566 schema: MZ_INTERNAL_SCHEMA,
8567 oid: oid::INDEX_MZ_SHOW_CLUSTERS_IND_OID,
8568 sql: "IN CLUSTER mz_catalog_server
8569ON mz_internal.mz_show_clusters (name)",
8570 is_retained_metrics_object: false,
8571};
8572
8573pub const MZ_SHOW_CLUSTER_REPLICAS_IND: BuiltinIndex = BuiltinIndex {
8574 name: "mz_show_cluster_replicas_ind",
8575 schema: MZ_INTERNAL_SCHEMA,
8576 oid: oid::INDEX_MZ_SHOW_CLUSTER_REPLICAS_IND_OID,
8577 sql: "IN CLUSTER mz_catalog_server
8578ON mz_internal.mz_show_cluster_replicas (cluster)",
8579 is_retained_metrics_object: false,
8580};
8581
8582pub const MZ_SHOW_SECRETS_IND: BuiltinIndex = BuiltinIndex {
8583 name: "mz_show_secrets_ind",
8584 schema: MZ_INTERNAL_SCHEMA,
8585 oid: oid::INDEX_MZ_SHOW_SECRETS_IND_OID,
8586 sql: "IN CLUSTER mz_catalog_server
8587ON mz_internal.mz_show_secrets (schema_id)",
8588 is_retained_metrics_object: false,
8589};
8590
8591pub const MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_IND: BuiltinIndex = BuiltinIndex {
8592 name: "mz_console_cluster_utilization_overview_ind",
8593 schema: MZ_INTERNAL_SCHEMA,
8594 oid: oid::INDEX_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_IND_OID,
8595 sql: "IN CLUSTER mz_catalog_server
8596ON mz_internal.mz_console_cluster_utilization_overview (cluster_id)",
8597 is_retained_metrics_object: false,
8598};
8599
8600pub const MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_3H_IND: BuiltinIndex = BuiltinIndex {
8601 name: "mz_console_cluster_utilization_overview_3h_ind",
8602 schema: MZ_INTERNAL_SCHEMA,
8603 oid: oid::INDEX_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_3H_IND_OID,
8604 sql: "IN CLUSTER mz_catalog_server
8605ON mz_internal.mz_console_cluster_utilization_overview_3h (cluster_id)",
8606 is_retained_metrics_object: false,
8607};
8608
8609pub const MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_24H_IND: BuiltinIndex = BuiltinIndex {
8610 name: "mz_console_cluster_utilization_overview_24h_ind",
8611 schema: MZ_INTERNAL_SCHEMA,
8612 oid: oid::INDEX_MZ_CONSOLE_CLUSTER_UTILIZATION_OVERVIEW_24H_IND_OID,
8613 sql: "IN CLUSTER mz_catalog_server
8614ON mz_internal.mz_console_cluster_utilization_overview_24h (cluster_id)",
8615 is_retained_metrics_object: false,
8616};
8617
8618pub const MZ_CLUSTER_DEPLOYMENT_LINEAGE_IND: BuiltinIndex = BuiltinIndex {
8619 name: "mz_cluster_deployment_lineage_ind",
8620 schema: MZ_INTERNAL_SCHEMA,
8621 oid: oid::INDEX_MZ_CLUSTER_DEPLOYMENT_LINEAGE_IND_OID,
8622 sql: "IN CLUSTER mz_catalog_server
8623ON mz_internal.mz_cluster_deployment_lineage (cluster_id)",
8624 is_retained_metrics_object: false,
8625};
8626
8627pub const MZ_SOURCE_STATUSES_IND: BuiltinIndex = BuiltinIndex {
8628 name: "mz_source_statuses_ind",
8629 schema: MZ_INTERNAL_SCHEMA,
8630 oid: oid::INDEX_MZ_SOURCE_STATUSES_IND_OID,
8631 sql: "IN CLUSTER mz_catalog_server
8632ON mz_internal.mz_source_statuses (id)",
8633 is_retained_metrics_object: false,
8634};
8635
8636pub const MZ_SINK_STATUSES_IND: BuiltinIndex = BuiltinIndex {
8637 name: "mz_sink_statuses_ind",
8638 schema: MZ_INTERNAL_SCHEMA,
8639 oid: oid::INDEX_MZ_SINK_STATUSES_IND_OID,
8640 sql: "IN CLUSTER mz_catalog_server
8641ON mz_internal.mz_sink_statuses (id)",
8642 is_retained_metrics_object: false,
8643};
8644
8645pub const MZ_SOURCE_STATUS_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8646 name: "mz_source_status_history_ind",
8647 schema: MZ_INTERNAL_SCHEMA,
8648 oid: oid::INDEX_MZ_SOURCE_STATUS_HISTORY_IND_OID,
8649 sql: "IN CLUSTER mz_catalog_server
8650ON mz_internal.mz_source_status_history (source_id)",
8651 is_retained_metrics_object: false,
8652};
8653
8654pub const MZ_SINK_STATUS_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8655 name: "mz_sink_status_history_ind",
8656 schema: MZ_INTERNAL_SCHEMA,
8657 oid: oid::INDEX_MZ_SINK_STATUS_HISTORY_IND_OID,
8658 sql: "IN CLUSTER mz_catalog_server
8659ON mz_internal.mz_sink_status_history (sink_id)",
8660 is_retained_metrics_object: false,
8661};
8662
8663pub static MZ_SOURCE_STATISTICS_WITH_HISTORY: LazyLock<BuiltinView> =
8677 LazyLock::new(|| BuiltinView {
8678 name: "mz_source_statistics_with_history",
8679 schema: MZ_INTERNAL_SCHEMA,
8680 oid: oid::VIEW_MZ_SOURCE_STATISTICS_WITH_HISTORY_OID,
8681 desc: RelationDesc::builder()
8682 .with_column("id", SqlScalarType::String.nullable(false))
8683 .with_column("replica_id", SqlScalarType::String.nullable(true))
8684 .with_column("messages_received", SqlScalarType::UInt64.nullable(false))
8685 .with_column("bytes_received", SqlScalarType::UInt64.nullable(false))
8686 .with_column("updates_staged", SqlScalarType::UInt64.nullable(false))
8687 .with_column("updates_committed", SqlScalarType::UInt64.nullable(false))
8688 .with_column("records_indexed", SqlScalarType::UInt64.nullable(false))
8689 .with_column("bytes_indexed", SqlScalarType::UInt64.nullable(false))
8690 .with_column(
8691 "rehydration_latency",
8692 SqlScalarType::Interval.nullable(true),
8693 )
8694 .with_column(
8695 "snapshot_records_known",
8696 SqlScalarType::UInt64.nullable(true),
8697 )
8698 .with_column(
8699 "snapshot_records_staged",
8700 SqlScalarType::UInt64.nullable(true),
8701 )
8702 .with_column("snapshot_committed", SqlScalarType::Bool.nullable(false))
8703 .with_column("offset_known", SqlScalarType::UInt64.nullable(true))
8704 .with_column("offset_committed", SqlScalarType::UInt64.nullable(true))
8705 .with_key(vec![0, 1])
8706 .finish(),
8707 column_comments: BTreeMap::new(),
8708 sql: "
8709WITH
8710 -- For each subsource, statistics are reported as its parent source
8711 subsource_to_parent AS
8712 (
8713 SELECT subsource.id AS id, parent.id AS report_id
8714 FROM mz_catalog.mz_sources AS subsource
8715 JOIN mz_internal.mz_object_dependencies AS dep ON subsource.id = dep.object_id
8716 JOIN mz_catalog.mz_sources AS parent ON parent.id = dep.referenced_object_id
8717 WHERE subsource.type = 'subsource'
8718 ),
8719 -- For each table from source, statistics are reported as its parent source
8720 table_to_parent AS
8721 (
8722 SELECT id, source_id AS report_id
8723 FROM mz_catalog.mz_tables
8724 WHERE source_id IS NOT NULL
8725 ),
8726 -- For each source and subsource, statistics are reported as itself
8727 source_refl AS
8728 (
8729 SELECT id, id AS report_id
8730 FROM mz_catalog.mz_sources
8731 WHERE type NOT IN ('progress', 'log')
8732 ),
8733 -- For each table from source, statistics are reported as itself
8734 table_refl AS
8735 (
8736 SELECT id, id AS report_id
8737 FROM mz_catalog.mz_tables
8738 WHERE source_id IS NOT NULL
8739 ),
8740 report_paths AS
8741 (
8742 SELECT id, report_id FROM subsource_to_parent
8743 UNION ALL SELECT id, report_id FROM table_to_parent
8744 UNION ALL SELECT id, report_id FROM source_refl
8745 UNION ALL SELECT id, report_id FROM table_refl
8746 )
8747SELECT
8748 report_paths.report_id AS id,
8749 replica_id,
8750 -- Counters
8751 SUM(messages_received)::uint8 AS messages_received,
8752 SUM(bytes_received)::uint8 AS bytes_received,
8753 SUM(updates_staged)::uint8 AS updates_staged,
8754 SUM(updates_committed)::uint8 AS updates_committed,
8755 -- Resetting Gauges
8756 SUM(records_indexed)::uint8 AS records_indexed,
8757 SUM(bytes_indexed)::uint8 AS bytes_indexed,
8758 -- Ensure we aggregate to NULL when not all workers are done rehydrating.
8759 CASE
8760 WHEN bool_or(rehydration_latency IS NULL) THEN NULL
8761 ELSE MAX(rehydration_latency)::interval
8762 END AS rehydration_latency,
8763 SUM(snapshot_records_known)::uint8 AS snapshot_records_known,
8764 SUM(snapshot_records_staged)::uint8 AS snapshot_records_staged,
8765 bool_and(snapshot_committed) as snapshot_committed,
8766 -- Gauges
8767 MAX(offset_known)::uint8 AS offset_known,
8768 MIN(offset_committed)::uint8 AS offset_committed
8769FROM mz_internal.mz_source_statistics_raw
8770 JOIN report_paths USING (id)
8771GROUP BY report_paths.report_id, replica_id",
8772 access: vec![PUBLIC_SELECT],
8773 ontology: None,
8774 });
8775
8776pub const MZ_SOURCE_STATISTICS_WITH_HISTORY_IND: BuiltinIndex = BuiltinIndex {
8777 name: "mz_source_statistics_with_history_ind",
8778 schema: MZ_INTERNAL_SCHEMA,
8779 oid: oid::INDEX_MZ_SOURCE_STATISTICS_WITH_HISTORY_IND_OID,
8780 sql: "IN CLUSTER mz_catalog_server
8781ON mz_internal.mz_source_statistics_with_history (id, replica_id)",
8782 is_retained_metrics_object: true,
8783};
8784
8785pub static MZ_SOURCE_STATISTICS: LazyLock<BuiltinView> = LazyLock::new(|| {
8788 BuiltinView {
8789 name: "mz_source_statistics",
8790 schema: MZ_INTERNAL_SCHEMA,
8791 oid: oid::VIEW_MZ_SOURCE_STATISTICS_OID,
8792 desc: RelationDesc::builder()
8794 .with_column("id", SqlScalarType::String.nullable(false))
8795 .with_column("replica_id", SqlScalarType::String.nullable(true))
8796 .with_column("messages_received", SqlScalarType::UInt64.nullable(false))
8797 .with_column("bytes_received", SqlScalarType::UInt64.nullable(false))
8798 .with_column("updates_staged", SqlScalarType::UInt64.nullable(false))
8799 .with_column("updates_committed", SqlScalarType::UInt64.nullable(false))
8800 .with_column("records_indexed", SqlScalarType::UInt64.nullable(false))
8801 .with_column("bytes_indexed", SqlScalarType::UInt64.nullable(false))
8802 .with_column(
8803 "rehydration_latency",
8804 SqlScalarType::Interval.nullable(true),
8805 )
8806 .with_column(
8807 "snapshot_records_known",
8808 SqlScalarType::UInt64.nullable(true),
8809 )
8810 .with_column(
8811 "snapshot_records_staged",
8812 SqlScalarType::UInt64.nullable(true),
8813 )
8814 .with_column("snapshot_committed", SqlScalarType::Bool.nullable(false))
8815 .with_column("offset_known", SqlScalarType::UInt64.nullable(true))
8816 .with_column("offset_committed", SqlScalarType::UInt64.nullable(true))
8817 .with_key(vec![0, 1])
8818 .finish(),
8819 column_comments: BTreeMap::from_iter([
8820 (
8821 "id",
8822 "The ID of the source. Corresponds to `mz_catalog.mz_sources.id`.",
8823 ),
8824 (
8825 "replica_id",
8826 "The ID of a replica running the source. Corresponds to `mz_catalog.mz_cluster_replicas.id`.",
8827 ),
8828 (
8829 "messages_received",
8830 "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.",
8831 ),
8832 (
8833 "bytes_received",
8834 "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.",
8835 ),
8836 (
8837 "updates_staged",
8838 "The number of updates (insertions plus deletions) the source has written but not yet committed to the storage layer.",
8839 ),
8840 (
8841 "updates_committed",
8842 "The number of updates (insertions plus deletions) the source has committed to the storage layer.",
8843 ),
8844 (
8845 "records_indexed",
8846 "The number of individual records indexed in the source envelope state.",
8847 ),
8848 (
8849 "bytes_indexed",
8850 "The number of bytes stored in the source's internal index, if any.",
8851 ),
8852 (
8853 "rehydration_latency",
8854 "The amount of time it took for the source to rehydrate its internal index, if any, after the source last restarted.",
8855 ),
8856 (
8857 "snapshot_records_known",
8858 "The size of the source's snapshot, measured in number of records. See below to learn what constitutes a record.",
8859 ),
8860 (
8861 "snapshot_records_staged",
8862 "The number of records in the source's snapshot that Materialize has read. See below to learn what constitutes a record.",
8863 ),
8864 (
8865 "snapshot_committed",
8866 "Whether the source has committed the initial snapshot for a source.",
8867 ),
8868 (
8869 "offset_known",
8870 "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.",
8871 ),
8872 (
8873 "offset_committed",
8874 "The offset of the the data that Materialize has durably ingested. See below to learn what constitutes an offset.",
8875 ),
8876 ]),
8877 sql: "SELECT * FROM mz_internal.mz_source_statistics_with_history WHERE length(id) > 0",
8878 access: vec![PUBLIC_SELECT],
8879 ontology: Some(Ontology {
8880 entity_name: "source_statistics",
8881 description: "Aggregated source ingestion statistics",
8882 links: &const {
8883 [OntologyLink {
8884 name: "statistics_of_source",
8885 target: "source",
8886 properties: LinkProperties::measures("id", "id", "ingestion_statistics"),
8887 }]
8888 },
8889 column_semantic_types: &const {
8890 [
8891 ("id", SemanticType::CatalogItemId),
8892 ("replica_id", SemanticType::ReplicaId),
8893 ("messages_received", SemanticType::RecordCount),
8894 ("bytes_received", SemanticType::ByteCount),
8895 ("updates_staged", SemanticType::RecordCount),
8896 ("updates_committed", SemanticType::RecordCount),
8897 ("records_indexed", SemanticType::RecordCount),
8898 ("bytes_indexed", SemanticType::ByteCount),
8899 ("snapshot_records_known", SemanticType::RecordCount),
8900 ("snapshot_records_staged", SemanticType::RecordCount),
8901 ]
8902 },
8903 }),
8904 }
8905});
8906
8907pub const MZ_SOURCE_STATISTICS_IND: BuiltinIndex = BuiltinIndex {
8908 name: "mz_source_statistics_ind",
8909 schema: MZ_INTERNAL_SCHEMA,
8910 oid: oid::INDEX_MZ_SOURCE_STATISTICS_IND_OID,
8911 sql: "IN CLUSTER mz_catalog_server
8912ON mz_internal.mz_source_statistics (id, replica_id)",
8913 is_retained_metrics_object: false,
8914};
8915
8916pub static MZ_SINK_STATISTICS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
8917 name: "mz_sink_statistics",
8918 schema: MZ_INTERNAL_SCHEMA,
8919 oid: oid::VIEW_MZ_SINK_STATISTICS_OID,
8920 desc: RelationDesc::builder()
8921 .with_column("id", SqlScalarType::String.nullable(false))
8922 .with_column("replica_id", SqlScalarType::String.nullable(true))
8923 .with_column("messages_staged", SqlScalarType::UInt64.nullable(false))
8924 .with_column("messages_committed", SqlScalarType::UInt64.nullable(false))
8925 .with_column("bytes_staged", SqlScalarType::UInt64.nullable(false))
8926 .with_column("bytes_committed", SqlScalarType::UInt64.nullable(false))
8927 .with_key(vec![0, 1])
8928 .finish(),
8929 column_comments: BTreeMap::from_iter([
8930 (
8931 "id",
8932 "The ID of the sink. Corresponds to `mz_catalog.mz_sinks.id`.",
8933 ),
8934 (
8935 "replica_id",
8936 "The ID of a replica running the sink. Corresponds to `mz_catalog.mz_cluster_replicas.id`.",
8937 ),
8938 (
8939 "messages_staged",
8940 "The number of messages staged but possibly not committed to the sink.",
8941 ),
8942 (
8943 "messages_committed",
8944 "The number of messages committed to the sink.",
8945 ),
8946 (
8947 "bytes_staged",
8948 "The number of bytes staged but possibly not committed to the sink. This counts both keys and values, if applicable.",
8949 ),
8950 (
8951 "bytes_committed",
8952 "The number of bytes committed to the sink. This counts both keys and values, if applicable.",
8953 ),
8954 ]),
8955 sql: "
8956SELECT
8957 id,
8958 replica_id,
8959 SUM(messages_staged)::uint8 AS messages_staged,
8960 SUM(messages_committed)::uint8 AS messages_committed,
8961 SUM(bytes_staged)::uint8 AS bytes_staged,
8962 SUM(bytes_committed)::uint8 AS bytes_committed
8963FROM mz_internal.mz_sink_statistics_raw
8964GROUP BY id, replica_id",
8965 access: vec![PUBLIC_SELECT],
8966 ontology: Some(Ontology {
8967 entity_name: "sink_statistics",
8968 description: "Aggregated sink export statistics",
8969 links: &const {
8970 [OntologyLink {
8971 name: "statistics_of_sink",
8972 target: "sink",
8973 properties: LinkProperties::measures("id", "id", "export_statistics"),
8974 }]
8975 },
8976 column_semantic_types: &const {
8977 [
8978 ("id", SemanticType::CatalogItemId),
8979 ("replica_id", SemanticType::ReplicaId),
8980 ("messages_staged", SemanticType::RecordCount),
8981 ("messages_committed", SemanticType::RecordCount),
8982 ("bytes_staged", SemanticType::ByteCount),
8983 ("bytes_committed", SemanticType::ByteCount),
8984 ]
8985 },
8986 }),
8987});
8988
8989pub const MZ_SINK_STATISTICS_IND: BuiltinIndex = BuiltinIndex {
8990 name: "mz_sink_statistics_ind",
8991 schema: MZ_INTERNAL_SCHEMA,
8992 oid: oid::INDEX_MZ_SINK_STATISTICS_IND_OID,
8993 sql: "IN CLUSTER mz_catalog_server
8994ON mz_internal.mz_sink_statistics (id, replica_id)",
8995 is_retained_metrics_object: true,
8996};
8997
8998pub const MZ_CLUSTER_REPLICA_STATUSES_IND: BuiltinIndex = BuiltinIndex {
8999 name: "mz_cluster_replica_statuses_ind",
9000 schema: MZ_INTERNAL_SCHEMA,
9001 oid: oid::INDEX_MZ_CLUSTER_REPLICA_STATUSES_IND_OID,
9002 sql: "IN CLUSTER mz_catalog_server
9003ON mz_internal.mz_cluster_replica_statuses (replica_id)",
9004 is_retained_metrics_object: false,
9005};
9006
9007pub const MZ_CLUSTER_REPLICA_STATUS_HISTORY_IND: BuiltinIndex = BuiltinIndex {
9008 name: "mz_cluster_replica_status_history_ind",
9009 schema: MZ_INTERNAL_SCHEMA,
9010 oid: oid::INDEX_MZ_CLUSTER_REPLICA_STATUS_HISTORY_IND_OID,
9011 sql: "IN CLUSTER mz_catalog_server
9012ON mz_internal.mz_cluster_replica_status_history (replica_id)",
9013 is_retained_metrics_object: false,
9014};
9015
9016pub const MZ_CLUSTER_REPLICA_METRICS_IND: BuiltinIndex = BuiltinIndex {
9017 name: "mz_cluster_replica_metrics_ind",
9018 schema: MZ_INTERNAL_SCHEMA,
9019 oid: oid::INDEX_MZ_CLUSTER_REPLICA_METRICS_IND_OID,
9020 sql: "IN CLUSTER mz_catalog_server
9021ON mz_internal.mz_cluster_replica_metrics (replica_id)",
9022 is_retained_metrics_object: false,
9023};
9024
9025pub const MZ_CLUSTER_REPLICA_METRICS_HISTORY_IND: BuiltinIndex = BuiltinIndex {
9026 name: "mz_cluster_replica_metrics_history_ind",
9027 schema: MZ_INTERNAL_SCHEMA,
9028 oid: oid::INDEX_MZ_CLUSTER_REPLICA_METRICS_HISTORY_IND_OID,
9029 sql: "IN CLUSTER mz_catalog_server
9030ON mz_internal.mz_cluster_replica_metrics_history (replica_id)",
9031 is_retained_metrics_object: false,
9032};
9033
9034pub const MZ_CLUSTER_REPLICA_HISTORY_IND: BuiltinIndex = BuiltinIndex {
9035 name: "mz_cluster_replica_history_ind",
9036 schema: MZ_INTERNAL_SCHEMA,
9037 oid: oid::INDEX_MZ_CLUSTER_REPLICA_HISTORY_IND_OID,
9038 sql: "IN CLUSTER mz_catalog_server
9039ON mz_internal.mz_cluster_replica_history (dropped_at)",
9040 is_retained_metrics_object: true,
9041};
9042
9043pub const MZ_CLUSTER_REPLICA_NAME_HISTORY_IND: BuiltinIndex = BuiltinIndex {
9044 name: "mz_cluster_replica_name_history_ind",
9045 schema: MZ_INTERNAL_SCHEMA,
9046 oid: oid::INDEX_MZ_CLUSTER_REPLICA_NAME_HISTORY_IND_OID,
9047 sql: "IN CLUSTER mz_catalog_server
9048ON mz_internal.mz_cluster_replica_name_history (id)",
9049 is_retained_metrics_object: false,
9050};
9051
9052pub const MZ_OBJECT_LIFETIMES_IND: BuiltinIndex = BuiltinIndex {
9053 name: "mz_object_lifetimes_ind",
9054 schema: MZ_INTERNAL_SCHEMA,
9055 oid: oid::INDEX_MZ_OBJECT_LIFETIMES_IND_OID,
9056 sql: "IN CLUSTER mz_catalog_server
9057ON mz_internal.mz_object_lifetimes (id)",
9058 is_retained_metrics_object: false,
9059};
9060
9061pub const MZ_OBJECT_HISTORY_IND: BuiltinIndex = BuiltinIndex {
9062 name: "mz_object_history_ind",
9063 schema: MZ_INTERNAL_SCHEMA,
9064 oid: oid::INDEX_MZ_OBJECT_HISTORY_IND_OID,
9065 sql: "IN CLUSTER mz_catalog_server
9066ON mz_internal.mz_object_history (id)",
9067 is_retained_metrics_object: false,
9068};
9069
9070pub const MZ_OBJECT_DEPENDENCIES_IND: BuiltinIndex = BuiltinIndex {
9071 name: "mz_object_dependencies_ind",
9072 schema: MZ_INTERNAL_SCHEMA,
9073 oid: oid::INDEX_MZ_OBJECT_DEPENDENCIES_IND_OID,
9074 sql: "IN CLUSTER mz_catalog_server
9075ON mz_internal.mz_object_dependencies (object_id)",
9076 is_retained_metrics_object: true,
9077};
9078
9079pub const MZ_COMPUTE_DEPENDENCIES_IND: BuiltinIndex = BuiltinIndex {
9080 name: "mz_compute_dependencies_ind",
9081 schema: MZ_INTERNAL_SCHEMA,
9082 oid: oid::INDEX_MZ_COMPUTE_DEPENDENCIES_IND_OID,
9083 sql: "IN CLUSTER mz_catalog_server
9084ON mz_internal.mz_compute_dependencies (dependency_id)",
9085 is_retained_metrics_object: false,
9086};
9087
9088pub const MZ_OBJECT_TRANSITIVE_DEPENDENCIES_IND: BuiltinIndex = BuiltinIndex {
9089 name: "mz_object_transitive_dependencies_ind",
9090 schema: MZ_INTERNAL_SCHEMA,
9091 oid: oid::INDEX_MZ_OBJECT_TRANSITIVE_DEPENDENCIES_IND_OID,
9092 sql: "IN CLUSTER mz_catalog_server
9093ON mz_internal.mz_object_transitive_dependencies (object_id)",
9094 is_retained_metrics_object: false,
9095};
9096
9097pub const MZ_OBJECT_GRAPH_EDGES_IND: BuiltinIndex = BuiltinIndex {
9098 name: "mz_object_graph_edges_ind",
9099 schema: MZ_INTERNAL_SCHEMA,
9100 oid: oid::INDEX_MZ_OBJECT_GRAPH_EDGES_IND_OID,
9101 sql: "IN CLUSTER mz_catalog_server
9102ON mz_internal.mz_object_graph_edges (object_id)",
9103 is_retained_metrics_object: false,
9104};
9105
9106pub const MZ_FRONTIERS_IND: BuiltinIndex = BuiltinIndex {
9107 name: "mz_frontiers_ind",
9108 schema: MZ_INTERNAL_SCHEMA,
9109 oid: oid::INDEX_MZ_FRONTIERS_IND_OID,
9110 sql: "IN CLUSTER mz_catalog_server
9111ON mz_internal.mz_frontiers (object_id)",
9112 is_retained_metrics_object: false,
9113};
9114
9115pub const MZ_WALLCLOCK_GLOBAL_LAG_RECENT_HISTORY_IND: BuiltinIndex = BuiltinIndex {
9116 name: "mz_wallclock_global_lag_recent_history_ind",
9117 schema: MZ_INTERNAL_SCHEMA,
9118 oid: oid::INDEX_MZ_WALLCLOCK_GLOBAL_LAG_RECENT_HISTORY_IND_OID,
9119 sql: "IN CLUSTER mz_catalog_server
9120ON mz_internal.mz_wallclock_global_lag_recent_history (object_id)",
9121 is_retained_metrics_object: false,
9122};
9123
9124pub const MZ_RECENT_ACTIVITY_LOG_THINNED_IND: BuiltinIndex = BuiltinIndex {
9125 name: "mz_recent_activity_log_thinned_ind",
9126 schema: MZ_INTERNAL_SCHEMA,
9127 oid: oid::INDEX_MZ_RECENT_ACTIVITY_LOG_THINNED_IND_OID,
9128 sql: "IN CLUSTER mz_catalog_server
9129-- sql_hash because we plan to join
9130-- this against mz_internal.mz_sql_text
9131ON mz_internal.mz_recent_activity_log_thinned (sql_hash)",
9132 is_retained_metrics_object: false,
9133};
9134
9135pub const MZ_WEBHOOK_SOURCES_IND: BuiltinIndex = BuiltinIndex {
9136 name: "mz_webhook_sources_ind",
9137 schema: MZ_INTERNAL_SCHEMA,
9138 oid: oid::INDEX_MZ_WEBHOOK_SOURCES_IND_OID,
9139 sql: "IN CLUSTER mz_catalog_server
9140ON mz_internal.mz_webhook_sources (id)",
9141 is_retained_metrics_object: true,
9142};
9143
9144pub const MZ_COMMENTS_IND: BuiltinIndex = BuiltinIndex {
9145 name: "mz_comments_ind",
9146 schema: MZ_INTERNAL_SCHEMA,
9147 oid: oid::INDEX_MZ_COMMENTS_IND_OID,
9148 sql: "IN CLUSTER mz_catalog_server
9149ON mz_internal.mz_comments (id)",
9150 is_retained_metrics_object: true,
9151};
9152
9153pub static MZ_ANALYTICS: BuiltinConnection = BuiltinConnection {
9154 name: "mz_analytics",
9155 schema: MZ_INTERNAL_SCHEMA,
9156 oid: oid::CONNECTION_MZ_ANALYTICS_OID,
9157 sql: "CREATE CONNECTION mz_internal.mz_analytics TO AWS (ASSUME ROLE ARN = '')",
9158 access: &[MzAclItem {
9159 grantee: MZ_SYSTEM_ROLE_ID,
9160 grantor: MZ_ANALYTICS_ROLE_ID,
9161 acl_mode: rbac::all_object_privileges(SystemObjectType::Object(ObjectType::Connection)),
9162 }],
9163 owner_id: &MZ_ANALYTICS_ROLE_ID,
9164 runtime_alterable: true,
9165};