1use std::collections::BTreeMap;
13use std::sync::LazyLock;
14
15use mz_catalog_protos::objects::CatalogItemType;
16use mz_pgrepr::oid;
17use mz_repr::namespaces::MZ_CATALOG_SCHEMA;
18use mz_repr::{RelationDesc, SemanticType, SqlScalarType};
19use mz_sql::catalog::{
20 CatalogType, CatalogTypeDetails, CatalogTypePgMetadata, NameReference, ObjectType,
21};
22use mz_sql::rbac;
23use mz_sql::session::user::{MZ_SYSTEM_ROLE_ID, SUPPORT_USER_NAME, SYSTEM_USER_NAME};
24use mz_storage_client::controller::IntrospectionType;
25
26use super::builtin::gid_mapping_object_type;
27use super::{
28 BuiltinIndex, BuiltinMaterializedView, BuiltinSource, BuiltinTable, BuiltinType, BuiltinView,
29 Cardinality, LinkProperties, Ontology, OntologyLink, PUBLIC_SELECT,
30};
31
32pub const TYPE_LIST: BuiltinType<NameReference> = BuiltinType {
33 name: "list",
34 schema: MZ_CATALOG_SCHEMA,
35 oid: mz_pgrepr::oid::TYPE_LIST_OID,
36 details: CatalogTypeDetails {
37 typ: CatalogType::Pseudo,
38 array_id: None,
39 pg_metadata: None,
40 },
41};
42
43pub const TYPE_MAP: BuiltinType<NameReference> = BuiltinType {
44 name: "map",
45 schema: MZ_CATALOG_SCHEMA,
46 oid: mz_pgrepr::oid::TYPE_MAP_OID,
47 details: CatalogTypeDetails {
48 typ: CatalogType::Pseudo,
49 array_id: None,
50 pg_metadata: None,
51 },
52};
53
54pub const TYPE_ANYCOMPATIBLELIST: BuiltinType<NameReference> = BuiltinType {
55 name: "anycompatiblelist",
56 schema: MZ_CATALOG_SCHEMA,
57 oid: mz_pgrepr::oid::TYPE_ANYCOMPATIBLELIST_OID,
58 details: CatalogTypeDetails {
59 typ: CatalogType::Pseudo,
60 array_id: None,
61 pg_metadata: None,
62 },
63};
64
65pub const TYPE_ANYCOMPATIBLEMAP: BuiltinType<NameReference> = BuiltinType {
66 name: "anycompatiblemap",
67 schema: MZ_CATALOG_SCHEMA,
68 oid: mz_pgrepr::oid::TYPE_ANYCOMPATIBLEMAP_OID,
69 details: CatalogTypeDetails {
70 typ: CatalogType::Pseudo,
71 array_id: None,
72 pg_metadata: None,
73 },
74};
75
76pub const TYPE_UINT2: BuiltinType<NameReference> = BuiltinType {
77 name: "uint2",
78 schema: MZ_CATALOG_SCHEMA,
79 oid: mz_pgrepr::oid::TYPE_UINT2_OID,
80 details: CatalogTypeDetails {
81 typ: CatalogType::UInt16,
82 array_id: None,
83 pg_metadata: None,
84 },
85};
86
87pub const TYPE_UINT2_ARRAY: BuiltinType<NameReference> = BuiltinType {
88 name: "_uint2",
89 schema: MZ_CATALOG_SCHEMA,
90 oid: mz_pgrepr::oid::TYPE_UINT2_ARRAY_OID,
91 details: CatalogTypeDetails {
92 typ: CatalogType::Array {
93 element_reference: TYPE_UINT2.name,
94 },
95 array_id: None,
96 pg_metadata: None,
97 },
98};
99
100pub const TYPE_UINT4: BuiltinType<NameReference> = BuiltinType {
101 name: "uint4",
102 schema: MZ_CATALOG_SCHEMA,
103 oid: mz_pgrepr::oid::TYPE_UINT4_OID,
104 details: CatalogTypeDetails {
105 typ: CatalogType::UInt32,
106 array_id: None,
107 pg_metadata: None,
108 },
109};
110
111pub const TYPE_UINT4_ARRAY: BuiltinType<NameReference> = BuiltinType {
112 name: "_uint4",
113 schema: MZ_CATALOG_SCHEMA,
114 oid: mz_pgrepr::oid::TYPE_UINT4_ARRAY_OID,
115 details: CatalogTypeDetails {
116 typ: CatalogType::Array {
117 element_reference: TYPE_UINT4.name,
118 },
119 array_id: None,
120 pg_metadata: None,
121 },
122};
123
124pub const TYPE_UINT8: BuiltinType<NameReference> = BuiltinType {
125 name: "uint8",
126 schema: MZ_CATALOG_SCHEMA,
127 oid: mz_pgrepr::oid::TYPE_UINT8_OID,
128 details: CatalogTypeDetails {
129 typ: CatalogType::UInt64,
130 array_id: None,
131 pg_metadata: None,
132 },
133};
134
135pub const TYPE_UINT8_ARRAY: BuiltinType<NameReference> = BuiltinType {
136 name: "_uint8",
137 schema: MZ_CATALOG_SCHEMA,
138 oid: mz_pgrepr::oid::TYPE_UINT8_ARRAY_OID,
139 details: CatalogTypeDetails {
140 typ: CatalogType::Array {
141 element_reference: TYPE_UINT8.name,
142 },
143 array_id: None,
144 pg_metadata: None,
145 },
146};
147
148pub const TYPE_MZ_TIMESTAMP: BuiltinType<NameReference> = BuiltinType {
149 name: "mz_timestamp",
150 schema: MZ_CATALOG_SCHEMA,
151 oid: mz_pgrepr::oid::TYPE_MZ_TIMESTAMP_OID,
152 details: CatalogTypeDetails {
153 typ: CatalogType::MzTimestamp,
154 array_id: None,
155 pg_metadata: None,
156 },
157};
158
159pub const TYPE_MZ_TIMESTAMP_ARRAY: BuiltinType<NameReference> = BuiltinType {
160 name: "_mz_timestamp",
161 schema: MZ_CATALOG_SCHEMA,
162 oid: mz_pgrepr::oid::TYPE_MZ_TIMESTAMP_ARRAY_OID,
163 details: CatalogTypeDetails {
164 typ: CatalogType::Array {
165 element_reference: TYPE_MZ_TIMESTAMP.name,
166 },
167 array_id: None,
168 pg_metadata: None,
169 },
170};
171
172pub const TYPE_MZ_ACL_ITEM: BuiltinType<NameReference> = BuiltinType {
173 name: "mz_aclitem",
174 schema: MZ_CATALOG_SCHEMA,
175 oid: mz_pgrepr::oid::TYPE_MZ_ACL_ITEM_OID,
176 details: CatalogTypeDetails {
177 typ: CatalogType::MzAclItem,
178 array_id: None,
179 pg_metadata: None,
180 },
181};
182
183pub const TYPE_MZ_ACL_ITEM_ARRAY: BuiltinType<NameReference> = BuiltinType {
184 name: "_mz_aclitem",
185 schema: MZ_CATALOG_SCHEMA,
186 oid: mz_pgrepr::oid::TYPE_MZ_ACL_ITEM_ARRAY_OID,
187 details: CatalogTypeDetails {
188 typ: CatalogType::Array {
189 element_reference: TYPE_MZ_ACL_ITEM.name,
190 },
191 array_id: None,
192 pg_metadata: Some(CatalogTypePgMetadata {
193 typinput_oid: 750,
194 typreceive_oid: 2400,
195 typsend_oid: 2401,
196 }),
197 },
198};
199
200pub static MZ_ICEBERG_SINKS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
201 BuiltinMaterializedView {
202 name: "mz_iceberg_sinks",
203 schema: MZ_CATALOG_SCHEMA,
204 oid: oid::MV_MZ_ICEBERG_SINKS_OID,
205 desc: RelationDesc::builder()
206 .with_column("id", SqlScalarType::String.nullable(false))
207 .with_column("namespace", SqlScalarType::String.nullable(false))
208 .with_column("table", SqlScalarType::String.nullable(false))
209 .finish(),
210 column_comments: BTreeMap::from_iter([
211 ("id", "The ID of the sink."),
212 (
213 "namespace",
214 "The namespace of the Iceberg table into which the sink is writing.",
215 ),
216 ("table", "The Iceberg table into which the sink is writing."),
217 ]),
218 sql: "
220IN CLUSTER mz_catalog_server
221WITH (
222 ASSERT NOT NULL id,
223 ASSERT NOT NULL namespace,
224 ASSERT NOT NULL \"table\"
225) AS
226SELECT
227 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
228 parsed->>'namespace' AS namespace,
229 parsed->>'table' AS \"table\"
230FROM
231 mz_internal.mz_catalog_raw
232 CROSS JOIN LATERAL (
233 SELECT mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')
234 ) AS l(parsed)
235WHERE
236 data->>'kind' = 'Item' AND
237 parsed->>'sink_type' = 'iceberg'",
238 is_retained_metrics_object: false,
239 access: vec![PUBLIC_SELECT],
240 ontology: Some(Ontology {
241 entity_name: "iceberg_sink",
242 description: "Iceberg-specific sink configuration (namespace, table)",
243 links: &const {
244 [OntologyLink {
245 name: "details_of",
246 target: "sink",
247 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
248 }]
249 },
250 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
251 }),
252 }
253});
254
255pub static MZ_KAFKA_SINKS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
256 BuiltinMaterializedView {
257 name: "mz_kafka_sinks",
258 schema: MZ_CATALOG_SCHEMA,
259 oid: oid::MV_MZ_KAFKA_SINKS_OID,
260 desc: RelationDesc::builder()
261 .with_column("id", SqlScalarType::String.nullable(false))
262 .with_column("topic", SqlScalarType::String.nullable(false))
263 .with_key(vec![0])
264 .finish(),
265 column_comments: BTreeMap::from_iter([
266 ("id", "The ID of the sink."),
267 (
268 "topic",
269 "The name of the Kafka topic into which the sink is writing.",
270 ),
271 ]),
272 sql: "
274IN CLUSTER mz_catalog_server
275WITH (
276 ASSERT NOT NULL id,
277 ASSERT NOT NULL topic
278) AS
279SELECT
280 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
281 parsed->>'topic' AS topic
282FROM
283 mz_internal.mz_catalog_raw
284 CROSS JOIN LATERAL (
285 SELECT mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')
286 ) AS l(parsed)
287WHERE
288 data->>'kind' = 'Item' AND
289 parsed->>'sink_type' = 'kafka'",
290 is_retained_metrics_object: false,
291 access: vec![PUBLIC_SELECT],
292 ontology: Some(Ontology {
293 entity_name: "kafka_sink",
294 description: "Kafka-specific sink configuration (topic)",
295 links: &const {
296 [OntologyLink {
297 name: "details_of",
298 target: "sink",
299 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
300 }]
301 },
302 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
303 }),
304 }
305});
306pub static MZ_KAFKA_CONNECTIONS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
313 BuiltinMaterializedView {
314 name: "mz_kafka_connections",
315 schema: MZ_CATALOG_SCHEMA,
316 oid: oid::MV_MZ_KAFKA_CONNECTIONS_OID,
317 desc: RelationDesc::builder()
318 .with_column("id", SqlScalarType::String.nullable(false))
319 .with_column(
320 "brokers",
321 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
322 )
323 .with_column("sink_progress_topic", SqlScalarType::String.nullable(false))
324 .with_key(vec![0])
325 .finish(),
326 column_comments: BTreeMap::from_iter([
327 ("id", "The ID of the connection."),
328 (
329 "brokers",
330 "The addresses of the Kafka brokers to connect to.",
331 ),
332 (
333 "sink_progress_topic",
334 "The name of the Kafka topic where any sinks associated with this connection will track their progress information and other metadata. The contents of this topic are unspecified.",
335 ),
336 ]),
337 sql: "
341IN CLUSTER mz_catalog_server
342WITH (
343 ASSERT NOT NULL id,
344 ASSERT NOT NULL brokers,
345 ASSERT NOT NULL sink_progress_topic
346) AS
347SELECT
348 mz_internal.parse_catalog_id(r.data->'key'->'gid') AS id,
349 ARRAY(
350 SELECT b.value
351 FROM jsonb_array_elements_text(details->'brokers')
352 WITH ORDINALITY AS b(value, ord)
353 ORDER BY b.ord
354 ) AS brokers,
355 COALESCE(
356 details->>'progress_topic',
357 '_materialize-progress-' || mz_environment_id() || '-'
358 || mz_internal.parse_catalog_id(r.data->'key'->'gid')
359 ) AS sink_progress_topic
360FROM
361 mz_internal.mz_catalog_raw r,
362 LATERAL (
363 SELECT mz_internal.parse_connection_details(
364 r.data->'value'->'definition'->'V1'->>'create_sql')
365 ) AS d(details)
366WHERE
367 r.data->>'kind' = 'Item' AND
368 -- The connection_type filter selects the kind. A non-matching row yields a
369 -- NULL connection_type and is dropped here, so no `details IS NOT NULL` is
370 -- needed (parse_connection_details returns jsonb null, which passes it).
371 mz_internal.parse_catalog_create_sql(
372 r.data->'value'->'definition'->'V1'->>'create_sql')->>'connection_type' = 'kafka'",
373 is_retained_metrics_object: false,
374 access: vec![PUBLIC_SELECT],
375 ontology: Some(Ontology {
376 entity_name: "kafka_connection",
377 description: "Kafka-specific connection configuration (brokers, progress topic)",
378 links: &const {
379 [OntologyLink {
380 name: "details_of",
381 target: "connection",
382 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
383 }]
384 },
385 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
386 }),
387 }
388});
389pub static MZ_KAFKA_SOURCES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
390 BuiltinMaterializedView {
391 name: "mz_kafka_sources",
392 schema: MZ_CATALOG_SCHEMA,
393 oid: oid::MV_MZ_KAFKA_SOURCES_OID,
394 desc: RelationDesc::builder()
395 .with_column("id", SqlScalarType::String.nullable(false))
396 .with_column("group_id_prefix", SqlScalarType::String.nullable(false))
397 .with_column("topic", SqlScalarType::String.nullable(false))
398 .with_key(vec![0])
399 .finish(),
400 column_comments: BTreeMap::from_iter([
401 (
402 "id",
403 "The ID of the Kafka source. Corresponds to `mz_catalog.mz_sources.id`.",
404 ),
405 (
406 "group_id_prefix",
407 "The value of the `GROUP ID PREFIX` connection option.",
408 ),
409 (
410 "topic",
411 "The name of the Kafka topic the source is reading from.",
412 ),
413 ]),
414 sql: "
419IN CLUSTER mz_catalog_server
420WITH (
421 ASSERT NOT NULL id,
422 ASSERT NOT NULL group_id_prefix,
423 ASSERT NOT NULL topic
424) AS
425SELECT
426 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
427 COALESCE(details->>'group_id_prefix', '')
428 || 'materialize-' || mz_environment_id()
429 || '-' || (details->>'connection_id')
430 || '-' || mz_internal.parse_catalog_id(data->'value'->'global_id')
431 AS group_id_prefix,
432 details->>'topic' AS topic
433FROM
434 mz_internal.mz_catalog_raw,
435 LATERAL (
436 SELECT mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')
437 ) AS l(parsed),
438 LATERAL (
439 SELECT mz_internal.parse_kafka_source_details(data->'value'->'definition'->'V1'->>'create_sql')
440 ) AS d(details)
441WHERE
442 data->>'kind' = 'Item' AND
443 parsed->>'source_type' = 'kafka'",
444 is_retained_metrics_object: false,
445 access: vec![PUBLIC_SELECT],
446 ontology: Some(Ontology {
447 entity_name: "kafka_source",
448 description: "Kafka-specific source configuration (topic, group ID)",
449 links: &const {
450 [OntologyLink {
451 name: "details_of",
452 target: "source",
453 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
454 }]
455 },
456 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
457 }),
458 }
459});
460
461pub static MZ_DATABASES: LazyLock<BuiltinMaterializedView> =
462 LazyLock::new(|| BuiltinMaterializedView {
463 name: "mz_databases",
464 schema: MZ_CATALOG_SCHEMA,
465 oid: oid::MV_MZ_DATABASES_OID,
466 desc: RelationDesc::builder()
467 .with_column("id", SqlScalarType::String.nullable(false))
468 .with_column("oid", SqlScalarType::Oid.nullable(false))
469 .with_column("name", SqlScalarType::String.nullable(false))
470 .with_column("owner_id", SqlScalarType::String.nullable(false))
471 .with_column(
472 "privileges",
473 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
474 )
475 .with_key(vec![0])
476 .with_key(vec![1])
477 .finish(),
478 column_comments: BTreeMap::from_iter([
479 ("id", "Materialize's unique ID for the database."),
480 ("oid", "A PostgreSQL-compatible OID for the database."),
481 ("name", "The name of the database."),
482 (
483 "owner_id",
484 "The role ID of the owner of the database. Corresponds to `mz_roles.id`.",
485 ),
486 ("privileges", "The privileges belonging to the database."),
487 ]),
488 sql: "
489IN CLUSTER mz_catalog_server
490WITH (
491 ASSERT NOT NULL id,
492 ASSERT NOT NULL oid,
493 ASSERT NOT NULL name,
494 ASSERT NOT NULL owner_id,
495 ASSERT NOT NULL privileges
496) AS
497SELECT
498 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
499 (data->'value'->>'oid')::oid AS oid,
500 data->'value'->>'name' AS name,
501 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
502 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges
503FROM mz_internal.mz_catalog_raw
504WHERE data->>'kind' = 'Database'",
505 is_retained_metrics_object: false,
506 access: vec![PUBLIC_SELECT],
507 ontology: Some(Ontology {
508 entity_name: "database",
509 description: "A top-level namespace that contains schemas",
510 links: &const {
511 [OntologyLink {
512 name: "owned_by",
513 target: "role",
514 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
515 }]
516 },
517 column_semantic_types: &const {
518 [
519 ("id", SemanticType::DatabaseId),
520 ("oid", SemanticType::OID),
521 ("owner_id", SemanticType::RoleId),
522 ]
523 },
524 }),
525 });
526
527pub static MZ_SCHEMAS: LazyLock<BuiltinMaterializedView> =
528 LazyLock::new(|| BuiltinMaterializedView {
529 name: "mz_schemas",
530 schema: MZ_CATALOG_SCHEMA,
531 oid: oid::MV_MZ_SCHEMAS_OID,
532 desc: RelationDesc::builder()
533 .with_column("id", SqlScalarType::String.nullable(false))
534 .with_column("oid", SqlScalarType::Oid.nullable(false))
535 .with_column("database_id", SqlScalarType::String.nullable(true))
536 .with_column("name", SqlScalarType::String.nullable(false))
537 .with_column("owner_id", SqlScalarType::String.nullable(false))
538 .with_column(
539 "privileges",
540 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
541 )
542 .with_key(vec![0])
543 .with_key(vec![1])
544 .finish(),
545 column_comments: BTreeMap::from_iter([
546 ("id", "Materialize's unique ID for the schema."),
547 ("oid", "A PostgreSQL-compatible oid for the schema."),
548 (
549 "database_id",
550 "The ID of the database containing the schema. Corresponds to `mz_databases.id`.",
551 ),
552 ("name", "The name of the schema."),
553 (
554 "owner_id",
555 "The role ID of the owner of the schema. Corresponds to `mz_roles.id`.",
556 ),
557 ("privileges", "The privileges belonging to the schema."),
558 ]),
559 sql: "
560IN CLUSTER mz_catalog_server
561WITH (
562 ASSERT NOT NULL id,
563 ASSERT NOT NULL oid,
564 ASSERT NOT NULL name,
565 ASSERT NOT NULL owner_id,
566 ASSERT NOT NULL privileges
567) AS
568SELECT
569 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
570 (data->'value'->>'oid')::oid AS oid,
571 CASE WHEN data->'value'->'database_id' != 'null'
572 THEN mz_internal.parse_catalog_id(data->'value'->'database_id')
573 END AS database_id,
574 data->'value'->>'name' AS name,
575 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
576 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges
577FROM mz_internal.mz_catalog_raw
578WHERE data->>'kind' = 'Schema'",
579 is_retained_metrics_object: false,
580 access: vec![PUBLIC_SELECT],
581 ontology: Some(Ontology {
582 entity_name: "schema",
583 description: "A namespace within a database that contains objects",
584 links: &const {
585 [
586 OntologyLink {
587 name: "in_database",
588 target: "database",
589 properties: LinkProperties::fk_nullable(
590 "database_id",
591 "id",
592 Cardinality::ManyToOne,
593 ),
594 },
595 OntologyLink {
596 name: "owned_by",
597 target: "role",
598 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
599 },
600 ]
601 },
602 column_semantic_types: &const {
603 [
604 ("id", SemanticType::SchemaId),
605 ("oid", SemanticType::OID),
606 ("database_id", SemanticType::DatabaseId),
607 ("owner_id", SemanticType::RoleId),
608 ]
609 },
610 }),
611 });
612
613pub static MZ_COLUMNS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
614 let sql = format!(
636 "
637IN CLUSTER mz_catalog_server
638WITH (
639 ASSERT NOT NULL id,
640 ASSERT NOT NULL name,
641 ASSERT NOT NULL position,
642 ASSERT NOT NULL nullable,
643 ASSERT NOT NULL type,
644 ASSERT NOT NULL type_oid,
645 ASSERT NOT NULL type_mod
646) AS
647WITH
648 items AS (
649 SELECT
650 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
651 data->'value'->>'name' AS name,
652 (data->'value'->>'oid')::oid AS oid,
653 -- A table's column defaults as an array in column order
654 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->'column_defaults' AS column_defaults
655 FROM mz_internal.mz_catalog_raw
656 WHERE data->>'kind' = 'Item'
657 ),
658 -- An item's columns are one row whose value lists them in position order.
659 item_columns AS (
660 SELECT
661 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
662 data->'value'->'columns' AS columns
663 FROM mz_internal.mz_catalog_raw
664 WHERE data->>'kind' = 'ItemColumns'
665 ),
666 defaults AS (
667 SELECT i.id, d.ordinality, d.value AS default
668 FROM
669 items AS i,
670 jsonb_array_elements_text(i.column_defaults) WITH ORDINALITY AS d(value, ordinality)
671 ),
672 cols AS (
673 SELECT
674 c.id,
675 col.ordinality,
676 col.value->>'name' AS name,
677 (col.value->>'nullable')::bool AS nullable,
678 (col.value->>'type_oid')::oid AS type_oid,
679 (col.value->>'type_mod')::int4 AS type_mod,
680 -- A column may have a custom type from a `CREATE TYPE` item of a list, map or record type.
681 -- We store the catalog ID of the custom type in the catalog and join on items to get its type
682 -- name and OID
683 CASE
684 WHEN jsonb_typeof(col.value->'custom_type') = 'object'
685 THEN mz_internal.parse_catalog_id(col.value->'custom_type')
686 END AS custom_type
687 FROM
688 item_columns AS c
689 CROSS JOIN LATERAL jsonb_array_elements(c.columns) WITH ORDINALITY AS col(value, ordinality)
690 ),
691 user_columns AS (
692 SELECT
693 c.id,
694 c.name,
695 -- WITH ORDINALITY numbers the list from one, which is what position reports
696 c.ordinality::uint8 AS position,
697 c.nullable,
698 coalesce(custom.name, mz_internal.mz_type_name(c.type_oid), 'unknown') AS type,
699 d.default,
700 coalesce(custom.oid, c.type_oid) AS type_oid,
701 c.type_mod
702 FROM
703 cols AS c
704 JOIN items AS i ON i.id = c.id
705 LEFT JOIN items AS custom ON custom.id = c.custom_type
706 LEFT JOIN defaults AS d ON d.id = c.id AND d.ordinality = c.ordinality
707 ),
708 builtin_relations AS (
709 SELECT
710 's' || (data->'value'->>'catalog_id') AS id,
711 data->'key'->>'schema_name' AS schema_name,
712 data->'key'->>'object_name' AS name
713 FROM mz_internal.mz_catalog_raw
714 WHERE
715 data->>'kind' = 'GidMapping' AND
716 data->'key'->>'object_type' IN ({table}, {source}, {view}, {materialized_view})
717 ),
718 builtin_columns AS (
719 SELECT
720 r.id,
721 b.name,
722 b.position,
723 b.nullable,
724 b.type,
725 b.default,
726 b.type_oid,
727 b.type_mod
728 FROM mz_internal.mz_builtin_columns b
729 JOIN builtin_relations r ON r.schema_name = b.schema_name AND r.name = b.relation_name
730 )
731SELECT * FROM user_columns
732UNION ALL
733SELECT * FROM builtin_columns",
734 table = gid_mapping_object_type(CatalogItemType::Table),
735 source = gid_mapping_object_type(CatalogItemType::Source),
736 view = gid_mapping_object_type(CatalogItemType::View),
737 materialized_view = gid_mapping_object_type(CatalogItemType::MaterializedView),
738 );
739 BuiltinMaterializedView {
740 name: "mz_columns",
741 schema: MZ_CATALOG_SCHEMA,
742 oid: oid::MV_MZ_COLUMNS_OID,
743 desc: RelationDesc::builder()
744 .with_column("id", SqlScalarType::String.nullable(false)) .with_column("name", SqlScalarType::String.nullable(false))
746 .with_column("position", SqlScalarType::UInt64.nullable(false))
747 .with_column("nullable", SqlScalarType::Bool.nullable(false))
748 .with_column("type", SqlScalarType::String.nullable(false))
749 .with_column("default", SqlScalarType::String.nullable(true))
750 .with_column("type_oid", SqlScalarType::Oid.nullable(false))
751 .with_column("type_mod", SqlScalarType::Int32.nullable(false))
752 .finish(),
753 column_comments: BTreeMap::from_iter([
754 (
755 "id",
756 "The unique ID of the table, source, or view containing the column.",
757 ),
758 ("name", "The name of the column."),
759 (
760 "position",
761 "The 1-indexed position of the column in its containing table, source, or view.",
762 ),
763 ("nullable", "Can the column contain a `NULL` value?"),
764 ("type", "The data type of the column."),
765 (
766 "default",
767 "The default expression of the column, or `NULL` if it has none.",
768 ),
769 (
770 "type_oid",
771 "The OID of the type of the column (references `mz_types`).",
772 ),
773 ("type_mod", "The packed type identifier of the column."),
774 ]),
775 sql: Box::leak(sql.into_boxed_str()),
776 is_retained_metrics_object: false,
777 access: vec![PUBLIC_SELECT],
778 ontology: Some(Ontology {
779 entity_name: "column",
780 description: "A column of a relation, with its name, position, type, and nullability",
781 links: &const {
782 [OntologyLink {
783 name: "belongs_to_relation",
784 target: "object",
785 properties: LinkProperties::ForeignKey {
786 source_column: "id",
787 target_column: "id",
788 cardinality: Cardinality::ManyToOne,
789 source_id_type: None,
790 requires_mapping: None,
791 nullable: false,
792 note: Some("id in mz_columns is the relation ID, not a unique column ID"),
793 extra_key_columns: None,
794 },
795 }]
796 },
797 column_semantic_types: &const {
798 [
799 ("id", SemanticType::CatalogItemId),
800 ("type_oid", SemanticType::OID),
801 ]
802 },
803 }),
804 }
805});
806
807const USER_INDEXES_CTE: &str = "\
810 user_indexes AS (
811 SELECT
812 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
813 (data->'value'->>'oid')::oid AS oid,
814 data->'value'->>'name' AS name,
815 parsed->>'on_id' AS on_id,
816 parsed->>'cluster_id' AS cluster_id,
817 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
818 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
819 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
820 FROM
821 mz_internal.mz_catalog_raw
822 CROSS JOIN LATERAL (
823 SELECT mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')
824 ) AS l(parsed)
825 WHERE
826 data->>'kind' = 'Item' AND
827 parsed->>'type' = 'index'
828 )";
829
830const CATALOG_SERVER_CLUSTER_CTE: &str = "\
833 catalog_server_cluster AS (
834 SELECT mz_internal.parse_catalog_id(data->'key'->'id') AS id
835 FROM mz_internal.mz_catalog_raw
836 WHERE data->>'kind' = 'Cluster' AND data->'value'->>'name' = 'mz_catalog_server'
837 )";
838
839const BUILTIN_INDEX_GID_MAPPINGS_CTE: &str = "\
842 builtin_index_gid_mappings AS (
843 SELECT
844 's' || (data->'value'->>'catalog_id') AS id,
845 data->'key'->>'object_name' AS name
846 FROM mz_internal.mz_catalog_raw
847 WHERE
848 data->>'kind' = 'GidMapping' AND
849 data->'key'->>'object_type' = '6'
850 )";
851
852const ON_GID_MAPPINGS_CTE: &str = "\
855 on_gid_mappings AS (
856 SELECT
857 's' || (data->'value'->>'catalog_id') AS id,
858 data->'key'->>'schema_name' AS schema_name,
859 data->'key'->>'object_name' AS object_name
860 FROM mz_internal.mz_catalog_raw
861 WHERE data->>'kind' = 'GidMapping'
862 )";
863
864static GID_MAPPING_CTES: LazyLock<String> =
870 LazyLock::new(|| format!("{BUILTIN_INDEX_GID_MAPPINGS_CTE},\n {ON_GID_MAPPINGS_CTE}"));
871
872pub static MZ_INDEXES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
873 let builtin_indexes_cte = format!("\
877 builtin_indexes AS (
878 SELECT *, mz_internal.redact_sql(create_sql) AS redacted_create_sql
879 FROM (
880 SELECT
881 bigm.id AS id,
882 biv.oid AS oid,
883 biv.name AS name,
884 om.id AS on_id,
885 csc.id AS cluster_id,
886 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
887 'CREATE INDEX \"' || biv.name || '\" IN CLUSTER [' || csc.id || '] ON [' || om.id || ' AS \"' || biv.on_schema_name || '\".\"' || biv.on_name || '\"] (' || biv.key_exprs || ')' AS create_sql
888 FROM mz_internal.mz_builtin_indexes biv
889 JOIN builtin_index_gid_mappings bigm ON bigm.name = biv.name
890 JOIN on_gid_mappings om ON om.schema_name = biv.on_schema_name AND om.object_name = biv.on_name
891 CROSS JOIN catalog_server_cluster csc
892 ) AS t
893 )");
894
895 let introspection_source_indexes_cte = format!("\
896 introspection_source_indexes AS (
897 SELECT *, mz_internal.redact_sql(create_sql) AS redacted_create_sql
898 FROM (
899 SELECT
900 'si' || (isi.data->'value'->>'catalog_id') AS id,
901 (isi.data->'value'->>'oid')::oid AS oid,
902 idx_name || '_' || cluster_id || '_primary_idx' AS name,
903 's' || (gm.data->'value'->>'catalog_id') AS on_id,
904 cluster_id,
905 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
906 'CREATE INDEX \"' || idx_name || '_' || cluster_id || '_primary_idx\" IN CLUSTER [' || cluster_id || '] ON \"mz_introspection\".\"' || idx_name || '\" (' || bli.col_list || ')' AS create_sql
907 FROM mz_internal.mz_catalog_raw AS isi
908 CROSS JOIN LATERAL (
909 SELECT isi.data->'key'->>'name', mz_internal.parse_catalog_id(isi.data->'key'->'cluster_id')
910 ) AS l(idx_name, cluster_id)
911 JOIN mz_internal.mz_catalog_raw AS gm ON
912 gm.data->>'kind' = 'GidMapping' AND
913 gm.data->'key'->>'object_type' = '2' AND
914 gm.data->'key'->>'schema_name' = 'mz_introspection' AND
915 gm.data->'key'->>'object_name' = idx_name
916 JOIN mz_internal.mz_builtin_log_indexes AS bli ON bli.name = idx_name
917 WHERE isi.data->>'kind' = 'ClusterIntrospectionSourceIndex'
918 ) AS t
919 )");
920
921 let gid_mapping_ctes: &str = &GID_MAPPING_CTES;
922 let sql = format!(
923 "
924IN CLUSTER mz_catalog_server
925WITH (
926 ASSERT NOT NULL id,
927 ASSERT NOT NULL oid,
928 ASSERT NOT NULL name,
929 ASSERT NOT NULL on_id,
930 ASSERT NOT NULL cluster_id,
931 ASSERT NOT NULL owner_id,
932 ASSERT NOT NULL create_sql,
933 ASSERT NOT NULL redacted_create_sql
934) AS
935WITH
936{USER_INDEXES_CTE},
937{CATALOG_SERVER_CLUSTER_CTE},
938{gid_mapping_ctes},
939{builtin_indexes_cte},
940{introspection_source_indexes_cte}
941SELECT * FROM user_indexes
942UNION ALL
943SELECT * FROM builtin_indexes
944UNION ALL
945SELECT * FROM introspection_source_indexes
946"
947 );
948
949 BuiltinMaterializedView {
950 name: "mz_indexes",
951 schema: MZ_CATALOG_SCHEMA,
952 oid: oid::MV_MZ_INDEXES_OID,
953 desc: RelationDesc::builder()
954 .with_column("id", SqlScalarType::String.nullable(false))
955 .with_column("oid", SqlScalarType::Oid.nullable(false))
956 .with_column("name", SqlScalarType::String.nullable(false))
957 .with_column("on_id", SqlScalarType::String.nullable(false))
958 .with_column("cluster_id", SqlScalarType::String.nullable(false))
959 .with_column("owner_id", SqlScalarType::String.nullable(false))
960 .with_column("create_sql", SqlScalarType::String.nullable(false))
961 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
962 .with_key(vec![0])
963 .with_key(vec![1])
964 .finish(),
965 column_comments: BTreeMap::from_iter([
966 ("id", "Materialize's unique ID for the index."),
967 ("oid", "A PostgreSQL-compatible OID for the index."),
968 ("name", "The name of the index."),
969 (
970 "on_id",
971 "The ID of the relation on which the index is built.",
972 ),
973 (
974 "cluster_id",
975 "The ID of the cluster in which the index is built.",
976 ),
977 (
978 "owner_id",
979 "The role ID of the owner of the index. Corresponds to `mz_roles.id`.",
980 ),
981 ("create_sql", "The `CREATE` SQL statement for the index."),
982 (
983 "redacted_create_sql",
984 "The redacted `CREATE` SQL statement for the index.",
985 ),
986 ]),
987 sql: Box::leak(sql.into_boxed_str()),
988 is_retained_metrics_object: false,
989 access: vec![PUBLIC_SELECT],
990 ontology: Some(Ontology {
991 entity_name: "index",
992 description: "An in-memory index on a relation for fast lookups",
993 links: &const {
994 [
995 OntologyLink {
996 name: "owned_by",
997 target: "role",
998 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
999 },
1000 OntologyLink {
1001 name: "runs_on_cluster",
1002 target: "cluster",
1003 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
1004 },
1005 OntologyLink {
1006 name: "indexes_relation",
1007 target: "relation",
1008 properties: LinkProperties::fk("on_id", "id", Cardinality::ManyToOne),
1009 },
1010 ]
1011 },
1012 column_semantic_types: &const {
1013 [
1014 ("id", SemanticType::CatalogItemId),
1015 ("oid", SemanticType::OID),
1016 ("on_id", SemanticType::CatalogItemId),
1017 ("cluster_id", SemanticType::ClusterId),
1018 ("owner_id", SemanticType::RoleId),
1019 ("create_sql", SemanticType::SqlDefinition),
1020 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
1021 ]
1022 },
1023 }),
1024 }
1025});
1026pub static MZ_INDEX_COLUMNS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1027 let sql = format!(
1028 "
1029IN CLUSTER mz_catalog_server
1030WITH (
1031 ASSERT NOT NULL index_id,
1032 ASSERT NOT NULL index_position,
1033 ASSERT NOT NULL nullable
1034) AS
1035WITH
1036 -- An index's keys are one row whose value lists them in key order.
1037 index_keys AS (
1038 SELECT
1039 mz_internal.parse_catalog_id(k.data->'key'->'id') AS index_id,
1040 k.data->'value'->'columns' AS columns,
1041 mz_internal.parse_catalog_create_sql(i.data->'value'->'definition'->'V1'->>'create_sql')->'key_parts' AS key_parts
1042 FROM
1043 mz_internal.mz_catalog_raw AS k
1044 -- Filter to index items so the join arranges only their rows. A
1045 -- persisted index's create_sql always starts with `CREATE INDEX`
1046 JOIN mz_internal.mz_catalog_raw AS i ON
1047 i.data->>'kind' = 'Item' AND
1048 i.data->'value'->'definition'->'V1'->>'create_sql' LIKE 'CREATE INDEX %' AND
1049 i.data->'key'->'gid' = k.data->'key'->'id'
1050 WHERE k.data->>'kind' = 'IndexColumns'
1051 ),
1052 key_parts AS (
1053 SELECT k.index_id, p.ordinality, p.value AS expression
1054 FROM
1055 index_keys AS k,
1056 jsonb_array_elements_text(k.key_parts) WITH ORDINALITY AS p(value, ordinality)
1057 ),
1058 user_index_columns AS (
1059 SELECT
1060 k.index_id,
1061 -- WITH ORDINALITY numbers the list from one, which is what index_position reports
1062 ik.ordinality::uint8 AS index_position,
1063 (ik.value->>'column')::uint8 + 1::uint8 AS on_position,
1064 -- Either on_position is null or on_expression is, thus we use a case
1065 CASE
1066 WHEN ik.value->>'column' IS NULL
1067 THEN p.expression
1068 END AS on_expression,
1069 (ik.value->>'nullable')::bool AS nullable
1070 FROM
1071 index_keys AS k
1072 CROSS JOIN LATERAL jsonb_array_elements(k.columns) WITH ORDINALITY AS ik(value, ordinality)
1073 LEFT JOIN key_parts AS p ON p.index_id = k.index_id AND p.ordinality = ik.ordinality
1074 ),
1075{BUILTIN_INDEX_GID_MAPPINGS_CTE},
1076 builtin_index_columns AS (
1077 SELECT
1078 bigm.id AS index_id,
1079 bic.index_position,
1080 bic.on_position,
1081 NULL::text AS on_expression,
1082 bic.nullable
1083 FROM mz_internal.mz_builtin_index_columns AS bic
1084 JOIN builtin_index_gid_mappings AS bigm ON bigm.name = bic.name
1085 WHERE bic.type = 'index'
1086 ),
1087 introspection_source_index_columns AS (
1088 SELECT
1089 'si' || (isi.data->'value'->>'catalog_id') AS index_id,
1090 bic.index_position,
1091 bic.on_position,
1092 NULL::text AS on_expression,
1093 bic.nullable
1094 FROM mz_internal.mz_catalog_raw AS isi
1095 JOIN mz_internal.mz_builtin_index_columns AS bic ON bic.name = isi.data->'key'->>'name'
1096 WHERE
1097 isi.data->>'kind' = 'ClusterIntrospectionSourceIndex' AND
1098 bic.type = 'log'
1099 )
1100SELECT * FROM user_index_columns
1101UNION ALL
1102SELECT * FROM builtin_index_columns
1103UNION ALL
1104SELECT * FROM introspection_source_index_columns"
1105 );
1106
1107 BuiltinMaterializedView {
1108 name: "mz_index_columns",
1109 schema: MZ_CATALOG_SCHEMA,
1110 oid: oid::MV_MZ_INDEX_COLUMNS_OID,
1111 desc: RelationDesc::builder()
1112 .with_column("index_id", SqlScalarType::String.nullable(false))
1113 .with_column("index_position", SqlScalarType::UInt64.nullable(false))
1114 .with_column("on_position", SqlScalarType::UInt64.nullable(true))
1115 .with_column("on_expression", SqlScalarType::String.nullable(true))
1116 .with_column("nullable", SqlScalarType::Bool.nullable(false))
1117 .finish(),
1118 column_comments: BTreeMap::from_iter([
1119 (
1120 "index_id",
1121 "The ID of the index which contains this column. Corresponds to `mz_indexes.id`.",
1122 ),
1123 (
1124 "index_position",
1125 "The 1-indexed position of this column within the index. (The order of columns in an index does not necessarily match the order of columns in the relation on which the index is built.)",
1126 ),
1127 (
1128 "on_position",
1129 "If not `NULL`, specifies the 1-indexed position of a column in the relation on which this index is built that determines the value of this index column.",
1130 ),
1131 (
1132 "on_expression",
1133 "If not `NULL`, specifies a SQL expression that is evaluated to compute the value of this index column. The expression may contain references to any of the columns of the relation.",
1134 ),
1135 (
1136 "nullable",
1137 "Can this column of the index evaluate to `NULL`?",
1138 ),
1139 ]),
1140 sql: Box::leak(sql.into_boxed_str()),
1141 is_retained_metrics_object: false,
1142 access: vec![PUBLIC_SELECT],
1143 ontology: Some(Ontology {
1144 entity_name: "index_column",
1145 description: "A column or expression in an index, with its position",
1146 links: &const {
1147 [OntologyLink {
1148 name: "belongs_to_index",
1149 target: "index",
1150 properties: LinkProperties::fk("index_id", "id", Cardinality::ManyToOne),
1151 }]
1152 },
1153 column_semantic_types: &[("index_id", SemanticType::CatalogItemId)],
1154 }),
1155 }
1156});
1157pub static MZ_TABLES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1158 BuiltinMaterializedView {
1159 name: "mz_tables",
1160 schema: MZ_CATALOG_SCHEMA,
1161 oid: oid::MV_MZ_TABLES_OID,
1162 desc: RelationDesc::builder()
1163 .with_column("id", SqlScalarType::String.nullable(false))
1164 .with_column("oid", SqlScalarType::Oid.nullable(false))
1165 .with_column("schema_id", SqlScalarType::String.nullable(false))
1166 .with_column("name", SqlScalarType::String.nullable(false))
1167 .with_column("owner_id", SqlScalarType::String.nullable(false))
1168 .with_column(
1169 "privileges",
1170 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1171 )
1172 .with_column("create_sql", SqlScalarType::String.nullable(true))
1173 .with_column("redacted_create_sql", SqlScalarType::String.nullable(true))
1174 .with_column("source_id", SqlScalarType::String.nullable(true))
1175 .with_key(vec![0])
1176 .with_key(vec![1])
1177 .finish(),
1178 column_comments: BTreeMap::from_iter([
1179 ("id", "Materialize's unique ID for the table."),
1180 ("oid", "A PostgreSQL-compatible OID for the table."),
1181 (
1182 "schema_id",
1183 "The ID of the schema to which the table belongs. Corresponds to `mz_schemas.id`.",
1184 ),
1185 ("name", "The name of the table."),
1186 (
1187 "owner_id",
1188 "The role ID of the owner of the table. Corresponds to `mz_roles.id`.",
1189 ),
1190 ("privileges", "The privileges belonging to the table."),
1191 ("create_sql", "The `CREATE` SQL statement for the table."),
1192 (
1193 "redacted_create_sql",
1194 "The redacted `CREATE` SQL statement for the table.",
1195 ),
1196 (
1197 "source_id",
1198 "The ID of the source associated with the table, if any. Corresponds to `mz_sources.id`.",
1199 ),
1200 ]),
1201 sql: Box::leak(format!("
1205IN CLUSTER mz_catalog_server
1206WITH (
1207 ASSERT NOT NULL id,
1208 ASSERT NOT NULL oid,
1209 ASSERT NOT NULL schema_id,
1210 ASSERT NOT NULL name,
1211 ASSERT NOT NULL owner_id,
1212 ASSERT NOT NULL privileges
1213) AS
1214WITH
1215 user_tables AS (
1216 SELECT
1217 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
1218 (data->'value'->>'oid')::oid AS oid,
1219 CASE WHEN data->'value'->>'ephemeral_owner_session' IS NULL
1220 THEN mz_internal.parse_catalog_id(data->'value'->'schema_id')
1221 ELSE '0'
1222 END AS schema_id,
1223 data->'value'->>'name' AS name,
1224 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
1225 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
1226 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
1227 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql,
1228 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'source_id' AS source_id
1229 FROM mz_internal.mz_catalog_raw
1230 WHERE
1231 data->>'kind' = 'Item' AND
1232 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'type' = 'table'
1233 ),
1234 builtin_mappings AS (
1235 SELECT
1236 data->'key'->>'schema_name' AS schema_name,
1237 data->'key'->>'object_name' AS name,
1238 's' || (data->'value'->>'catalog_id') AS id
1239 FROM mz_internal.mz_catalog_raw
1240 WHERE
1241 data->>'kind' = 'GidMapping' AND
1242 data->'key'->>'object_type' = '1'
1243 ),
1244 builtin_tables AS (
1245 SELECT
1246 m.id,
1247 t.oid,
1248 s.id AS schema_id,
1249 t.name,
1250 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
1251 t.privileges,
1252 NULL::text AS create_sql,
1253 NULL::text AS redacted_create_sql,
1254 NULL::text AS source_id
1255 FROM mz_internal.mz_builtin_tables t
1256 JOIN builtin_mappings m USING (schema_name, name)
1257 JOIN mz_schemas s ON s.name = t.schema_name
1258 WHERE s.database_id IS NULL
1259 )
1260SELECT * FROM user_tables
1261UNION ALL
1262SELECT * FROM builtin_tables").into_boxed_str()),
1263 is_retained_metrics_object: true,
1264 access: vec![PUBLIC_SELECT],
1265 ontology: Some(Ontology {
1266 entity_name: "table",
1267 description: "A user-writable table that can be inserted into and updated",
1268 links: &const {
1269 [
1270 OntologyLink {
1271 name: "in_schema",
1272 target: "schema",
1273 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1274 },
1275 OntologyLink {
1276 name: "owned_by",
1277 target: "role",
1278 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1279 },
1280 OntologyLink {
1281 name: "created_by_source",
1282 target: "source",
1283 properties: LinkProperties::fk_nullable(
1284 "source_id",
1285 "id",
1286 Cardinality::ManyToOne,
1287 ),
1288 },
1289 ]
1290 },
1291 column_semantic_types: &const {
1292 [
1293 ("id", SemanticType::CatalogItemId),
1294 ("oid", SemanticType::OID),
1295 ("schema_id", SemanticType::SchemaId),
1296 ("owner_id", SemanticType::RoleId),
1297 ("create_sql", SemanticType::SqlDefinition),
1298 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
1299 ("source_id", SemanticType::CatalogItemId),
1300 ]
1301 },
1302 }),
1303}
1304});
1305
1306pub static MZ_CONNECTIONS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1307 BuiltinMaterializedView {
1308 name: "mz_connections",
1309 schema: MZ_CATALOG_SCHEMA,
1310 oid: oid::MV_MZ_CONNECTIONS_OID,
1311 desc: RelationDesc::builder()
1312 .with_column("id", SqlScalarType::String.nullable(false))
1313 .with_column("oid", SqlScalarType::Oid.nullable(false))
1314 .with_column("schema_id", SqlScalarType::String.nullable(false))
1315 .with_column("name", SqlScalarType::String.nullable(false))
1316 .with_column("type", SqlScalarType::String.nullable(false))
1317 .with_column("owner_id", SqlScalarType::String.nullable(false))
1318 .with_column(
1319 "privileges",
1320 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1321 )
1322 .with_column("create_sql", SqlScalarType::String.nullable(false))
1323 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
1324 .with_key(vec![0])
1325 .with_key(vec![1])
1326 .finish(),
1327 column_comments: BTreeMap::from_iter([
1328 ("id", "The unique ID of the connection."),
1329 ("oid", "A PostgreSQL-compatible OID for the connection."),
1330 (
1331 "schema_id",
1332 "The ID of the schema to which the connection belongs. Corresponds to `mz_schemas.id`.",
1333 ),
1334 ("name", "The name of the connection."),
1335 (
1336 "type",
1337 "The type of the connection: `confluent-schema-registry`, `kafka`, `postgres`, or `ssh-tunnel`.",
1338 ),
1339 (
1340 "owner_id",
1341 "The role ID of the owner of the connection. Corresponds to `mz_roles.id`.",
1342 ),
1343 ("privileges", "The privileges belonging to the connection."),
1344 (
1345 "create_sql",
1346 "The `CREATE` SQL statement for the connection.",
1347 ),
1348 (
1349 "redacted_create_sql",
1350 "The redacted `CREATE` SQL statement for the connection.",
1351 ),
1352 ]),
1353 sql: "
1354IN CLUSTER mz_catalog_server
1355WITH (
1356 ASSERT NOT NULL id,
1357 ASSERT NOT NULL oid,
1358 ASSERT NOT NULL schema_id,
1359 ASSERT NOT NULL name,
1360 ASSERT NOT NULL type,
1361 ASSERT NOT NULL owner_id,
1362 ASSERT NOT NULL privileges,
1363 ASSERT NOT NULL create_sql,
1364 ASSERT NOT NULL redacted_create_sql
1365) AS
1366SELECT
1367 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
1368 (data->'value'->>'oid')::oid AS oid,
1369 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
1370 data->'value'->>'name' AS name,
1371 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'connection_type' AS type,
1372 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
1373 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
1374 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
1375 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
1376FROM mz_internal.mz_catalog_raw
1377WHERE
1378 data->>'kind' = 'Item' AND
1379 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'type' = 'connection'",
1380 is_retained_metrics_object: false,
1381 access: vec![PUBLIC_SELECT],
1382 ontology: Some(Ontology {
1383 entity_name: "connection",
1384 description: "A reusable connection configuration to an external system",
1385 links: &const { [
1386 OntologyLink {
1387 name: "in_schema",
1388 target: "schema",
1389 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1390 },
1391 OntologyLink {
1392 name: "owned_by",
1393 target: "role",
1394 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1395 },
1396 ] },
1397 column_semantic_types: &const {[("id", SemanticType::CatalogItemId), ("oid", SemanticType::OID), ("schema_id", SemanticType::SchemaId), ("type", SemanticType::ConnectionType), ("owner_id", SemanticType::RoleId), ("create_sql", SemanticType::SqlDefinition), ("redacted_create_sql", SemanticType::RedactedSqlDefinition)]},
1398 }),
1399 }
1400});
1401
1402pub static MZ_SSH_TUNNEL_CONNECTIONS: LazyLock<BuiltinMaterializedView> =
1407 LazyLock::new(|| BuiltinMaterializedView {
1408 name: "mz_ssh_tunnel_connections",
1409 schema: MZ_CATALOG_SCHEMA,
1410 oid: oid::MV_MZ_SSH_TUNNEL_CONNECTIONS_OID,
1411 desc: RelationDesc::builder()
1412 .with_column("id", SqlScalarType::String.nullable(false))
1413 .with_column("public_key_1", SqlScalarType::String.nullable(false))
1414 .with_column("public_key_2", SqlScalarType::String.nullable(false))
1415 .with_key(vec![0])
1416 .finish(),
1417 column_comments: BTreeMap::from_iter([
1418 ("id", "The ID of the connection."),
1419 (
1420 "public_key_1",
1421 "The first public key associated with the SSH tunnel.",
1422 ),
1423 (
1424 "public_key_2",
1425 "The second public key associated with the SSH tunnel.",
1426 ),
1427 ]),
1428 sql: "
1429IN CLUSTER mz_catalog_server
1430WITH (
1431 ASSERT NOT NULL id,
1432 ASSERT NOT NULL public_key_1,
1433 ASSERT NOT NULL public_key_2
1434) AS
1435SELECT
1436 mz_internal.parse_catalog_id(r.data->'key'->'gid') AS id,
1437 details->>'public_key_1' AS public_key_1,
1438 details->>'public_key_2' AS public_key_2
1439FROM
1440 mz_internal.mz_catalog_raw r,
1441 LATERAL (
1442 SELECT mz_internal.parse_connection_details(
1443 r.data->'value'->'definition'->'V1'->>'create_sql')
1444 ) AS d(details)
1445WHERE
1446 r.data->>'kind' = 'Item' AND
1447 -- The connection_type filter selects the kind. A non-matching row yields a
1448 -- NULL connection_type and is dropped here, so no `details IS NOT NULL` is
1449 -- needed (parse_connection_details returns jsonb null, which passes it).
1450 mz_internal.parse_catalog_create_sql(
1451 r.data->'value'->'definition'->'V1'->>'create_sql')->>'connection_type' = 'ssh-tunnel'",
1452 is_retained_metrics_object: false,
1453 access: vec![PUBLIC_SELECT],
1454 ontology: Some(Ontology {
1455 entity_name: "ssh_tunnel_connection",
1456 description: "SSH tunnel connection with public keys",
1457 links: &const {
1458 [OntologyLink {
1459 name: "details_of",
1460 target: "connection",
1461 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
1462 }]
1463 },
1464 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
1465 }),
1466 });
1467pub static MZ_SOURCES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1468 let sql = format!("
1469IN CLUSTER mz_catalog_server
1470WITH (
1471 ASSERT NOT NULL id,
1472 ASSERT NOT NULL oid,
1473 ASSERT NOT NULL schema_id,
1474 ASSERT NOT NULL name,
1475 ASSERT NOT NULL type,
1476 ASSERT NOT NULL owner_id,
1477 ASSERT NOT NULL privileges
1478) AS
1479WITH
1480 user_sources AS (
1481 SELECT
1482 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
1483 (data->'value'->>'oid')::oid AS oid,
1484 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
1485 data->'value'->>'name' AS name,
1486 parsed->>'source_type' AS type,
1487 parsed->>'connection_id' AS connection_id,
1488 NULL AS size,
1489 parsed->>'envelope_type' AS envelope_type,
1490 parsed->>'key_format' AS key_format,
1491 parsed->>'value_format' AS value_format,
1492 COALESCE(
1493 parsed->>'cluster_id',
1494 (
1495 SELECT mz_internal.parse_catalog_create_sql(p.data->'value'->'definition'->'V1'->>'create_sql')->>'cluster_id'
1496 FROM mz_internal.mz_catalog_raw p
1497 WHERE
1498 p.data->>'kind' = 'Item' AND
1499 mz_internal.parse_catalog_id(p.data->'key'->'gid') = parsed->>'of_source_id'
1500 )
1501 ) AS cluster_id,
1502 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
1503 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
1504 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
1505 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
1506 FROM
1507 mz_internal.mz_catalog_raw
1508 CROSS JOIN LATERAL (
1509 SELECT mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')
1510 ) AS l(parsed)
1511 WHERE
1512 data->>'kind' = 'Item' AND
1513 parsed->>'type' IN ('source', 'subsource')
1514 ),
1515 builtin_mappings AS (
1516 SELECT
1517 data->'key'->>'schema_name' AS schema_name,
1518 data->'key'->>'object_name' AS name,
1519 's' || (data->'value'->>'catalog_id') AS id
1520 FROM mz_internal.mz_catalog_raw
1521 WHERE
1522 data->>'kind' = 'GidMapping' AND
1523 data->'key'->>'object_type' = '2'
1524 ),
1525 builtin_sources AS (
1526 SELECT
1527 m.id,
1528 src.oid,
1529 s.id AS schema_id,
1530 src.name,
1531 src.type,
1532 NULL AS connection_id,
1533 NULL AS size,
1534 NULL AS envelope_type,
1535 NULL AS key_format,
1536 NULL AS value_format,
1537 NULL AS cluster_id,
1538 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
1539 src.privileges,
1540 NULL AS create_sql,
1541 NULL AS redacted_create_sql
1542 FROM mz_internal.mz_builtin_sources AS src
1543 JOIN builtin_mappings m USING (schema_name, name)
1544 JOIN mz_schemas s ON s.name = src.schema_name
1545 WHERE s.database_id IS NULL
1546 )
1547SELECT * FROM user_sources
1548UNION ALL
1549SELECT * FROM builtin_sources");
1550
1551 BuiltinMaterializedView {
1552 name: "mz_sources",
1553 schema: MZ_CATALOG_SCHEMA,
1554 oid: oid::MV_MZ_SOURCES_OID,
1555 desc: RelationDesc::builder()
1556 .with_column("id", SqlScalarType::String.nullable(false))
1557 .with_column("oid", SqlScalarType::Oid.nullable(false))
1558 .with_column("schema_id", SqlScalarType::String.nullable(false))
1559 .with_column("name", SqlScalarType::String.nullable(false))
1560 .with_column("type", SqlScalarType::String.nullable(false))
1561 .with_column("connection_id", SqlScalarType::String.nullable(true))
1562 .with_column("size", SqlScalarType::String.nullable(true))
1563 .with_column("envelope_type", SqlScalarType::String.nullable(true))
1564 .with_column("key_format", SqlScalarType::String.nullable(true))
1565 .with_column("value_format", SqlScalarType::String.nullable(true))
1566 .with_column("cluster_id", SqlScalarType::String.nullable(true))
1567 .with_column("owner_id", SqlScalarType::String.nullable(false))
1568 .with_column(
1569 "privileges",
1570 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1571 )
1572 .with_column("create_sql", SqlScalarType::String.nullable(true))
1573 .with_column("redacted_create_sql", SqlScalarType::String.nullable(true))
1574 .with_key(vec![0])
1575 .with_key(vec![1])
1576 .finish(),
1577 column_comments: BTreeMap::from_iter([
1578 ("id", "Materialize's unique ID for the source."),
1579 ("oid", "A PostgreSQL-compatible OID for the source."),
1580 (
1581 "schema_id",
1582 "The ID of the schema to which the source belongs. Corresponds to `mz_schemas.id`.",
1583 ),
1584 ("name", "The name of the source."),
1585 (
1586 "type",
1587 "The type of the source: `kafka`, `mysql`, `postgres`, `load-generator`, `progress`, or `subsource`.",
1588 ),
1589 (
1590 "connection_id",
1591 "The ID of the connection associated with the source, if any. Corresponds to `mz_connections.id`.",
1592 ),
1593 ("size", "*Deprecated* The size of the source."),
1594 (
1595 "envelope_type",
1596 "For old-syntax Kafka sources, the envelope type: `none`, `upsert`, or `debezium`. `NULL` for new-syntax Kafka sources, whose envelopes are defined per source table (see `mz_kafka_source_tables`), and for other source types.",
1597 ),
1598 (
1599 "key_format",
1600 "For Kafka sources, the format of the Kafka message key: `avro`, `csv`, `regex`, `bytes`, `json`, `text`, or `NULL`.",
1601 ),
1602 (
1603 "value_format",
1604 "For Kafka sources, the format of the Kafka message value: `avro`, `csv`, `regex`, `bytes`, `json`, `text`. `NULL` for other source types.",
1605 ),
1606 (
1607 "cluster_id",
1608 "The ID of the cluster maintaining the source. Corresponds to `mz_clusters.id`.",
1609 ),
1610 (
1611 "owner_id",
1612 "The role ID of the owner of the source. Corresponds to `mz_roles.id`.",
1613 ),
1614 ("privileges", "The privileges granted on the source."),
1615 ("create_sql", "The `CREATE` SQL statement for the source."),
1616 (
1617 "redacted_create_sql",
1618 "The redacted `CREATE` SQL statement for the source.",
1619 ),
1620 ]),
1621 sql: Box::leak(sql.into_boxed_str()),
1622 is_retained_metrics_object: true,
1623 access: vec![PUBLIC_SELECT],
1624 ontology: Some(Ontology {
1625 entity_name: "source",
1626 description: "An external data source ingested into Materialize (e.g., Kafka, Postgres)",
1627 links: &const {
1628 [
1629 OntologyLink {
1630 name: "in_schema",
1631 target: "schema",
1632 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1633 },
1634 OntologyLink {
1635 name: "owned_by",
1636 target: "role",
1637 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1638 },
1639 OntologyLink {
1640 name: "runs_on_cluster",
1641 target: "cluster",
1642 properties: LinkProperties::fk_nullable(
1643 "cluster_id",
1644 "id",
1645 Cardinality::ManyToOne,
1646 ),
1647 },
1648 OntologyLink {
1649 name: "uses_connection",
1650 target: "connection",
1651 properties: LinkProperties::fk_nullable(
1652 "connection_id",
1653 "id",
1654 Cardinality::ManyToOne,
1655 ),
1656 },
1657 ]
1658 },
1659 column_semantic_types: &const {
1660 [
1661 ("id", SemanticType::CatalogItemId),
1662 ("oid", SemanticType::OID),
1663 ("schema_id", SemanticType::SchemaId),
1664 ("type", SemanticType::SourceType),
1665 ("connection_id", SemanticType::CatalogItemId),
1666 ("cluster_id", SemanticType::ClusterId),
1667 ("owner_id", SemanticType::RoleId),
1668 ("create_sql", SemanticType::SqlDefinition),
1669 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
1670 ]
1671 },
1672 }),
1673 }
1674});
1675pub static MZ_SINKS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1680 BuiltinMaterializedView {
1681 name: "mz_sinks",
1682 schema: MZ_CATALOG_SCHEMA,
1683 oid: oid::MV_MZ_SINKS_OID,
1684 desc: RelationDesc::builder()
1685 .with_column("id", SqlScalarType::String.nullable(false))
1686 .with_column("oid", SqlScalarType::Oid.nullable(false))
1687 .with_column("schema_id", SqlScalarType::String.nullable(false))
1688 .with_column("name", SqlScalarType::String.nullable(false))
1689 .with_column("type", SqlScalarType::String.nullable(false))
1690 .with_column("connection_id", SqlScalarType::String.nullable(true))
1691 .with_column("size", SqlScalarType::String.nullable(true))
1692 .with_column("envelope_type", SqlScalarType::String.nullable(true))
1693 .with_column("format", SqlScalarType::String.nullable(true))
1696 .with_column("key_format", SqlScalarType::String.nullable(true))
1697 .with_column("value_format", SqlScalarType::String.nullable(true))
1698 .with_column("cluster_id", SqlScalarType::String.nullable(false))
1699 .with_column("owner_id", SqlScalarType::String.nullable(false))
1700 .with_column("create_sql", SqlScalarType::String.nullable(false))
1701 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
1702 .with_key(vec![0])
1703 .with_key(vec![1])
1704 .finish(),
1705 column_comments: BTreeMap::from_iter([
1706 ("id", "Materialize's unique ID for the sink."),
1707 ("oid", "A PostgreSQL-compatible OID for the sink."),
1708 (
1709 "schema_id",
1710 "The ID of the schema to which the sink belongs. Corresponds to `mz_schemas.id`.",
1711 ),
1712 ("name", "The name of the sink."),
1713 ("type", "The type of the sink: `kafka`."),
1714 (
1715 "connection_id",
1716 "The ID of the connection associated with the sink, if any. Corresponds to `mz_connections.id`.",
1717 ),
1718 ("size", "The size of the sink."),
1719 (
1720 "envelope_type",
1721 "The envelope of the sink: `upsert`, or `debezium`.",
1722 ),
1723 (
1724 "format",
1725 "*Deprecated* The format of the Kafka messages produced by the sink: `avro`, `json`, `text`, or `bytes`.",
1726 ),
1727 (
1728 "key_format",
1729 "The format of the Kafka message key for messages produced by the sink: `avro`, `json`, `bytes`, `text`, or `NULL`.",
1730 ),
1731 (
1732 "value_format",
1733 "The format of the Kafka message value for messages produced by the sink: `avro`, `json`, `text`, or `bytes`.",
1734 ),
1735 (
1736 "cluster_id",
1737 "The ID of the cluster maintaining the sink. Corresponds to `mz_clusters.id`.",
1738 ),
1739 (
1740 "owner_id",
1741 "The role ID of the owner of the sink. Corresponds to `mz_roles.id`.",
1742 ),
1743 ("create_sql", "The `CREATE` SQL statement for the sink."),
1744 (
1745 "redacted_create_sql",
1746 "The redacted `CREATE` SQL statement for the sink.",
1747 ),
1748 ]),
1749 sql: "
1750IN CLUSTER mz_catalog_server
1751WITH (
1752 ASSERT NOT NULL id,
1753 ASSERT NOT NULL oid,
1754 ASSERT NOT NULL schema_id,
1755 ASSERT NOT NULL name,
1756 ASSERT NOT NULL type,
1757 ASSERT NOT NULL cluster_id,
1758 ASSERT NOT NULL owner_id,
1759 ASSERT NOT NULL create_sql,
1760 ASSERT NOT NULL redacted_create_sql
1761) AS
1762SELECT
1763 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
1764 (data->'value'->>'oid')::oid AS oid,
1765 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
1766 data->'value'->>'name' AS name,
1767 parsed->>'sink_type' AS type,
1768 parsed->>'connection_id' AS connection_id,
1769 NULL::text AS size,
1770 parsed->>'envelope_type' AS envelope_type,
1771 parsed->>'format' AS format,
1772 parsed->>'key_format' AS key_format,
1773 parsed->>'value_format' AS value_format,
1774 parsed->>'cluster_id' AS cluster_id,
1775 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
1776 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
1777 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
1778FROM
1779 mz_internal.mz_catalog_raw
1780 CROSS JOIN LATERAL (
1781 SELECT mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')
1782 ) AS l(parsed)
1783WHERE
1784 data->>'kind' = 'Item' AND
1785 parsed->>'type' = 'sink'",
1786 is_retained_metrics_object: true,
1787 access: vec![PUBLIC_SELECT],
1788 ontology: Some(Ontology {
1789 entity_name: "sink",
1790 description: "An export of data from Materialize to an external system",
1791 links: &const {
1792 [
1793 OntologyLink {
1794 name: "in_schema",
1795 target: "schema",
1796 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1797 },
1798 OntologyLink {
1799 name: "owned_by",
1800 target: "role",
1801 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1802 },
1803 OntologyLink {
1804 name: "runs_on_cluster",
1805 target: "cluster",
1806 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
1807 },
1808 OntologyLink {
1809 name: "uses_connection",
1810 target: "connection",
1811 properties: LinkProperties::fk_nullable(
1812 "connection_id",
1813 "id",
1814 Cardinality::ManyToOne,
1815 ),
1816 },
1817 ]
1818 },
1819 column_semantic_types: &const {
1820 [
1821 ("id", SemanticType::CatalogItemId),
1822 ("oid", SemanticType::OID),
1823 ("schema_id", SemanticType::SchemaId),
1824 ("connection_id", SemanticType::CatalogItemId),
1825 ("cluster_id", SemanticType::ClusterId),
1826 ("owner_id", SemanticType::RoleId),
1827 ("create_sql", SemanticType::SqlDefinition),
1828 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
1829 ]
1830 },
1831 }),
1832 }
1833});
1834pub static MZ_VIEWS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1835 BuiltinMaterializedView {
1836 name: "mz_views",
1837 schema: MZ_CATALOG_SCHEMA,
1838 oid: oid::MV_MZ_VIEWS_OID,
1839 desc: RelationDesc::builder()
1840 .with_column("id", SqlScalarType::String.nullable(false))
1841 .with_column("oid", SqlScalarType::Oid.nullable(false))
1842 .with_column("schema_id", SqlScalarType::String.nullable(false))
1843 .with_column("name", SqlScalarType::String.nullable(false))
1844 .with_column("definition", SqlScalarType::String.nullable(false))
1845 .with_column("owner_id", SqlScalarType::String.nullable(false))
1846 .with_column(
1847 "privileges",
1848 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1849 )
1850 .with_column("create_sql", SqlScalarType::String.nullable(false))
1851 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
1852 .with_key(vec![0])
1853 .with_key(vec![1])
1854 .finish(),
1855 column_comments: BTreeMap::from_iter([
1856 ("id", "Materialize's unique ID for the view."),
1857 ("oid", "A PostgreSQL-compatible OID for the view."),
1858 (
1859 "schema_id",
1860 "The ID of the schema to which the view belongs. Corresponds to `mz_schemas.id`.",
1861 ),
1862 ("name", "The name of the view."),
1863 ("definition", "The view definition (a `SELECT` query)."),
1864 (
1865 "owner_id",
1866 "The role ID of the owner of the view. Corresponds to `mz_roles.id`.",
1867 ),
1868 ("privileges", "The privileges belonging to the view."),
1869 ("create_sql", "The `CREATE` SQL statement for the view."),
1870 (
1871 "redacted_create_sql",
1872 "The redacted `CREATE` SQL statement for the view.",
1873 ),
1874 ]),
1875 sql: Box::leak(format!("
1882IN CLUSTER mz_catalog_server
1883WITH (
1884 ASSERT NOT NULL id,
1885 ASSERT NOT NULL oid,
1886 ASSERT NOT NULL schema_id,
1887 ASSERT NOT NULL name,
1888 ASSERT NOT NULL definition,
1889 ASSERT NOT NULL owner_id,
1890 ASSERT NOT NULL privileges,
1891 ASSERT NOT NULL create_sql,
1892 ASSERT NOT NULL redacted_create_sql
1893) AS
1894WITH
1895 user_views AS (
1896 SELECT
1897 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
1898 (data->'value'->>'oid')::oid AS oid,
1899 CASE WHEN data->'value'->>'ephemeral_owner_session' IS NULL
1900 THEN mz_internal.parse_catalog_id(data->'value'->'schema_id')
1901 ELSE '0'
1902 END AS schema_id,
1903 data->'value'->>'name' AS name,
1904 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'definition' AS definition,
1905 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
1906 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
1907 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
1908 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
1909 FROM mz_internal.mz_catalog_raw
1910 WHERE
1911 data->>'kind' = 'Item' AND
1912 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'type' = 'view'
1913 ),
1914 builtin_mappings AS (
1915 SELECT
1916 data->'key'->>'schema_name' AS schema_name,
1917 data->'key'->>'object_name' AS name,
1918 's' || (data->'value'->>'catalog_id') AS id
1919 FROM mz_internal.mz_catalog_raw
1920 WHERE
1921 data->>'kind' = 'GidMapping' AND
1922 data->'key'->>'object_type' = '4'
1923 ),
1924 builtin_views AS (
1925 SELECT
1926 m.id,
1927 v.oid,
1928 s.id AS schema_id,
1929 v.name,
1930 v.definition,
1931 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
1932 v.privileges,
1933 v.create_sql,
1934 mz_internal.redact_sql(v.create_sql) AS redacted_create_sql
1935 FROM mz_internal.mz_builtin_views v
1936 JOIN builtin_mappings m USING (schema_name, name)
1937 JOIN mz_schemas s ON s.name = v.schema_name
1938 WHERE s.database_id IS NULL
1939 )
1940SELECT * FROM user_views
1941UNION ALL
1942SELECT * FROM builtin_views").into_boxed_str()),
1943 is_retained_metrics_object: false,
1944 access: vec![PUBLIC_SELECT],
1945 ontology: Some(Ontology {
1946 entity_name: "view",
1947 description: "A non-materialized view defined by a SQL query",
1948 links: &const {
1949 [
1950 OntologyLink {
1951 name: "in_schema",
1952 target: "schema",
1953 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1954 },
1955 OntologyLink {
1956 name: "owned_by",
1957 target: "role",
1958 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1959 },
1960 ]
1961 },
1962 column_semantic_types: &const {
1963 [
1964 ("id", SemanticType::CatalogItemId),
1965 ("oid", SemanticType::OID),
1966 ("schema_id", SemanticType::SchemaId),
1967 ("definition", SemanticType::SqlDefinition),
1968 ("owner_id", SemanticType::RoleId),
1969 ("create_sql", SemanticType::SqlDefinition),
1970 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
1971 ]
1972 },
1973 }),
1974}
1975});
1976
1977pub static MZ_MATERIALIZED_VIEWS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1978 BuiltinMaterializedView {
1979 name: "mz_materialized_views",
1980 schema: MZ_CATALOG_SCHEMA,
1981 oid: oid::MV_MZ_MATERIALIZED_VIEWS_OID,
1982 desc: RelationDesc::builder()
1983 .with_column("id", SqlScalarType::String.nullable(false))
1984 .with_column("oid", SqlScalarType::Oid.nullable(false))
1985 .with_column("schema_id", SqlScalarType::String.nullable(false))
1986 .with_column("name", SqlScalarType::String.nullable(false))
1987 .with_column("cluster_id", SqlScalarType::String.nullable(false))
1988 .with_column("definition", SqlScalarType::String.nullable(false))
1989 .with_column("owner_id", SqlScalarType::String.nullable(false))
1990 .with_column(
1991 "privileges",
1992 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1993 )
1994 .with_column("create_sql", SqlScalarType::String.nullable(false))
1995 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
1996 .with_key(vec![0])
1997 .with_key(vec![1])
1998 .finish(),
1999 column_comments: BTreeMap::from_iter([
2000 ("id", "Materialize's unique ID for the materialized view."),
2001 (
2002 "oid",
2003 "A PostgreSQL-compatible OID for the materialized view.",
2004 ),
2005 (
2006 "schema_id",
2007 "The ID of the schema to which the materialized view belongs. Corresponds to `mz_schemas.id`.",
2008 ),
2009 ("name", "The name of the materialized view."),
2010 (
2011 "cluster_id",
2012 "The ID of the cluster maintaining the materialized view. Corresponds to `mz_clusters.id`.",
2013 ),
2014 (
2015 "definition",
2016 "The materialized view definition (a `SELECT` query).",
2017 ),
2018 (
2019 "owner_id",
2020 "The role ID of the owner of the materialized view. Corresponds to `mz_roles.id`.",
2021 ),
2022 (
2023 "privileges",
2024 "The privileges belonging to the materialized view.",
2025 ),
2026 (
2027 "create_sql",
2028 "The `CREATE` SQL statement for the materialized view.",
2029 ),
2030 (
2031 "redacted_create_sql",
2032 "The redacted `CREATE` SQL statement for the materialized view.",
2033 ),
2034 ]),
2035 sql: Box::leak(format!("
2036IN CLUSTER mz_catalog_server
2037WITH (
2038 ASSERT NOT NULL id,
2039 ASSERT NOT NULL oid,
2040 ASSERT NOT NULL schema_id,
2041 ASSERT NOT NULL name,
2042 ASSERT NOT NULL cluster_id,
2043 ASSERT NOT NULL definition,
2044 ASSERT NOT NULL owner_id,
2045 ASSERT NOT NULL privileges,
2046 ASSERT NOT NULL create_sql,
2047 ASSERT NOT NULL redacted_create_sql
2048) AS
2049WITH
2050 user_mvs AS (
2051 SELECT
2052 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
2053 (data->'value'->>'oid')::oid AS oid,
2054 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
2055 data->'value'->>'name' AS name,
2056 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'cluster_id' AS cluster_id,
2057 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'definition' AS definition,
2058 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
2059 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
2060 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
2061 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
2062 FROM mz_internal.mz_catalog_raw
2063 WHERE
2064 data->>'kind' = 'Item' AND
2065 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'type' = 'materialized-view'
2066 ),
2067 builtin_mappings AS (
2068 SELECT
2069 data->'key'->>'schema_name' AS schema_name,
2070 data->'key'->>'object_name' AS name,
2071 's' || (data->'value'->>'catalog_id') AS id
2072 FROM mz_internal.mz_catalog_raw
2073 WHERE
2074 data->>'kind' = 'GidMapping' AND
2075 data->'key'->>'object_type' = '5'
2076 ),
2077 builtin_mvs AS (
2078 SELECT
2079 m.id,
2080 mv.oid,
2081 s.id AS schema_id,
2082 mv.name,
2083 c.id AS cluster_id,
2084 mv.definition,
2085 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
2086 mv.privileges,
2087 mv.create_sql,
2088 mz_internal.redact_sql(mv.create_sql) AS redacted_create_sql
2089 FROM mz_internal.mz_builtin_materialized_views mv
2090 JOIN builtin_mappings m USING (schema_name, name)
2091 JOIN mz_schemas s ON s.name = mv.schema_name
2092 JOIN mz_clusters c ON c.name = mv.cluster_name
2093 WHERE s.database_id IS NULL
2094 )
2095SELECT * FROM user_mvs
2096UNION ALL
2097SELECT * FROM builtin_mvs").into_boxed_str()),
2098 is_retained_metrics_object: false,
2099 access: vec![PUBLIC_SELECT],
2100 ontology: Some(Ontology {
2101 entity_name: "mv",
2102 description: "A materialized view maintained incrementally on a cluster",
2103 links: &const { [
2104 OntologyLink { name: "in_schema", target: "schema", properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne) },
2105 OntologyLink { name: "owned_by", target: "role", properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne) },
2106 OntologyLink { name: "runs_on_cluster", target: "cluster", properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne) },
2107 ] },
2108 column_semantic_types: &const {[("id", SemanticType::CatalogItemId), ("oid", SemanticType::OID), ("schema_id", SemanticType::SchemaId), ("cluster_id", SemanticType::ClusterId), ("definition", SemanticType::SqlDefinition), ("owner_id", SemanticType::RoleId), ("create_sql", SemanticType::SqlDefinition), ("redacted_create_sql", SemanticType::RedactedSqlDefinition)]},
2109 }),
2110 }
2111});
2112pub static MZ_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2113 name: "mz_types",
2114 schema: MZ_CATALOG_SCHEMA,
2115 oid: oid::TABLE_MZ_TYPES_OID,
2116 desc: RelationDesc::builder()
2117 .with_column("id", SqlScalarType::String.nullable(false))
2118 .with_column("oid", SqlScalarType::Oid.nullable(false))
2119 .with_column("schema_id", SqlScalarType::String.nullable(false))
2120 .with_column("name", SqlScalarType::String.nullable(false))
2121 .with_column("category", SqlScalarType::String.nullable(false))
2122 .with_column("owner_id", SqlScalarType::String.nullable(false))
2123 .with_column(
2124 "privileges",
2125 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
2126 )
2127 .with_column("create_sql", SqlScalarType::String.nullable(true))
2128 .with_column("redacted_create_sql", SqlScalarType::String.nullable(true))
2129 .with_key(vec![0])
2130 .with_key(vec![1])
2131 .finish(),
2132 column_comments: BTreeMap::from_iter([
2133 ("id", "Materialize's unique ID for the type."),
2134 ("oid", "A PostgreSQL-compatible OID for the type."),
2135 (
2136 "schema_id",
2137 "The ID of the schema to which the type belongs. Corresponds to `mz_schemas.id`.",
2138 ),
2139 ("name", "The name of the type."),
2140 ("category", "The category of the type."),
2141 (
2142 "owner_id",
2143 "The role ID of the owner of the type. Corresponds to `mz_roles.id`.",
2144 ),
2145 ("privileges", "The privileges belonging to the type."),
2146 ("create_sql", "The `CREATE` SQL statement for the type."),
2147 (
2148 "redacted_create_sql",
2149 "The redacted `CREATE` SQL statement for the type.",
2150 ),
2151 ]),
2152 is_retained_metrics_object: false,
2153 access: vec![PUBLIC_SELECT],
2154 ontology: Some(Ontology {
2155 entity_name: "type",
2156 description: "A named data type (base, array, list, map, or pseudo)",
2157 links: &const {
2158 [
2159 OntologyLink {
2160 name: "in_schema",
2161 target: "schema",
2162 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
2163 },
2164 OntologyLink {
2165 name: "owned_by",
2166 target: "role",
2167 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
2168 },
2169 ]
2170 },
2171 column_semantic_types: &const {
2172 [
2173 ("id", SemanticType::CatalogItemId),
2174 ("oid", SemanticType::OID),
2175 ("schema_id", SemanticType::SchemaId),
2176 ("owner_id", SemanticType::RoleId),
2177 ("create_sql", SemanticType::SqlDefinition),
2178 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
2179 ]
2180 },
2181 }),
2182});
2183pub static MZ_ARRAY_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2184 name: "mz_array_types",
2185 schema: MZ_CATALOG_SCHEMA,
2186 oid: oid::TABLE_MZ_ARRAY_TYPES_OID,
2187 desc: RelationDesc::builder()
2188 .with_column("id", SqlScalarType::String.nullable(false))
2189 .with_column("element_id", SqlScalarType::String.nullable(false))
2190 .finish(),
2191 column_comments: BTreeMap::from_iter([
2192 ("id", "The ID of the array type."),
2193 ("element_id", "The ID of the array's element type."),
2194 ]),
2195 is_retained_metrics_object: false,
2196 access: vec![PUBLIC_SELECT],
2197 ontology: Some(Ontology {
2198 entity_name: "array_type",
2199 description: "An array type with its element type",
2200 links: &const {
2201 [
2202 OntologyLink {
2203 name: "detail_of",
2204 target: "type",
2205 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
2206 },
2207 OntologyLink {
2208 name: "has_element_type",
2209 target: "type",
2210 properties: LinkProperties::fk("element_id", "id", Cardinality::ManyToOne),
2211 },
2212 ]
2213 },
2214 column_semantic_types: &const {
2215 [
2216 ("id", SemanticType::CatalogItemId),
2217 ("element_id", SemanticType::CatalogItemId),
2218 ]
2219 },
2220 }),
2221});
2222pub static MZ_BASE_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2223 name: "mz_base_types",
2224 schema: MZ_CATALOG_SCHEMA,
2225 oid: oid::TABLE_MZ_BASE_TYPES_OID,
2226 desc: RelationDesc::builder()
2227 .with_column("id", SqlScalarType::String.nullable(false))
2228 .finish(),
2229 column_comments: BTreeMap::from_iter([("id", "The ID of the type.")]),
2230 is_retained_metrics_object: false,
2231 access: vec![PUBLIC_SELECT],
2232 ontology: Some(Ontology {
2233 entity_name: "base_type",
2234 description: "A primitive/base data type",
2235 links: &const { [] },
2236 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
2237 }),
2238});
2239pub static MZ_LIST_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2240 name: "mz_list_types",
2241 schema: MZ_CATALOG_SCHEMA,
2242 oid: oid::TABLE_MZ_LIST_TYPES_OID,
2243 desc: RelationDesc::builder()
2244 .with_column("id", SqlScalarType::String.nullable(false))
2245 .with_column("element_id", SqlScalarType::String.nullable(false))
2246 .with_column(
2247 "element_modifiers",
2248 SqlScalarType::List {
2249 element_type: Box::new(SqlScalarType::Int64),
2250 custom_id: None,
2251 }
2252 .nullable(true),
2253 )
2254 .finish(),
2255 column_comments: BTreeMap::from_iter([
2256 ("id", "The ID of the list type."),
2257 ("element_id", "The IID of the list's element type."),
2258 (
2259 "element_modifiers",
2260 "The element type modifiers, or `NULL` if none.",
2261 ),
2262 ]),
2263 is_retained_metrics_object: false,
2264 access: vec![PUBLIC_SELECT],
2265 ontology: Some(Ontology {
2266 entity_name: "list_type",
2267 description: "A list type with its element type",
2268 links: &const {
2269 [
2270 OntologyLink {
2271 name: "detail_of",
2272 target: "type",
2273 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
2274 },
2275 OntologyLink {
2276 name: "has_element_type",
2277 target: "type",
2278 properties: LinkProperties::fk("element_id", "id", Cardinality::ManyToOne),
2279 },
2280 ]
2281 },
2282 column_semantic_types: &const {
2283 [
2284 ("id", SemanticType::CatalogItemId),
2285 ("element_id", SemanticType::CatalogItemId),
2286 ]
2287 },
2288 }),
2289});
2290pub static MZ_MAP_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2291 name: "mz_map_types",
2292 schema: MZ_CATALOG_SCHEMA,
2293 oid: oid::TABLE_MZ_MAP_TYPES_OID,
2294 desc: RelationDesc::builder()
2295 .with_column("id", SqlScalarType::String.nullable(false))
2296 .with_column("key_id", SqlScalarType::String.nullable(false))
2297 .with_column("value_id", SqlScalarType::String.nullable(false))
2298 .with_column(
2299 "key_modifiers",
2300 SqlScalarType::List {
2301 element_type: Box::new(SqlScalarType::Int64),
2302 custom_id: None,
2303 }
2304 .nullable(true),
2305 )
2306 .with_column(
2307 "value_modifiers",
2308 SqlScalarType::List {
2309 element_type: Box::new(SqlScalarType::Int64),
2310 custom_id: None,
2311 }
2312 .nullable(true),
2313 )
2314 .finish(),
2315 column_comments: BTreeMap::from_iter([
2316 ("id", "The ID of the map type."),
2317 ("key_id", "The ID of the map's key type."),
2318 ("value_id", "The ID of the map's value type."),
2319 (
2320 "key_modifiers",
2321 "The key type modifiers, or `NULL` if none.",
2322 ),
2323 (
2324 "value_modifiers",
2325 "The value type modifiers, or `NULL` if none.",
2326 ),
2327 ]),
2328 is_retained_metrics_object: false,
2329 access: vec![PUBLIC_SELECT],
2330 ontology: Some(Ontology {
2331 entity_name: "map_type",
2332 description: "A map type with its key and value types",
2333 links: &const {
2334 [
2335 OntologyLink {
2336 name: "detail_of",
2337 target: "type",
2338 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
2339 },
2340 OntologyLink {
2341 name: "has_key_type",
2342 target: "type",
2343 properties: LinkProperties::fk("key_id", "id", Cardinality::ManyToOne),
2344 },
2345 OntologyLink {
2346 name: "has_value_type",
2347 target: "type",
2348 properties: LinkProperties::fk("value_id", "id", Cardinality::ManyToOne),
2349 },
2350 ]
2351 },
2352 column_semantic_types: &const {
2353 [
2354 ("id", SemanticType::CatalogItemId),
2355 ("key_id", SemanticType::CatalogItemId),
2356 ("value_id", SemanticType::CatalogItemId),
2357 ]
2358 },
2359 }),
2360});
2361pub static MZ_ROLES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2362 let sql = format!(
2366 "
2367IN CLUSTER mz_catalog_server
2368WITH (
2369 ASSERT NOT NULL id,
2370 ASSERT NOT NULL oid,
2371 ASSERT NOT NULL name,
2372 ASSERT NOT NULL inherit
2373) AS
2374SELECT
2375 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
2376 (data->'value'->>'oid')::oid AS oid,
2377 data->'value'->>'name' AS name,
2378 (data->'value'->'attributes'->>'inherit')::bool AS inherit,
2379 COALESCE(
2380 (data->'value'->'attributes'->>'login')::bool,
2381 data->'value'->>'name' IN ('{system}', '{support}')
2382 ) AS rolcanlogin,
2383 COALESCE(
2384 (data->'value'->'attributes'->>'superuser')::bool,
2385 CASE WHEN data->'value'->>'name' IN ('{system}', '{support}') THEN true END
2386 ) AS rolsuper
2387FROM mz_internal.mz_catalog_raw
2388WHERE data->>'kind' = 'Role' AND data->'key'->'id' != '\"Public\"'::jsonb",
2389 system = SYSTEM_USER_NAME,
2390 support = SUPPORT_USER_NAME,
2391 );
2392
2393 BuiltinMaterializedView {
2394 name: "mz_roles",
2395 schema: MZ_CATALOG_SCHEMA,
2396 oid: oid::MV_MZ_ROLES_OID,
2397 desc: RelationDesc::builder()
2398 .with_column("id", SqlScalarType::String.nullable(false))
2399 .with_column("oid", SqlScalarType::Oid.nullable(false))
2400 .with_column("name", SqlScalarType::String.nullable(false))
2401 .with_column("inherit", SqlScalarType::Bool.nullable(false))
2402 .with_column("rolcanlogin", SqlScalarType::Bool.nullable(true))
2403 .with_column("rolsuper", SqlScalarType::Bool.nullable(true))
2404 .with_key(vec![0])
2405 .with_key(vec![1])
2406 .finish(),
2407 column_comments: BTreeMap::from_iter([
2408 ("id", "Materialize's unique ID for the role."),
2409 ("oid", "A PostgreSQL-compatible OID for the role."),
2410 ("name", "The name of the role."),
2411 (
2412 "inherit",
2413 "Indicates whether the role has inheritance of privileges.",
2414 ),
2415 ("rolcanlogin", "Indicates whether the role can log in."),
2416 ("rolsuper", "Indicates whether the role is a superuser."),
2417 ]),
2418 sql: Box::leak(sql.into_boxed_str()),
2419 is_retained_metrics_object: false,
2420 access: vec![PUBLIC_SELECT],
2421 ontology: Some(Ontology {
2422 entity_name: "role",
2423 description: "A user or role for authentication and access control",
2424 links: &const { [] },
2425 column_semantic_types: &const { [("id", SemanticType::RoleId), ("oid", SemanticType::OID)] },
2426 }),
2427 }
2428});
2429
2430pub static MZ_ROLE_MEMBERS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2431 BuiltinMaterializedView {
2432 name: "mz_role_members",
2433 schema: MZ_CATALOG_SCHEMA,
2434 oid: oid::MV_MZ_ROLE_MEMBERS_OID,
2435 desc: RelationDesc::builder()
2436 .with_column("role_id", SqlScalarType::String.nullable(false))
2437 .with_column("member", SqlScalarType::String.nullable(false))
2438 .with_column("grantor", SqlScalarType::String.nullable(false))
2439 .finish(),
2440 column_comments: BTreeMap::from_iter([
2441 (
2442 "role_id",
2443 "The ID of the role the `member` is a member of. Corresponds to `mz_roles.id`.",
2444 ),
2445 (
2446 "member",
2447 "The ID of the role that is a member of `role_id`. Corresponds to `mz_roles.id`.",
2448 ),
2449 (
2450 "grantor",
2451 "The ID of the role that granted membership of `member` to `role_id`. Corresponds to `mz_roles.id`.",
2452 ),
2453 ]),
2454 sql: "
2455IN CLUSTER mz_catalog_server
2456WITH (
2457 ASSERT NOT NULL role_id,
2458 ASSERT NOT NULL member,
2459 ASSERT NOT NULL grantor
2460) AS
2461SELECT
2462 mz_internal.parse_catalog_id(entry->'key') AS role_id,
2463 mz_internal.parse_catalog_id(data->'key'->'id') AS member,
2464 mz_internal.parse_catalog_id(entry->'value') AS grantor
2465FROM
2466 mz_internal.mz_catalog_raw,
2467 jsonb_array_elements(data->'value'->'membership'->'map') AS entry
2468WHERE data->>'kind' = 'Role'",
2469 is_retained_metrics_object: false,
2470 access: vec![PUBLIC_SELECT],
2471 ontology: Some(Ontology {
2472 entity_name: "role_membership",
2473 description: "A membership grant: one role is a member of another role",
2474 links: &const {
2475 [
2476 OntologyLink {
2477 name: "group_role",
2478 target: "role",
2479 properties: LinkProperties::fk("role_id", "id", Cardinality::ManyToOne),
2480 },
2481 OntologyLink {
2482 name: "member_role",
2483 target: "role",
2484 properties: LinkProperties::fk("member", "id", Cardinality::ManyToOne),
2485 },
2486 OntologyLink {
2487 name: "granted_by",
2488 target: "role",
2489 properties: LinkProperties::fk("grantor", "id", Cardinality::ManyToOne),
2490 },
2491 ]
2492 },
2493 column_semantic_types: &const {
2494 [
2495 ("role_id", SemanticType::RoleId),
2496 ("member", SemanticType::RoleId),
2497 ("grantor", SemanticType::RoleId),
2498 ]
2499 },
2500 }),
2501 }
2502});
2503
2504pub static MZ_ROLE_PARAMETERS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2505 BuiltinMaterializedView {
2506 name: "mz_role_parameters",
2507 schema: MZ_CATALOG_SCHEMA,
2508 oid: oid::MV_MZ_ROLE_PARAMETERS_OID,
2509 desc: RelationDesc::builder()
2510 .with_column("role_id", SqlScalarType::String.nullable(false))
2511 .with_column("parameter_name", SqlScalarType::String.nullable(false))
2512 .with_column("parameter_value", SqlScalarType::String.nullable(false))
2513 .finish(),
2514 column_comments: BTreeMap::from_iter([
2515 (
2516 "role_id",
2517 "The ID of the role whose configuration parameter default is set. Corresponds to `mz_roles.id`.",
2518 ),
2519 (
2520 "parameter_name",
2521 "The configuration parameter name. One of the supported configuration parameters.",
2522 ),
2523 (
2524 "parameter_value",
2525 "The default value of the parameter for the given role. Can be either a single value, or a comma-separated list of values for configuration parameters that accept a list.",
2526 ),
2527 ]),
2528 sql: "
2529IN CLUSTER mz_catalog_server
2530WITH (
2531 ASSERT NOT NULL role_id,
2532 ASSERT NOT NULL parameter_name,
2533 ASSERT NOT NULL parameter_value
2534) AS
2535SELECT
2536 mz_internal.parse_catalog_id(data->'key'->'id') AS role_id,
2537 entry->>'key' AS parameter_name,
2538 CASE
2539 WHEN entry->'val' ? 'Flat' THEN entry->'val'->>'Flat'
2540 ELSE (
2541 SELECT pg_catalog.string_agg(t.elem, ', ' ORDER BY t.ord)
2542 FROM jsonb_array_elements_text(entry->'val'->'SqlSet')
2543 WITH ORDINALITY AS t(elem, ord)
2544 )
2545 END AS parameter_value
2546FROM
2547 mz_internal.mz_catalog_raw,
2548 jsonb_array_elements(data->'value'->'vars'->'entries') AS entry
2549WHERE data->>'kind' = 'Role'",
2550 is_retained_metrics_object: false,
2551 access: vec![PUBLIC_SELECT],
2552 ontology: Some(Ontology {
2553 entity_name: "role_parameter",
2554 description: "A session parameter default set for a role",
2555 links: &const {
2556 [OntologyLink {
2557 name: "default_parameter_setting_of",
2558 target: "role",
2559 properties: LinkProperties::fk("role_id", "id", Cardinality::ManyToOne),
2560 }]
2561 },
2562 column_semantic_types: &[("role_id", SemanticType::RoleId)],
2563 }),
2564 }
2565});
2566pub static MZ_ROLE_AUTH: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2567 name: "mz_role_auth",
2568 schema: MZ_CATALOG_SCHEMA,
2569 oid: oid::TABLE_MZ_ROLE_AUTH_OID,
2570 desc: RelationDesc::builder()
2571 .with_column("role_id", SqlScalarType::String.nullable(false))
2572 .with_column("role_oid", SqlScalarType::Oid.nullable(false))
2573 .with_column("password_hash", SqlScalarType::String.nullable(true))
2574 .with_column(
2575 "updated_at",
2576 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2577 )
2578 .finish(),
2579 column_comments: BTreeMap::from_iter([
2580 (
2581 "role_id",
2582 "The ID of the role. Corresponds to `mz_roles.id`.",
2583 ),
2584 ("role_oid", "A PostgreSQL-compatible OID for the role."),
2585 (
2586 "password_hash",
2587 "The hashed password for the role, if any. Uses the `SCRAM-SHA-256` algorithm.",
2588 ),
2589 (
2590 "updated_at",
2591 "The time at which the password was last updated.",
2592 ),
2593 ]),
2594 is_retained_metrics_object: false,
2595 access: vec![rbac::owner_privilege(ObjectType::Table, MZ_SYSTEM_ROLE_ID)],
2596 ontology: None,
2597});
2598pub static MZ_PSEUDO_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2599 name: "mz_pseudo_types",
2600 schema: MZ_CATALOG_SCHEMA,
2601 oid: oid::TABLE_MZ_PSEUDO_TYPES_OID,
2602 desc: RelationDesc::builder()
2603 .with_column("id", SqlScalarType::String.nullable(false))
2604 .finish(),
2605 column_comments: BTreeMap::from_iter([("id", "The ID of the type.")]),
2606 is_retained_metrics_object: false,
2607 access: vec![PUBLIC_SELECT],
2608 ontology: Some(Ontology {
2609 entity_name: "pseudo_type",
2610 description: "A pseudo-type used in function signatures",
2611 links: &const { [] },
2612 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
2613 }),
2614});
2615pub static MZ_FUNCTIONS: LazyLock<BuiltinTable> = LazyLock::new(|| {
2616 BuiltinTable {
2617 name: "mz_functions",
2618 schema: MZ_CATALOG_SCHEMA,
2619 oid: oid::TABLE_MZ_FUNCTIONS_OID,
2620 desc: RelationDesc::builder()
2621 .with_column("id", SqlScalarType::String.nullable(false)) .with_column("oid", SqlScalarType::Oid.nullable(false))
2623 .with_column("schema_id", SqlScalarType::String.nullable(false))
2624 .with_column("name", SqlScalarType::String.nullable(false))
2625 .with_column(
2626 "argument_type_ids",
2627 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
2628 )
2629 .with_column(
2630 "variadic_argument_type_id",
2631 SqlScalarType::String.nullable(true),
2632 )
2633 .with_column("return_type_id", SqlScalarType::String.nullable(true))
2634 .with_column("returns_set", SqlScalarType::Bool.nullable(false))
2635 .with_column("owner_id", SqlScalarType::String.nullable(false))
2636 .finish(),
2637 column_comments: BTreeMap::from_iter([
2638 ("id", "Materialize's unique ID for the function."),
2639 ("oid", "A PostgreSQL-compatible OID for the function."),
2640 (
2641 "schema_id",
2642 "The ID of the schema to which the function belongs. Corresponds to `mz_schemas.id`.",
2643 ),
2644 ("name", "The name of the function."),
2645 (
2646 "argument_type_ids",
2647 "The ID of each argument's type. Each entry refers to `mz_types.id`.",
2648 ),
2649 (
2650 "variadic_argument_type_id",
2651 "The ID of the variadic argument's type, or `NULL` if the function does not have a variadic argument. Refers to `mz_types.id`.",
2652 ),
2653 (
2654 "return_type_id",
2655 "The returned value's type, or `NULL` if the function does not return a value. Refers to `mz_types.id`. Note that for table functions with > 1 column, this type corresponds to [`record`].",
2656 ),
2657 (
2658 "returns_set",
2659 "Whether the function returns a set, i.e. the function is a table function.",
2660 ),
2661 (
2662 "owner_id",
2663 "The role ID of the owner of the function. Corresponds to `mz_roles.id`.",
2664 ),
2665 ]),
2666 is_retained_metrics_object: false,
2667 access: vec![PUBLIC_SELECT],
2668 ontology: Some(Ontology {
2669 entity_name: "function",
2670 description: "A built-in or user-defined function",
2671 links: &const {
2672 [
2673 OntologyLink {
2674 name: "in_schema",
2675 target: "schema",
2676 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
2677 },
2678 OntologyLink {
2679 name: "owned_by",
2680 target: "role",
2681 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
2682 },
2683 OntologyLink {
2684 name: "returns_type",
2685 target: "type",
2686 properties: LinkProperties::fk_nullable(
2687 "return_type_id",
2688 "id",
2689 Cardinality::ManyToOne,
2690 ),
2691 },
2692 OntologyLink {
2693 name: "has_variadic_arg_type",
2694 target: "type",
2695 properties: LinkProperties::fk_nullable(
2696 "variadic_argument_type_id",
2697 "id",
2698 Cardinality::ManyToOne,
2699 ),
2700 },
2701 ]
2702 },
2703 column_semantic_types: &const {
2704 [
2705 ("id", SemanticType::CatalogItemId),
2706 ("oid", SemanticType::OID),
2707 ("schema_id", SemanticType::SchemaId),
2708 ("variadic_argument_type_id", SemanticType::CatalogItemId),
2709 ("return_type_id", SemanticType::CatalogItemId),
2710 ("owner_id", SemanticType::RoleId),
2711 ]
2712 },
2713 }),
2714 }
2715});
2716pub static MZ_OPERATORS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2717 name: "mz_operators",
2718 schema: MZ_CATALOG_SCHEMA,
2719 oid: oid::TABLE_MZ_OPERATORS_OID,
2720 desc: RelationDesc::builder()
2721 .with_column("oid", SqlScalarType::Oid.nullable(false))
2722 .with_column("name", SqlScalarType::String.nullable(false))
2723 .with_column(
2724 "argument_type_ids",
2725 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
2726 )
2727 .with_column("return_type_id", SqlScalarType::String.nullable(true))
2728 .finish(),
2729 column_comments: BTreeMap::new(),
2730 is_retained_metrics_object: false,
2731 access: vec![PUBLIC_SELECT],
2732 ontology: Some(Ontology {
2733 entity_name: "operator",
2734 description: "A built-in SQL operator",
2735 links: &const {
2736 [OntologyLink {
2737 name: "returns_type",
2738 target: "type",
2739 properties: LinkProperties::fk_nullable(
2740 "return_type_id",
2741 "id",
2742 Cardinality::ManyToOne,
2743 ),
2744 }]
2745 },
2746 column_semantic_types: &const {
2747 [
2748 ("oid", SemanticType::OID),
2749 ("return_type_id", SemanticType::CatalogItemId),
2750 ]
2751 },
2752 }),
2753});
2754
2755pub static MZ_CLUSTERS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2756 BuiltinMaterializedView {
2757 name: "mz_clusters",
2758 schema: MZ_CATALOG_SCHEMA,
2759 oid: oid::MV_MZ_CLUSTERS_OID,
2760 desc: RelationDesc::builder()
2761 .with_column("id", SqlScalarType::String.nullable(false))
2762 .with_column("name", SqlScalarType::String.nullable(false))
2763 .with_column("owner_id", SqlScalarType::String.nullable(false))
2764 .with_column(
2765 "privileges",
2766 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
2767 )
2768 .with_column("managed", SqlScalarType::Bool.nullable(false))
2769 .with_column("size", SqlScalarType::String.nullable(true))
2770 .with_column("replication_factor", SqlScalarType::UInt32.nullable(true))
2771 .with_column("disk", SqlScalarType::Bool.nullable(true))
2772 .with_column(
2773 "availability_zones",
2774 SqlScalarType::List {
2775 element_type: Box::new(SqlScalarType::String),
2776 custom_id: None,
2777 }
2778 .nullable(true),
2779 )
2780 .with_column(
2781 "introspection_debugging",
2782 SqlScalarType::Bool.nullable(true),
2783 )
2784 .with_column(
2785 "introspection_interval",
2786 SqlScalarType::Interval.nullable(true),
2787 )
2788 .with_key(vec![0])
2789 .finish(),
2790 column_comments: BTreeMap::from_iter([
2791 ("id", "Materialize's unique ID for the cluster."),
2792 ("name", "The name of the cluster."),
2793 (
2794 "owner_id",
2795 "The role ID of the owner of the cluster. Corresponds to `mz_roles.id`.",
2796 ),
2797 ("privileges", "The privileges belonging to the cluster."),
2798 (
2799 "managed",
2800 "Whether the cluster is a managed cluster with automatically managed replicas.",
2801 ),
2802 (
2803 "size",
2804 "If the cluster is managed, the desired size of the cluster's replicas. `NULL` for unmanaged clusters.",
2805 ),
2806 (
2807 "replication_factor",
2808 "If the cluster is managed, the desired number of replicas of the cluster. `NULL` for unmanaged clusters.",
2809 ),
2810 (
2811 "disk",
2812 "**Unstable** If the cluster is managed, `true` if the replicas have the `DISK` option . `NULL` for unmanaged clusters.",
2813 ),
2814 (
2815 "availability_zones",
2816 "**Unstable** If the cluster is managed, the list of availability zones specified in `AVAILABILITY ZONES`. `NULL` for unmanaged clusters.",
2817 ),
2818 (
2819 "introspection_debugging",
2820 "Whether introspection of the gathering of the introspection data is enabled.",
2821 ),
2822 (
2823 "introspection_interval",
2824 "The interval at which to collect introspection data.",
2825 ),
2826 ]),
2827 sql: "
2851IN CLUSTER mz_catalog_server
2852WITH (
2853 ASSERT NOT NULL id,
2854 ASSERT NOT NULL name,
2855 ASSERT NOT NULL owner_id,
2856 ASSERT NOT NULL privileges,
2857 ASSERT NOT NULL managed
2858) AS
2859SELECT
2860 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
2861 data->'value'->>'name' AS name,
2862 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
2863 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
2864 jsonb_typeof(data->'value'->'config'->'variant') = 'object' AS managed,
2865 data->'value'->'config'->'variant'->'Managed'->>'size' AS size,
2866 (data->'value'->'config'->'variant'->'Managed'->>'replication_factor')::uint4 AS replication_factor,
2867 CASE
2868 WHEN jsonb_typeof(data->'value'->'config'->'variant') = 'object' THEN
2869 NOT COALESCE(internal.swap_enabled, false)
2870 AND COALESCE(internal.disk_bytes, 0) != 0
2871 END AS disk,
2872 CASE
2873 WHEN jsonb_array_length(data->'value'->'config'->'variant'->'Managed'->'availability_zones') > 0 THEN
2874 (
2875 SELECT mz_catalog.list_agg(az.value ORDER BY az.ord)
2876 FROM jsonb_array_elements_text(data->'value'->'config'->'variant'->'Managed'->'availability_zones')
2877 WITH ORDINALITY AS az(value, ord)
2878 )
2879 END AS availability_zones,
2880 (data->'value'->'config'->'variant'->'Managed'->'logging'->>'log_logging')::bool AS introspection_debugging,
2881 CASE
2882 WHEN data->'value'->'config'->'variant'->'Managed'->'logging'->'interval' != 'null'::jsonb THEN
2883 (
2884 (data->'value'->'config'->'variant'->'Managed'->'logging'->'interval'->>'secs')
2885 || ' seconds '
2886 || ((data->'value'->'config'->'variant'->'Managed'->'logging'->'interval'->>'nanos')::bigint / 1000)::text
2887 || ' microseconds'
2888 )::interval
2889 END AS introspection_interval
2890FROM (
2891 SELECT data FROM mz_internal.mz_catalog_raw WHERE data->>'kind' = 'Cluster'
2892) raw
2893LEFT JOIN mz_internal.mz_cluster_replica_size_internal internal
2894 ON internal.size = data->'value'->'config'->'variant'->'Managed'->>'size'",
2895 is_retained_metrics_object: false,
2896 access: vec![PUBLIC_SELECT],
2897 ontology: Some(Ontology {
2898 entity_name: "cluster",
2899 description: "A compute cluster that runs dataflows for sources, sinks, MVs, and indexes",
2900 links: &const {
2901 [
2902 OntologyLink {
2903 name: "owned_by",
2904 target: "role",
2905 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
2906 },
2907 OntologyLink {
2908 name: "has_size",
2909 target: "replica_size",
2910 properties: LinkProperties::fk_nullable("size", "size", Cardinality::ManyToOne),
2911 },
2912 ]
2913 },
2914 column_semantic_types: &const {
2915 [
2916 ("id", SemanticType::ClusterId),
2917 ("owner_id", SemanticType::RoleId),
2918 ]
2919 },
2920 }),
2921 }
2922});
2923
2924pub static MZ_SECRETS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2925 BuiltinMaterializedView {
2926 name: "mz_secrets",
2927 schema: MZ_CATALOG_SCHEMA,
2928 oid: oid::MV_MZ_SECRETS_OID,
2929 desc: RelationDesc::builder()
2930 .with_column("id", SqlScalarType::String.nullable(false))
2931 .with_column("oid", SqlScalarType::Oid.nullable(false))
2932 .with_column("schema_id", SqlScalarType::String.nullable(false))
2933 .with_column("name", SqlScalarType::String.nullable(false))
2934 .with_column("owner_id", SqlScalarType::String.nullable(false))
2935 .with_column(
2936 "privileges",
2937 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
2938 )
2939 .finish(),
2940 column_comments: BTreeMap::from_iter([
2941 ("id", "The unique ID of the secret."),
2942 ("oid", "A PostgreSQL-compatible oid for the secret."),
2943 (
2944 "schema_id",
2945 "The ID of the schema to which the secret belongs. Corresponds to `mz_schemas.id`.",
2946 ),
2947 ("name", "The name of the secret."),
2948 (
2949 "owner_id",
2950 "The role ID of the owner of the secret. Corresponds to `mz_roles.id`.",
2951 ),
2952 ("privileges", "The privileges belonging to the secret."),
2953 ]),
2954 sql: "
2955IN CLUSTER mz_catalog_server
2956WITH (
2957 ASSERT NOT NULL id,
2958 ASSERT NOT NULL oid,
2959 ASSERT NOT NULL schema_id,
2960 ASSERT NOT NULL name,
2961 ASSERT NOT NULL owner_id,
2962 ASSERT NOT NULL privileges
2963) AS
2964SELECT
2965 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
2966 (data->'value'->>'oid')::oid AS oid,
2967 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
2968 data->'value'->>'name' AS name,
2969 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
2970 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges
2971FROM mz_internal.mz_catalog_raw
2972WHERE
2973 data->>'kind' = 'Item' AND
2974 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'type' = 'secret'",
2975 is_retained_metrics_object: false,
2976 access: vec![PUBLIC_SELECT],
2977 ontology: Some(Ontology {
2978 entity_name: "secret",
2979 description: "A user-defined secret containing sensitive configuration (e.g., credentials)",
2980 links: &const { [
2981 OntologyLink {
2982 name: "in_schema",
2983 target: "schema",
2984 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
2985 },
2986 OntologyLink {
2987 name: "owned_by",
2988 target: "role",
2989 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
2990 },
2991 ] },
2992 column_semantic_types: &const {[("id", SemanticType::CatalogItemId), ("oid", SemanticType::OID), ("schema_id", SemanticType::SchemaId), ("owner_id", SemanticType::RoleId)]},
2993 }),
2994 }
2995});
2996
2997pub static MZ_CLUSTER_REPLICAS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2998 BuiltinMaterializedView {
2999 name: "mz_cluster_replicas",
3000 schema: MZ_CATALOG_SCHEMA,
3001 oid: oid::MV_MZ_CLUSTER_REPLICAS_OID,
3002 desc: RelationDesc::builder()
3003 .with_column("id", SqlScalarType::String.nullable(false))
3004 .with_column("name", SqlScalarType::String.nullable(false))
3005 .with_column("cluster_id", SqlScalarType::String.nullable(false))
3006 .with_column("size", SqlScalarType::String.nullable(true))
3007 .with_column("availability_zone", SqlScalarType::String.nullable(true))
3010 .with_column("owner_id", SqlScalarType::String.nullable(false))
3011 .with_column("disk", SqlScalarType::Bool.nullable(true))
3012 .with_key(vec![0])
3013 .finish(),
3014 column_comments: BTreeMap::from_iter([
3015 ("id", "Materialize's unique ID for the cluster replica."),
3016 ("name", "The name of the cluster replica."),
3017 (
3018 "cluster_id",
3019 "The ID of the cluster to which the replica belongs. Corresponds to `mz_clusters.id`.",
3020 ),
3021 (
3022 "size",
3023 "The cluster replica's size, selected during creation.",
3024 ),
3025 (
3026 "availability_zone",
3027 "The availability zones the replica is provisioned in, comma-separated. `NULL` if nothing constrains the replica's placement.",
3028 ),
3029 (
3030 "owner_id",
3031 "The role ID of the owner of the cluster replica. Corresponds to `mz_roles.id`.",
3032 ),
3033 ("disk", "If the replica has a local disk."),
3034 ]),
3035 sql: "
3059IN CLUSTER mz_catalog_server
3060WITH (
3061 ASSERT NOT NULL id,
3062 ASSERT NOT NULL name,
3063 ASSERT NOT NULL cluster_id,
3064 ASSERT NOT NULL owner_id
3065) AS
3066SELECT
3067 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
3068 data->'value'->>'name' AS name,
3069 mz_internal.parse_catalog_id(data->'value'->'cluster_id') AS cluster_id,
3070 data->'value'->'config'->'location'->'Managed'->>'size' AS size,
3071 CASE
3072 WHEN jsonb_array_length(data->'value'->'config'->'location'->'Managed'->'availability_zones') > 0 THEN
3073 (
3074 SELECT pg_catalog.string_agg(az.value, ',' ORDER BY az.ord)
3075 FROM jsonb_array_elements_text(data->'value'->'config'->'location'->'Managed'->'availability_zones')
3076 WITH ORDINALITY AS az(value, ord)
3077 )
3078 END AS availability_zone,
3079 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
3080 CASE
3081 WHEN data->'value'->'config'->'location' ? 'Managed' THEN
3082 NOT COALESCE(internal.swap_enabled, false)
3083 AND COALESCE(internal.disk_bytes, 0) != 0
3084 END AS disk
3085FROM (
3086 SELECT data FROM mz_internal.mz_catalog_raw WHERE data->>'kind' = 'ClusterReplica'
3087) raw
3088LEFT JOIN mz_internal.mz_cluster_replica_size_internal internal
3089 ON internal.size = data->'value'->'config'->'location'->'Managed'->>'size'",
3090 is_retained_metrics_object: true,
3091 access: vec![PUBLIC_SELECT],
3092 ontology: Some(Ontology {
3093 entity_name: "replica",
3094 description: "A physical replica of a cluster providing fault tolerance",
3095 links: &const {
3096 [
3097 OntologyLink {
3098 name: "owned_by",
3099 target: "role",
3100 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
3101 },
3102 OntologyLink {
3103 name: "belongs_to_cluster",
3104 target: "cluster",
3105 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
3106 },
3107 OntologyLink {
3108 name: "has_size",
3109 target: "replica_size",
3110 properties: LinkProperties::fk_nullable(
3111 "size",
3112 "size",
3113 Cardinality::ManyToOne,
3114 ),
3115 },
3116 ]
3117 },
3118 column_semantic_types: &const {
3119 [
3120 ("id", SemanticType::ReplicaId),
3121 ("cluster_id", SemanticType::ClusterId),
3122 ("owner_id", SemanticType::RoleId),
3123 ]
3124 },
3125 }),
3126 }
3127});
3128
3129pub static MZ_CLUSTER_REPLICA_SIZES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3130 name: "mz_cluster_replica_sizes",
3131 schema: MZ_CATALOG_SCHEMA,
3132 oid: oid::TABLE_MZ_CLUSTER_REPLICA_SIZES_OID,
3133 desc: RelationDesc::builder()
3134 .with_column("size", SqlScalarType::String.nullable(false))
3135 .with_column("processes", SqlScalarType::UInt64.nullable(false))
3136 .with_column("workers", SqlScalarType::UInt64.nullable(false))
3137 .with_column("cpu_nano_cores", SqlScalarType::UInt64.nullable(false))
3138 .with_column("memory_bytes", SqlScalarType::UInt64.nullable(false))
3139 .with_column("disk_bytes", SqlScalarType::UInt64.nullable(true))
3140 .with_column(
3141 "credits_per_hour",
3142 SqlScalarType::Numeric { max_scale: None }.nullable(false),
3143 )
3144 .with_column("disabled", SqlScalarType::Bool.nullable(false))
3145 .finish(),
3146 column_comments: BTreeMap::from_iter([
3147 ("size", "The human-readable replica size."),
3148 ("processes", "The number of processes in the replica."),
3149 (
3150 "workers",
3151 "The number of Timely Dataflow workers per process.",
3152 ),
3153 (
3154 "cpu_nano_cores",
3155 "The CPU allocation per process, in billionths of a vCPU core.",
3156 ),
3157 ("memory_bytes", "The RAM allocation per process, in bytes."),
3158 ("disk_bytes", "The disk allocation per process."),
3159 (
3160 "credits_per_hour",
3161 "The number of compute credits consumed per hour.",
3162 ),
3163 (
3164 "disabled",
3165 "Whether the size is disabled. Existing replicas keep running on a disabled size, but new clusters and replicas cannot choose it.",
3166 ),
3167 ]),
3168 is_retained_metrics_object: true,
3169 access: vec![PUBLIC_SELECT],
3170 ontology: Some(Ontology {
3171 entity_name: "replica_size",
3172 description: "Cluster replica sizes with CPU, memory, and credit cost",
3173 links: &const { [] },
3174 column_semantic_types: &const {
3175 [
3176 ("memory_bytes", SemanticType::ByteCount),
3177 ("disk_bytes", SemanticType::ByteCount),
3178 ("credits_per_hour", SemanticType::CreditRate),
3179 ]
3180 },
3181 }),
3182});
3183
3184pub static MZ_AUDIT_EVENTS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
3185 BuiltinMaterializedView {
3186 name: "mz_audit_events",
3187 schema: MZ_CATALOG_SCHEMA,
3188 oid: oid::MV_MZ_AUDIT_EVENTS_OID,
3189 desc: RelationDesc::builder()
3190 .with_column("id", SqlScalarType::UInt64.nullable(false))
3191 .with_column("event_type", SqlScalarType::String.nullable(false))
3192 .with_column("object_type", SqlScalarType::String.nullable(false))
3193 .with_column("details", SqlScalarType::Jsonb.nullable(false))
3194 .with_column("user", SqlScalarType::String.nullable(true))
3195 .with_column(
3196 "occurred_at",
3197 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3198 )
3199 .with_key(vec![0])
3200 .finish(),
3201 column_comments: BTreeMap::from_iter([
3202 (
3203 "id",
3204 "Materialize's unique, monotonically increasing ID for the event.",
3205 ),
3206 (
3207 "event_type",
3208 "The type of the event: `create`, `drop`, `alter`, `grant`, `revoke`, or `comment`.",
3209 ),
3210 (
3211 "object_type",
3212 "The type of the affected object: `cluster`, `cluster-replica`, `connection`, `continual-task`, `database`, `func`, `index`, `materialized-view`, `metric-sink`, `network-policy`, `role`, `schema`, `secret`, `sink`, `source`, `system`, `table`, `type`, or `view`.",
3213 ),
3214 (
3215 "details",
3216 "Additional details about the event. The shape of the details varies based on `event_type` and `object_type`.",
3217 ),
3218 (
3219 "user",
3220 "The user who triggered the event, or `NULL` if triggered by the system.",
3221 ),
3222 (
3223 "occurred_at",
3224 "The time at which the event occurred. Guaranteed to be in order of event creation. Events created in the same transaction will have identical values.",
3225 ),
3226 ]),
3227 sql: "
3249IN CLUSTER mz_catalog_server
3250WITH (
3251 ASSERT NOT NULL id,
3252 ASSERT NOT NULL event_type,
3253 ASSERT NOT NULL object_type,
3254 ASSERT NOT NULL details,
3255 ASSERT NOT NULL occurred_at
3256) AS
3257WITH ev AS (
3258 SELECT data->'key'->'event'->'V1' AS e
3259 FROM mz_internal.mz_catalog_raw
3260 WHERE data->>'kind' = 'AuditLog'
3261)
3262SELECT
3263 (e->>'id')::uint8 AS id,
3264 CASE (e->>'event_type')
3265 WHEN '1' THEN 'create'
3266 WHEN '2' THEN 'drop'
3267 WHEN '3' THEN 'alter'
3268 WHEN '4' THEN 'grant'
3269 WHEN '5' THEN 'revoke'
3270 WHEN '6' THEN 'comment'
3271 END AS event_type,
3272 CASE (e->>'object_type')
3273 WHEN '1' THEN 'cluster'
3274 WHEN '2' THEN 'cluster-replica'
3275 WHEN '3' THEN 'connection'
3276 WHEN '4' THEN 'database'
3277 WHEN '5' THEN 'func'
3278 WHEN '6' THEN 'index'
3279 WHEN '7' THEN 'materialized-view'
3280 WHEN '8' THEN 'role'
3281 WHEN '9' THEN 'secret'
3282 WHEN '10' THEN 'schema'
3283 WHEN '11' THEN 'sink'
3284 WHEN '12' THEN 'source'
3285 WHEN '13' THEN 'table'
3286 WHEN '14' THEN 'type'
3287 WHEN '15' THEN 'view'
3288 WHEN '16' THEN 'system'
3289 WHEN '17' THEN 'continual-task'
3290 WHEN '18' THEN 'network-policy'
3291 WHEN '19' THEN 'metric-sink'
3292 END AS object_type,
3293 mz_internal.parse_catalog_audit_log_details(e->'details') AS details,
3294 e->'user'->>'inner' AS \"user\",
3295 -- `occurred_at` is serialized by `proto::EpochMillis` as
3296 -- `{\"millis\": <u64>}`; reach through `'millis'` to get the integer.
3297 to_timestamp(((e->'occurred_at'->>'millis')::float8) / 1000.0) AS occurred_at
3298FROM ev",
3299 is_retained_metrics_object: false,
3300 access: vec![PUBLIC_SELECT],
3301 ontology: Some(Ontology {
3302 entity_name: "audit_event",
3303 description: "An audit log entry recording a DDL operation",
3304 links: &const { [] },
3305 column_semantic_types: &const {
3306 [
3307 ("object_type", SemanticType::ObjectType),
3308 ("occurred_at", SemanticType::WallclockTimestamp),
3309 ]
3310 },
3311 }),
3312 }
3313});
3314
3315pub static MZ_EGRESS_IPS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
3316 name: "mz_egress_ips",
3317 schema: MZ_CATALOG_SCHEMA,
3318 oid: oid::TABLE_MZ_EGRESS_IPS_OID,
3319 desc: RelationDesc::builder()
3320 .with_column("egress_ip", SqlScalarType::String.nullable(false))
3321 .with_column("prefix_length", SqlScalarType::Int32.nullable(false))
3322 .with_column("cidr", SqlScalarType::String.nullable(false))
3323 .finish(),
3324 column_comments: BTreeMap::from_iter([
3325 ("egress_ip", "The start of the range of IP addresses."),
3326 (
3327 "prefix_length",
3328 "The number of leading bits in the CIDR netmask.",
3329 ),
3330 ("cidr", "The CIDR representation."),
3331 ]),
3332 is_retained_metrics_object: false,
3333 access: vec![PUBLIC_SELECT],
3334 ontology: Some(Ontology {
3335 entity_name: "egress_ip",
3336 description: "IP addresses used for outbound connections from Materialize",
3337 links: &const { [] },
3338 column_semantic_types: &[],
3339 }),
3340});
3341
3342pub static MZ_AWS_PRIVATELINK_CONNECTIONS: LazyLock<BuiltinMaterializedView> =
3350 LazyLock::new(|| {
3351 BuiltinMaterializedView {
3352 name: "mz_aws_privatelink_connections",
3353 schema: MZ_CATALOG_SCHEMA,
3354 oid: oid::MV_MZ_AWS_PRIVATELINK_CONNECTIONS_OID,
3355 desc: RelationDesc::builder()
3356 .with_column("id", SqlScalarType::String.nullable(false))
3357 .with_column("principal", SqlScalarType::String.nullable(false))
3358 .with_key(vec![0])
3359 .finish(),
3360 column_comments: BTreeMap::from_iter([
3361 ("id", "The ID of the connection."),
3362 (
3363 "principal",
3364 "The AWS Principal that Materialize will use to connect to the VPC endpoint.",
3365 ),
3366 ]),
3367 sql: "
3370IN CLUSTER mz_catalog_server
3371WITH (
3372 ASSERT NOT NULL id,
3373 ASSERT NOT NULL principal
3374) AS
3375SELECT id, principal FROM (
3376 SELECT
3377 mz_internal.parse_catalog_id(r.data->'key'->'gid') AS id,
3378 'arn:aws:iam::' || mz_aws_account_id() || ':role/mz_'
3379 || mz_aws_external_id_prefix() || '_'
3380 || mz_internal.parse_catalog_id(r.data->'key'->'gid') AS principal
3381 FROM mz_internal.mz_catalog_raw r
3382 WHERE
3383 r.data->>'kind' = 'Item' AND
3384 mz_internal.parse_catalog_create_sql(
3385 r.data->'value'->'definition'->'V1'->>'create_sql')->>'connection_type'
3386 = 'aws-privatelink'
3387)
3388WHERE principal IS NOT NULL",
3389 is_retained_metrics_object: false,
3390 access: vec![PUBLIC_SELECT],
3391 ontology: Some(Ontology {
3392 entity_name: "aws_privatelink_connection",
3393 description: "AWS PrivateLink connection configuration",
3394 links: &const {
3395 [OntologyLink {
3396 name: "details_of",
3397 target: "connection",
3398 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
3399 }]
3400 },
3401 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
3402 }),
3403 }
3404 });
3405
3406pub static MZ_CLUSTER_REPLICA_FRONTIERS: LazyLock<BuiltinSource> =
3407 LazyLock::new(|| BuiltinSource {
3408 name: "mz_cluster_replica_frontiers",
3409 schema: MZ_CATALOG_SCHEMA,
3410 oid: oid::SOURCE_MZ_CLUSTER_REPLICA_FRONTIERS_OID,
3411 data_source: IntrospectionType::ReplicaFrontiers.into(),
3412 desc: RelationDesc::builder()
3413 .with_column("object_id", SqlScalarType::String.nullable(false))
3414 .with_column("replica_id", SqlScalarType::String.nullable(false))
3415 .with_column("write_frontier", SqlScalarType::MzTimestamp.nullable(true))
3416 .finish(),
3417 column_comments: BTreeMap::from_iter([
3418 (
3419 "object_id",
3420 "The ID of the source, sink, index, materialized view, or subscription.",
3421 ),
3422 ("replica_id", "The ID of a cluster replica."),
3423 (
3424 "write_frontier",
3425 "The next timestamp at which the output may change.",
3426 ),
3427 ]),
3428 is_retained_metrics_object: false,
3429 access: vec![PUBLIC_SELECT],
3430 ontology: None,
3431 });
3432
3433pub static MZ_CLUSTER_REPLICA_FRONTIERS_IND: LazyLock<BuiltinIndex> =
3434 LazyLock::new(|| BuiltinIndex {
3435 name: "mz_cluster_replica_frontiers_ind",
3436 schema: MZ_CATALOG_SCHEMA,
3437 oid: oid::INDEX_MZ_CLUSTER_REPLICA_FRONTIERS_IND_OID,
3438 sql: "IN CLUSTER mz_catalog_server ON mz_catalog.mz_cluster_replica_frontiers (object_id)",
3439 is_retained_metrics_object: false,
3440 });
3441
3442pub static MZ_DEFAULT_PRIVILEGES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
3443 BuiltinMaterializedView {
3444 name: "mz_default_privileges",
3445 schema: MZ_CATALOG_SCHEMA,
3446 oid: oid::MV_MZ_DEFAULT_PRIVILEGES_OID,
3447 desc: RelationDesc::builder()
3448 .with_column("role_id", SqlScalarType::String.nullable(false))
3449 .with_column("database_id", SqlScalarType::String.nullable(true))
3450 .with_column("schema_id", SqlScalarType::String.nullable(true))
3451 .with_column("object_type", SqlScalarType::String.nullable(false))
3452 .with_column("grantee", SqlScalarType::String.nullable(false))
3453 .with_column("privileges", SqlScalarType::String.nullable(false))
3454 .finish(),
3455 column_comments: BTreeMap::from_iter([
3456 (
3457 "role_id",
3458 "Privileges described in this row will be granted on objects created by `role_id`. The role ID `p` stands for the `PUBLIC` pseudo-role and applies to all roles.",
3459 ),
3460 (
3461 "database_id",
3462 "Privileges described in this row will be granted only on objects in the database identified by `database_id` if non-null.",
3463 ),
3464 (
3465 "schema_id",
3466 "Privileges described in this row will be granted only on objects in the schema identified by `schema_id` if non-null.",
3467 ),
3468 (
3469 "object_type",
3470 "Privileges described in this row will be granted only on objects of type `object_type`.",
3471 ),
3472 (
3473 "grantee",
3474 "Privileges described in this row will be granted to `grantee`. The role ID `p` stands for the `PUBLIC` pseudo-role and applies to all roles.",
3475 ),
3476 ("privileges", "The set of privileges that will be granted."),
3477 ]),
3478 sql: "
3486IN CLUSTER mz_catalog_server
3487WITH (
3488 ASSERT NOT NULL role_id,
3489 ASSERT NOT NULL object_type,
3490 ASSERT NOT NULL grantee,
3491 ASSERT NOT NULL privileges
3492) AS
3493SELECT
3494 mz_internal.parse_catalog_id(data->'key'->'role_id') AS role_id,
3495 CASE WHEN data->'key'->'database_id' != 'null'::jsonb
3496 THEN mz_internal.parse_catalog_id(data->'key'->'database_id') END AS database_id,
3497 CASE WHEN data->'key'->'schema_id' != 'null'::jsonb
3498 THEN mz_internal.parse_catalog_id(data->'key'->'schema_id') END AS schema_id,
3499 CASE data->'key'->>'object_type'
3500 WHEN '1' THEN 'table'
3501 WHEN '2' THEN 'view'
3502 WHEN '3' THEN 'materialized view'
3503 WHEN '4' THEN 'source'
3504 WHEN '5' THEN 'sink'
3505 WHEN '6' THEN 'index'
3506 WHEN '7' THEN 'type'
3507 WHEN '8' THEN 'role'
3508 WHEN '9' THEN 'cluster'
3509 WHEN '10' THEN 'cluster replica'
3510 WHEN '11' THEN 'secret'
3511 WHEN '12' THEN 'connection'
3512 WHEN '13' THEN 'database'
3513 WHEN '14' THEN 'schema'
3514 WHEN '15' THEN 'function'
3515 -- variant 16 reserved/unused in mz_catalog_protos::ObjectType.
3516 WHEN '17' THEN 'network policy'
3517 END AS object_type,
3518 mz_internal.parse_catalog_id(data->'key'->'grantee') AS grantee,
3519 mz_internal.parse_catalog_acl_mode(data->'value'->'privileges') AS privileges
3520FROM mz_internal.mz_catalog_raw
3521WHERE data->>'kind' = 'DefaultPrivileges'",
3522 is_retained_metrics_object: false,
3523 access: vec![PUBLIC_SELECT],
3524 ontology: Some(Ontology {
3525 entity_name: "default_privilege",
3526 description: "A default privilege rule applied to newly created objects",
3527 links: &const {
3528 [
3529 OntologyLink {
3530 name: "default_priv_for_role",
3531 target: "role",
3532 properties: LinkProperties::fk("role_id", "id", Cardinality::ManyToOne),
3533 },
3534 OntologyLink {
3535 name: "default_priv_in_database",
3536 target: "database",
3537 properties: LinkProperties::fk_nullable(
3538 "database_id",
3539 "id",
3540 Cardinality::ManyToOne,
3541 ),
3542 },
3543 OntologyLink {
3544 name: "default_priv_in_schema",
3545 target: "schema",
3546 properties: LinkProperties::fk_nullable(
3547 "schema_id",
3548 "id",
3549 Cardinality::ManyToOne,
3550 ),
3551 },
3552 OntologyLink {
3553 name: "default_priv_granted_to",
3554 target: "role",
3555 properties: LinkProperties::fk("grantee", "id", Cardinality::ManyToOne),
3556 },
3557 ]
3558 },
3559 column_semantic_types: &const {
3560 [
3561 ("role_id", SemanticType::RoleId),
3562 ("database_id", SemanticType::DatabaseId),
3563 ("schema_id", SemanticType::SchemaId),
3564 ("object_type", SemanticType::ObjectType),
3565 ("grantee", SemanticType::RoleId),
3566 ]
3567 },
3568 }),
3569 }
3570});
3571
3572pub static MZ_SYSTEM_PRIVILEGES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
3573 BuiltinMaterializedView {
3574 name: "mz_system_privileges",
3575 schema: MZ_CATALOG_SCHEMA,
3576 oid: oid::MV_MZ_SYSTEM_PRIVILEGES_OID,
3577 desc: RelationDesc::builder()
3578 .with_column("privileges", SqlScalarType::MzAclItem.nullable(false))
3579 .finish(),
3580 column_comments: BTreeMap::from_iter([(
3581 "privileges",
3582 "The privileges belonging to the system.",
3583 )]),
3584 sql: "
3588IN CLUSTER mz_catalog_server
3589WITH (
3590 ASSERT NOT NULL privileges
3591) AS
3592SELECT
3593 unnest(mz_internal.parse_catalog_privileges(
3594 jsonb_build_array(
3595 jsonb_build_object(
3596 'grantee', data->'key'->'grantee',
3597 'grantor', data->'key'->'grantor',
3598 'acl_mode', data->'value'->'acl_mode'
3599 )
3600 )
3601 )) AS privileges
3602FROM mz_internal.mz_catalog_raw
3603WHERE data->>'kind' = 'SystemPrivileges'",
3604 is_retained_metrics_object: false,
3605 access: vec![PUBLIC_SELECT],
3606 ontology: Some(Ontology {
3607 entity_name: "system_privilege",
3608 description: "A system-level privilege grant",
3609 links: &const { [] },
3610 column_semantic_types: &[],
3611 }),
3612 }
3613});
3614
3615pub static MZ_STORAGE_USAGE: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3616 name: "mz_storage_usage",
3617 schema: MZ_CATALOG_SCHEMA,
3618 oid: oid::VIEW_MZ_STORAGE_USAGE_OID,
3619 desc: RelationDesc::builder()
3620 .with_column("object_id", SqlScalarType::String.nullable(false))
3621 .with_column("size_bytes", SqlScalarType::UInt64.nullable(false))
3622 .with_column(
3623 "collection_timestamp",
3624 SqlScalarType::TimestampTz { precision: None }.nullable(false),
3625 )
3626 .with_key(vec![0, 2])
3627 .finish(),
3628 column_comments: BTreeMap::from_iter([
3629 (
3630 "object_id",
3631 "The ID of the table, source, or materialized view.",
3632 ),
3633 (
3634 "size_bytes",
3635 "The number of storage bytes used by the object.",
3636 ),
3637 (
3638 "collection_timestamp",
3639 "The time at which storage usage of the object was assessed.",
3640 ),
3641 ]),
3642 sql: "
3643SELECT
3644 object_id,
3645 sum(size_bytes)::uint8 AS size_bytes,
3646 collection_timestamp
3647FROM
3648 mz_internal.mz_storage_shards
3649 JOIN mz_internal.mz_storage_usage_by_shard USING (shard_id)
3650GROUP BY object_id, collection_timestamp",
3651 access: vec![PUBLIC_SELECT],
3652 ontology: Some(Ontology {
3653 entity_name: "storage_usage",
3654 description: "Historical storage usage per object over time",
3655 links: &const {
3656 [OntologyLink {
3657 name: "storage_usage_of",
3658 target: "object",
3659 properties: LinkProperties::fk("object_id", "id", Cardinality::ManyToOne),
3660 }]
3661 },
3662 column_semantic_types: &const {
3663 [
3664 ("object_id", SemanticType::CatalogItemId),
3665 ("size_bytes", SemanticType::ByteCount),
3666 ("collection_timestamp", SemanticType::WallclockTimestamp),
3667 ]
3668 },
3669 }),
3670});
3671
3672pub static MZ_RECENT_STORAGE_USAGE: LazyLock<BuiltinView> = LazyLock::new(|| {
3673 BuiltinView {
3674 name: "mz_recent_storage_usage",
3675 schema: MZ_CATALOG_SCHEMA,
3676 oid: oid::VIEW_MZ_RECENT_STORAGE_USAGE_OID,
3677 desc: RelationDesc::builder()
3678 .with_column("object_id", SqlScalarType::String.nullable(false))
3679 .with_column("size_bytes", SqlScalarType::UInt64.nullable(true))
3680 .with_key(vec![0])
3681 .finish(),
3682 column_comments: BTreeMap::from_iter([
3683 ("object_id", "The ID of the table, source, or materialized view."),
3684 ("size_bytes", "The number of storage bytes used by the object in the most recent assessment."),
3685 ]),
3686 sql: "
3687WITH
3688
3689recent_storage_usage_by_shard AS (
3690 SELECT shard_id, size_bytes, collection_timestamp
3691 FROM mz_internal.mz_storage_usage_by_shard
3692 -- Restricting to the last 6 hours makes it feasible to index the view.
3693 WHERE collection_timestamp + '6 hours' >= mz_now()
3694),
3695
3696most_recent_collection_timestamp_by_shard AS (
3697 SELECT shard_id, max(collection_timestamp) AS collection_timestamp
3698 FROM recent_storage_usage_by_shard
3699 GROUP BY shard_id
3700)
3701
3702SELECT
3703 object_id,
3704 sum(size_bytes)::uint8 AS size_bytes
3705FROM
3706 mz_internal.mz_storage_shards
3707 LEFT JOIN most_recent_collection_timestamp_by_shard
3708 ON mz_storage_shards.shard_id = most_recent_collection_timestamp_by_shard.shard_id
3709 LEFT JOIN recent_storage_usage_by_shard
3710 ON mz_storage_shards.shard_id = recent_storage_usage_by_shard.shard_id
3711 AND most_recent_collection_timestamp_by_shard.collection_timestamp = recent_storage_usage_by_shard.collection_timestamp
3712GROUP BY object_id",
3713 access: vec![PUBLIC_SELECT],
3714 ontology: Some(Ontology {
3715 entity_name: "recent_storage",
3716 description: "Most recent storage usage snapshot per object",
3717 links: &const { [
3718 OntologyLink { name: "recent_storage_of", target: "object", properties: LinkProperties::fk("object_id", "id", Cardinality::OneToOne) },
3719 ] },
3720 column_semantic_types: &const {[("object_id", SemanticType::CatalogItemId), ("size_bytes", SemanticType::ByteCount)]},
3721 }),
3722}
3723});
3724
3725pub static MZ_RECENT_STORAGE_USAGE_IND: LazyLock<BuiltinIndex> = LazyLock::new(|| BuiltinIndex {
3726 name: "mz_recent_storage_usage_ind",
3727 schema: MZ_CATALOG_SCHEMA,
3728 oid: oid::INDEX_MZ_RECENT_STORAGE_USAGE_IND_OID,
3729 sql: "IN CLUSTER mz_catalog_server ON mz_catalog.mz_recent_storage_usage (object_id)",
3730 is_retained_metrics_object: false,
3731});
3732
3733pub static MZ_RELATIONS: LazyLock<BuiltinView> = LazyLock::new(|| {
3734 BuiltinView {
3735 name: "mz_relations",
3736 schema: MZ_CATALOG_SCHEMA,
3737 oid: oid::VIEW_MZ_RELATIONS_OID,
3738 desc: RelationDesc::builder()
3739 .with_column("id", SqlScalarType::String.nullable(false))
3740 .with_column("oid", SqlScalarType::Oid.nullable(false))
3741 .with_column("schema_id", SqlScalarType::String.nullable(false))
3742 .with_column("name", SqlScalarType::String.nullable(false))
3743 .with_column("type", SqlScalarType::String.nullable(false))
3744 .with_column("owner_id", SqlScalarType::String.nullable(false))
3745 .with_column("cluster_id", SqlScalarType::String.nullable(true))
3746 .with_column("privileges", SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false))
3747 .finish(),
3748 column_comments: BTreeMap::from_iter([
3749 ("id", "Materialize's unique ID for the relation."),
3750 ("oid", "A PostgreSQL-compatible OID for the relation."),
3751 ("schema_id", "The ID of the schema to which the relation belongs. Corresponds to `mz_schemas.id`."),
3752 ("name", "The name of the relation."),
3753 ("type", "The type of the relation: either `table`, `source`, `view`, or `materialized-view`."),
3754 ("owner_id", "The role ID of the owner of the relation. Corresponds to `mz_roles.id`."),
3755 ("cluster_id", "The ID of the cluster maintaining the source, materialized view, index, or sink. Corresponds to `mz_clusters.id`. `NULL` for other object types."),
3756 ("privileges", "The privileges belonging to the relation."),
3757 ]),
3758 sql: "
3759 SELECT id, oid, schema_id, name, 'table' AS type, owner_id, NULL::text AS cluster_id, privileges FROM mz_catalog.mz_tables
3760UNION ALL SELECT id, oid, schema_id, name, 'source', owner_id, cluster_id, privileges FROM mz_catalog.mz_sources
3761UNION ALL SELECT id, oid, schema_id, name, 'view', owner_id, NULL::text, privileges FROM mz_catalog.mz_views
3762UNION ALL SELECT id, oid, schema_id, name, 'materialized-view', owner_id, cluster_id, privileges FROM mz_catalog.mz_materialized_views",
3763 access: vec![PUBLIC_SELECT],
3764 ontology: Some(Ontology {
3765 entity_name: "relation",
3766 description: "Union of all relation types: tables, sources, views, MVs (convenience view)",
3767 links: &const { [
3768 OntologyLink { name: "union_includes", target: "table", properties: LinkProperties::union_disc("type", "table") },
3769 OntologyLink { name: "union_includes", target: "source", properties: LinkProperties::union_disc("type", "source") },
3770 OntologyLink { name: "union_includes", target: "view", properties: LinkProperties::union_disc("type", "view") },
3771 OntologyLink { name: "union_includes", target: "mv", properties: LinkProperties::union_disc("type", "materialized-view") },
3772 ] },
3773 column_semantic_types: &const {[("id", SemanticType::CatalogItemId), ("oid", SemanticType::OID), ("schema_id", SemanticType::SchemaId), ("type", SemanticType::ObjectType), ("owner_id", SemanticType::RoleId), ("cluster_id", SemanticType::ClusterId)]},
3774 }),
3775 }
3776});
3777
3778pub static MZ_OBJECTS: LazyLock<BuiltinView> = LazyLock::new(|| {
3779 BuiltinView {
3780 name: "mz_objects",
3781 schema: MZ_CATALOG_SCHEMA,
3782 oid: oid::VIEW_MZ_OBJECTS_OID,
3783 desc: RelationDesc::builder()
3784 .with_column("id", SqlScalarType::String.nullable(false))
3785 .with_column("oid", SqlScalarType::Oid.nullable(false))
3786 .with_column("schema_id", SqlScalarType::String.nullable(false))
3787 .with_column("name", SqlScalarType::String.nullable(false))
3788 .with_column("type", SqlScalarType::String.nullable(false))
3789 .with_column("owner_id", SqlScalarType::String.nullable(false))
3790 .with_column("cluster_id", SqlScalarType::String.nullable(true))
3791 .with_column("privileges", SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(true))
3792 .finish(),
3793 column_comments: BTreeMap::from_iter([
3794 ("id", "Materialize's unique ID for the object."),
3795 ("oid", "A PostgreSQL-compatible OID for the object."),
3796 ("schema_id", "The ID of the schema to which the object belongs. Corresponds to `mz_schemas.id`."),
3797 ("name", "The name of the object."),
3798 ("type", "The type of the object: one of `table`, `source`, `view`, `materialized-view`, `sink`, `metric-sink`, `index`, `connection`, `secret`, `type`, or `function`."),
3799 ("owner_id", "The role ID of the owner of the object. Corresponds to `mz_roles.id`."),
3800 ("cluster_id", "The ID of the cluster maintaining the source, materialized view, index, or sink. Corresponds to `mz_clusters.id`. `NULL` for other object types."),
3801 ("privileges", "The privileges belonging to the object."),
3802 ]),
3803 sql:
3804 "SELECT id, oid, schema_id, name, type, owner_id, cluster_id, privileges FROM mz_catalog.mz_relations
3805UNION ALL
3806 SELECT id, oid, schema_id, name, 'sink', owner_id, cluster_id, NULL::mz_catalog.mz_aclitem[] FROM mz_catalog.mz_sinks
3807UNION ALL
3808 SELECT id, oid, schema_id, name, 'metric-sink', owner_id, cluster_id, NULL::mz_catalog.mz_aclitem[] FROM mz_internal.mz_metric_sinks
3809UNION ALL
3810 SELECT mz_indexes.id, mz_indexes.oid, mz_relations.schema_id, mz_indexes.name, 'index', mz_indexes.owner_id, mz_indexes.cluster_id, NULL::mz_catalog.mz_aclitem[]
3811 FROM mz_catalog.mz_indexes
3812 JOIN mz_catalog.mz_relations ON mz_indexes.on_id = mz_relations.id
3813UNION ALL
3814 SELECT id, oid, schema_id, name, 'connection', owner_id, NULL::text, privileges FROM mz_catalog.mz_connections
3815UNION ALL
3816 SELECT id, oid, schema_id, name, 'type', owner_id, NULL::text, privileges FROM mz_catalog.mz_types
3817UNION ALL
3818 SELECT id, oid, schema_id, name, 'function', owner_id, NULL::text, NULL::mz_catalog.mz_aclitem[] FROM mz_catalog.mz_functions
3819UNION ALL
3820 SELECT id, oid, schema_id, name, 'secret', owner_id, NULL::text, privileges FROM mz_catalog.mz_secrets",
3821 access: vec![PUBLIC_SELECT],
3822 ontology: Some(Ontology {
3823 entity_name: "object",
3824 description: "Union of all object types: relations, indexes, connections, etc. (convenience view)",
3825 links: &const {
3826 [
3827 OntologyLink {
3828 name: "union_includes",
3829 target: "relation",
3830 properties: LinkProperties::Union {
3831 discriminator_column: None,
3832 discriminator_value: None,
3833 note: Some("covers all mz_relations rows (table, source, view, mv)"),
3834 },
3835 },
3836 OntologyLink {
3837 name: "union_includes",
3838 target: "table",
3839 properties: LinkProperties::union_disc("type", "table"),
3840 },
3841 OntologyLink {
3842 name: "union_includes",
3843 target: "source",
3844 properties: LinkProperties::union_disc("type", "source"),
3845 },
3846 OntologyLink {
3847 name: "union_includes",
3848 target: "view",
3849 properties: LinkProperties::union_disc("type", "view"),
3850 },
3851 OntologyLink {
3852 name: "union_includes",
3853 target: "mv",
3854 properties: LinkProperties::union_disc("type", "materialized-view"),
3855 },
3856 OntologyLink {
3857 name: "union_includes",
3858 target: "sink",
3859 properties: LinkProperties::union_disc("type", "sink"),
3860 },
3861 OntologyLink {
3862 name: "union_includes",
3863 target: "index",
3864 properties: LinkProperties::union_disc("type", "index"),
3865 },
3866 OntologyLink {
3867 name: "union_includes",
3868 target: "connection",
3869 properties: LinkProperties::union_disc("type", "connection"),
3870 },
3871 OntologyLink {
3872 name: "union_includes",
3873 target: "type",
3874 properties: LinkProperties::union_disc("type", "type"),
3875 },
3876 OntologyLink {
3877 name: "union_includes",
3878 target: "function",
3879 properties: LinkProperties::union_disc("type", "function"),
3880 },
3881 OntologyLink {
3882 name: "union_includes",
3883 target: "secret",
3884 properties: LinkProperties::union_disc("type", "secret"),
3885 },
3886 OntologyLink {
3887 name: "in_schema",
3888 target: "schema",
3889 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
3890 },
3891 OntologyLink {
3892 name: "owned_by",
3893 target: "role",
3894 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
3895 },
3896 OntologyLink {
3897 name: "on_cluster",
3898 target: "cluster",
3899 properties: LinkProperties::fk_nullable(
3900 "cluster_id",
3901 "id",
3902 Cardinality::ManyToOne,
3903 ),
3904 },
3905 ]
3906 },
3907 column_semantic_types: &const {
3908 [
3909 ("id", SemanticType::CatalogItemId),
3910 ("oid", SemanticType::OID),
3911 ("schema_id", SemanticType::SchemaId),
3912 ("type", SemanticType::ObjectType),
3913 ("owner_id", SemanticType::RoleId),
3914 ("cluster_id", SemanticType::ClusterId),
3915 ]
3916 },
3917 }),
3918 }
3919});
3920
3921pub static MZ_TIMEZONE_ABBREVIATIONS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3922 name: "mz_timezone_abbreviations",
3923 schema: MZ_CATALOG_SCHEMA,
3924 oid: oid::VIEW_MZ_TIMEZONE_ABBREVIATIONS_OID,
3925 desc: RelationDesc::builder()
3926 .with_column("abbreviation", SqlScalarType::String.nullable(false))
3927 .with_column("utc_offset", SqlScalarType::Interval.nullable(true))
3928 .with_column("dst", SqlScalarType::Bool.nullable(true))
3929 .with_column("timezone_name", SqlScalarType::String.nullable(true))
3930 .with_key(vec![0])
3931 .finish(),
3932 column_comments: BTreeMap::from_iter([
3933 ("abbreviation", "The timezone abbreviation."),
3934 (
3935 "utc_offset",
3936 "The UTC offset of the timezone or `NULL` if fixed.",
3937 ),
3938 (
3939 "dst",
3940 "Whether the timezone is in daylight savings or `NULL` if fixed.",
3941 ),
3942 (
3943 "timezone_name",
3944 "The full name of the non-fixed timezone or `NULL` if not fixed.",
3945 ),
3946 ]),
3947 sql: format!(
3948 "SELECT * FROM ({}) _ (abbreviation, utc_offset, dst, timezone_name)",
3949 mz_pgtz::abbrev::MZ_CATALOG_TIMEZONE_ABBREVIATIONS_SQL,
3950 )
3951 .leak(),
3952 access: vec![PUBLIC_SELECT],
3953 ontology: None,
3954});
3955
3956pub static MZ_TIMEZONE_NAMES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3957 name: "mz_timezone_names",
3958 schema: MZ_CATALOG_SCHEMA,
3959 oid: oid::VIEW_MZ_TIMEZONE_NAMES_OID,
3960 desc: RelationDesc::builder()
3961 .with_column("name", SqlScalarType::String.nullable(false))
3962 .with_key(vec![0])
3963 .finish(),
3964 column_comments: BTreeMap::from_iter([("name", "The timezone name.")]),
3965 sql: format!(
3966 "SELECT * FROM ({}) _ (name)",
3967 mz_pgtz::timezone::MZ_CATALOG_TIMEZONE_NAMES_SQL,
3968 )
3969 .leak(),
3970 access: vec![PUBLIC_SELECT],
3971 ontology: None,
3972});
3973
3974pub const MZ_DATABASES_IND: BuiltinIndex = BuiltinIndex {
3975 name: "mz_databases_ind",
3976 schema: MZ_CATALOG_SCHEMA,
3977 oid: oid::INDEX_MZ_DATABASES_IND_OID,
3978 sql: "IN CLUSTER mz_catalog_server
3979ON mz_catalog.mz_databases (name)",
3980 is_retained_metrics_object: false,
3981};
3982
3983pub const MZ_SCHEMAS_IND: BuiltinIndex = BuiltinIndex {
3984 name: "mz_schemas_ind",
3985 schema: MZ_CATALOG_SCHEMA,
3986 oid: oid::INDEX_MZ_SCHEMAS_IND_OID,
3987 sql: "IN CLUSTER mz_catalog_server
3988ON mz_catalog.mz_schemas (database_id)",
3989 is_retained_metrics_object: false,
3990};
3991
3992pub const MZ_CONNECTIONS_IND: BuiltinIndex = BuiltinIndex {
3993 name: "mz_connections_ind",
3994 schema: MZ_CATALOG_SCHEMA,
3995 oid: oid::INDEX_MZ_CONNECTIONS_IND_OID,
3996 sql: "IN CLUSTER mz_catalog_server
3997ON mz_catalog.mz_connections (schema_id)",
3998 is_retained_metrics_object: false,
3999};
4000
4001pub const MZ_TABLES_IND: BuiltinIndex = BuiltinIndex {
4002 name: "mz_tables_ind",
4003 schema: MZ_CATALOG_SCHEMA,
4004 oid: oid::INDEX_MZ_TABLES_IND_OID,
4005 sql: "IN CLUSTER mz_catalog_server
4006ON mz_catalog.mz_tables (schema_id)",
4007 is_retained_metrics_object: false,
4008};
4009
4010pub const MZ_TYPES_IND: BuiltinIndex = BuiltinIndex {
4011 name: "mz_types_ind",
4012 schema: MZ_CATALOG_SCHEMA,
4013 oid: oid::INDEX_MZ_TYPES_IND_OID,
4014 sql: "IN CLUSTER mz_catalog_server
4015ON mz_catalog.mz_types (schema_id)",
4016 is_retained_metrics_object: false,
4017};
4018
4019pub const MZ_OBJECTS_IND: BuiltinIndex = BuiltinIndex {
4020 name: "mz_objects_ind",
4021 schema: MZ_CATALOG_SCHEMA,
4022 oid: oid::INDEX_MZ_OBJECTS_IND_OID,
4023 sql: "IN CLUSTER mz_catalog_server
4024ON mz_catalog.mz_objects (schema_id)",
4025 is_retained_metrics_object: false,
4026};
4027
4028pub const MZ_COLUMNS_IND: BuiltinIndex = BuiltinIndex {
4029 name: "mz_columns_ind",
4030 schema: MZ_CATALOG_SCHEMA,
4031 oid: oid::INDEX_MZ_COLUMNS_IND_OID,
4032 sql: "IN CLUSTER mz_catalog_server
4033ON mz_catalog.mz_columns (name)",
4034 is_retained_metrics_object: false,
4035};
4036
4037pub const MZ_SECRETS_IND: BuiltinIndex = BuiltinIndex {
4038 name: "mz_secrets_ind",
4039 schema: MZ_CATALOG_SCHEMA,
4040 oid: oid::INDEX_MZ_SECRETS_IND_OID,
4041 sql: "IN CLUSTER mz_catalog_server
4042ON mz_catalog.mz_secrets (name)",
4043 is_retained_metrics_object: false,
4044};
4045
4046pub const MZ_VIEWS_IND: BuiltinIndex = BuiltinIndex {
4047 name: "mz_views_ind",
4048 schema: MZ_CATALOG_SCHEMA,
4049 oid: oid::INDEX_MZ_VIEWS_IND_OID,
4050 sql: "IN CLUSTER mz_catalog_server
4051ON mz_catalog.mz_views (schema_id)",
4052 is_retained_metrics_object: false,
4053};
4054
4055pub const MZ_CLUSTERS_IND: BuiltinIndex = BuiltinIndex {
4056 name: "mz_clusters_ind",
4057 schema: MZ_CATALOG_SCHEMA,
4058 oid: oid::INDEX_MZ_CLUSTERS_IND_OID,
4059 sql: "IN CLUSTER mz_catalog_server
4060ON mz_catalog.mz_clusters (id)",
4061 is_retained_metrics_object: false,
4062};
4063
4064pub const MZ_INDEXES_IND: BuiltinIndex = BuiltinIndex {
4065 name: "mz_indexes_ind",
4066 schema: MZ_CATALOG_SCHEMA,
4067 oid: oid::INDEX_MZ_INDEXES_IND_OID,
4068 sql: "IN CLUSTER mz_catalog_server
4069ON mz_catalog.mz_indexes (id)",
4070 is_retained_metrics_object: false,
4071};
4072
4073pub const MZ_ROLES_IND: BuiltinIndex = BuiltinIndex {
4074 name: "mz_roles_ind",
4075 schema: MZ_CATALOG_SCHEMA,
4076 oid: oid::INDEX_MZ_ROLES_IND_OID,
4077 sql: "IN CLUSTER mz_catalog_server
4078ON mz_catalog.mz_roles (id)",
4079 is_retained_metrics_object: false,
4080};
4081
4082pub const MZ_SOURCES_IND: BuiltinIndex = BuiltinIndex {
4083 name: "mz_sources_ind",
4084 schema: MZ_CATALOG_SCHEMA,
4085 oid: oid::INDEX_MZ_SOURCES_IND_OID,
4086 sql: "IN CLUSTER mz_catalog_server
4087ON mz_catalog.mz_sources (id)",
4088 is_retained_metrics_object: true,
4089};
4090
4091pub const MZ_SINKS_IND: BuiltinIndex = BuiltinIndex {
4092 name: "mz_sinks_ind",
4093 schema: MZ_CATALOG_SCHEMA,
4094 oid: oid::INDEX_MZ_SINKS_IND_OID,
4095 sql: "IN CLUSTER mz_catalog_server
4096ON mz_catalog.mz_sinks (id)",
4097 is_retained_metrics_object: true,
4098};
4099
4100pub const MZ_MATERIALIZED_VIEWS_IND: BuiltinIndex = BuiltinIndex {
4101 name: "mz_materialized_views_ind",
4102 schema: MZ_CATALOG_SCHEMA,
4103 oid: oid::INDEX_MZ_MATERIALIZED_VIEWS_IND_OID,
4104 sql: "IN CLUSTER mz_catalog_server
4105ON mz_catalog.mz_materialized_views (id)",
4106 is_retained_metrics_object: false,
4107};
4108
4109pub const MZ_CLUSTER_REPLICAS_IND: BuiltinIndex = BuiltinIndex {
4110 name: "mz_cluster_replicas_ind",
4111 schema: MZ_CATALOG_SCHEMA,
4112 oid: oid::INDEX_MZ_CLUSTER_REPLICAS_IND_OID,
4113 sql: "IN CLUSTER mz_catalog_server
4114ON mz_catalog.mz_cluster_replicas (id)",
4115 is_retained_metrics_object: true,
4116};
4117
4118pub const MZ_CLUSTER_REPLICA_SIZES_IND: BuiltinIndex = BuiltinIndex {
4119 name: "mz_cluster_replica_sizes_ind",
4120 schema: MZ_CATALOG_SCHEMA,
4121 oid: oid::INDEX_MZ_CLUSTER_REPLICA_SIZES_IND_OID,
4122 sql: "IN CLUSTER mz_catalog_server
4123ON mz_catalog.mz_cluster_replica_sizes (size)",
4124 is_retained_metrics_object: true,
4125};
4126
4127pub const MZ_KAFKA_SOURCES_IND: BuiltinIndex = BuiltinIndex {
4128 name: "mz_kafka_sources_ind",
4129 schema: MZ_CATALOG_SCHEMA,
4130 oid: oid::INDEX_MZ_KAFKA_SOURCES_IND_OID,
4131 sql: "IN CLUSTER mz_catalog_server
4132ON mz_catalog.mz_kafka_sources (id)",
4133 is_retained_metrics_object: true,
4134};
4135
4136#[cfg(test)]
4137mod tests {
4138 use mz_catalog_protos::objects::ObjectType as ProtoObjectType;
4139 use mz_sql::catalog::ObjectType as SqlObjectType;
4140
4141 use crate::builtin::mz_catalog::MZ_DEFAULT_PRIVILEGES;
4142
4143 #[mz_ore::test]
4151 fn object_type_case_matches_proto_display() {
4152 fn expected_for(proto: ProtoObjectType) -> Option<SqlObjectType> {
4158 match proto {
4159 ProtoObjectType::Unknown => None,
4160 ProtoObjectType::MetricSink => None,
4161 ProtoObjectType::Table => Some(SqlObjectType::Table),
4162 ProtoObjectType::View => Some(SqlObjectType::View),
4163 ProtoObjectType::MaterializedView => Some(SqlObjectType::MaterializedView),
4164 ProtoObjectType::Source => Some(SqlObjectType::Source),
4165 ProtoObjectType::Sink => Some(SqlObjectType::Sink),
4166 ProtoObjectType::Index => Some(SqlObjectType::Index),
4167 ProtoObjectType::Type => Some(SqlObjectType::Type),
4168 ProtoObjectType::Role => Some(SqlObjectType::Role),
4169 ProtoObjectType::Cluster => Some(SqlObjectType::Cluster),
4170 ProtoObjectType::ClusterReplica => Some(SqlObjectType::ClusterReplica),
4171 ProtoObjectType::Secret => Some(SqlObjectType::Secret),
4172 ProtoObjectType::Connection => Some(SqlObjectType::Connection),
4173 ProtoObjectType::Database => Some(SqlObjectType::Database),
4174 ProtoObjectType::Schema => Some(SqlObjectType::Schema),
4175 ProtoObjectType::Func => Some(SqlObjectType::Func),
4176 ProtoObjectType::NetworkPolicy => Some(SqlObjectType::NetworkPolicy),
4177 }
4178 }
4179
4180 let variants: &[ProtoObjectType] = &[
4185 ProtoObjectType::Unknown,
4186 ProtoObjectType::Table,
4187 ProtoObjectType::View,
4188 ProtoObjectType::MaterializedView,
4189 ProtoObjectType::Source,
4190 ProtoObjectType::Sink,
4191 ProtoObjectType::Index,
4192 ProtoObjectType::Type,
4193 ProtoObjectType::Role,
4194 ProtoObjectType::Cluster,
4195 ProtoObjectType::ClusterReplica,
4196 ProtoObjectType::Secret,
4197 ProtoObjectType::Connection,
4198 ProtoObjectType::Database,
4199 ProtoObjectType::Schema,
4200 ProtoObjectType::Func,
4201 ProtoObjectType::NetworkPolicy,
4202 ProtoObjectType::MetricSink,
4203 ];
4204
4205 let sql = MZ_DEFAULT_PRIVILEGES.sql;
4206 for &proto in variants {
4207 #[allow(clippy::as_conversions)]
4210 let repr = proto as u8;
4211 match expected_for(proto) {
4212 Some(sql_ty) => {
4213 let display = sql_ty.to_string().to_lowercase();
4214 let one_space = format!("WHEN '{repr}' THEN '{display}'");
4218 let two_spaces = format!("WHEN '{repr}' THEN '{display}'");
4219 assert!(
4220 sql.contains(&one_space) || sql.contains(&two_spaces),
4221 "missing CASE arm for `{proto:?}`: expected \
4222 `WHEN '{repr}' THEN '{display}'` (or with double space) \
4223 in MZ_DEFAULT_PRIVILEGES.sql",
4224 );
4225 }
4226 None => {
4227 let pattern = format!("WHEN '{repr}'");
4228 assert!(
4229 !sql.contains(&pattern),
4230 "unexpected CASE arm for sentinel `{proto:?}`: \
4231 found `{pattern}` in MZ_DEFAULT_PRIVILEGES.sql",
4232 );
4233 }
4234 }
4235 }
4236 }
4237}