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