1use std::collections::BTreeMap;
13use std::sync::LazyLock;
14
15use itertools::Itertools;
16use mz_ore::collections::CollectionExt;
17use mz_pgrepr::oid;
18use mz_repr::namespaces::MZ_CATALOG_SCHEMA;
19use mz_repr::{RelationDesc, SemanticType, SqlScalarType};
20use mz_sql::ast::Statement;
21use mz_sql::ast::display::{AstDisplay, escaped_string_literal};
22use mz_sql::catalog::{
23 CatalogType, CatalogTypeDetails, CatalogTypePgMetadata, NameReference, ObjectType,
24};
25use mz_sql::rbac;
26use mz_sql::session::user::{MZ_SYSTEM_ROLE_ID, SUPPORT_USER_NAME, SYSTEM_USER_NAME};
27use mz_storage_client::controller::IntrospectionType;
28
29use super::{
30 BuiltinIndex, BuiltinLog, BuiltinMaterializedView, BuiltinSource, BuiltinTable, BuiltinType,
31 BuiltinView, Cardinality, LinkProperties, Ontology, OntologyLink, PUBLIC_SELECT,
32};
33
34pub const TYPE_LIST: BuiltinType<NameReference> = BuiltinType {
35 name: "list",
36 schema: MZ_CATALOG_SCHEMA,
37 oid: mz_pgrepr::oid::TYPE_LIST_OID,
38 details: CatalogTypeDetails {
39 typ: CatalogType::Pseudo,
40 array_id: None,
41 pg_metadata: None,
42 },
43};
44
45pub const TYPE_MAP: BuiltinType<NameReference> = BuiltinType {
46 name: "map",
47 schema: MZ_CATALOG_SCHEMA,
48 oid: mz_pgrepr::oid::TYPE_MAP_OID,
49 details: CatalogTypeDetails {
50 typ: CatalogType::Pseudo,
51 array_id: None,
52 pg_metadata: None,
53 },
54};
55
56pub const TYPE_ANYCOMPATIBLELIST: BuiltinType<NameReference> = BuiltinType {
57 name: "anycompatiblelist",
58 schema: MZ_CATALOG_SCHEMA,
59 oid: mz_pgrepr::oid::TYPE_ANYCOMPATIBLELIST_OID,
60 details: CatalogTypeDetails {
61 typ: CatalogType::Pseudo,
62 array_id: None,
63 pg_metadata: None,
64 },
65};
66
67pub const TYPE_ANYCOMPATIBLEMAP: BuiltinType<NameReference> = BuiltinType {
68 name: "anycompatiblemap",
69 schema: MZ_CATALOG_SCHEMA,
70 oid: mz_pgrepr::oid::TYPE_ANYCOMPATIBLEMAP_OID,
71 details: CatalogTypeDetails {
72 typ: CatalogType::Pseudo,
73 array_id: None,
74 pg_metadata: None,
75 },
76};
77
78pub const TYPE_UINT2: BuiltinType<NameReference> = BuiltinType {
79 name: "uint2",
80 schema: MZ_CATALOG_SCHEMA,
81 oid: mz_pgrepr::oid::TYPE_UINT2_OID,
82 details: CatalogTypeDetails {
83 typ: CatalogType::UInt16,
84 array_id: None,
85 pg_metadata: None,
86 },
87};
88
89pub const TYPE_UINT2_ARRAY: BuiltinType<NameReference> = BuiltinType {
90 name: "_uint2",
91 schema: MZ_CATALOG_SCHEMA,
92 oid: mz_pgrepr::oid::TYPE_UINT2_ARRAY_OID,
93 details: CatalogTypeDetails {
94 typ: CatalogType::Array {
95 element_reference: TYPE_UINT2.name,
96 },
97 array_id: None,
98 pg_metadata: None,
99 },
100};
101
102pub const TYPE_UINT4: BuiltinType<NameReference> = BuiltinType {
103 name: "uint4",
104 schema: MZ_CATALOG_SCHEMA,
105 oid: mz_pgrepr::oid::TYPE_UINT4_OID,
106 details: CatalogTypeDetails {
107 typ: CatalogType::UInt32,
108 array_id: None,
109 pg_metadata: None,
110 },
111};
112
113pub const TYPE_UINT4_ARRAY: BuiltinType<NameReference> = BuiltinType {
114 name: "_uint4",
115 schema: MZ_CATALOG_SCHEMA,
116 oid: mz_pgrepr::oid::TYPE_UINT4_ARRAY_OID,
117 details: CatalogTypeDetails {
118 typ: CatalogType::Array {
119 element_reference: TYPE_UINT4.name,
120 },
121 array_id: None,
122 pg_metadata: None,
123 },
124};
125
126pub const TYPE_UINT8: BuiltinType<NameReference> = BuiltinType {
127 name: "uint8",
128 schema: MZ_CATALOG_SCHEMA,
129 oid: mz_pgrepr::oid::TYPE_UINT8_OID,
130 details: CatalogTypeDetails {
131 typ: CatalogType::UInt64,
132 array_id: None,
133 pg_metadata: None,
134 },
135};
136
137pub const TYPE_UINT8_ARRAY: BuiltinType<NameReference> = BuiltinType {
138 name: "_uint8",
139 schema: MZ_CATALOG_SCHEMA,
140 oid: mz_pgrepr::oid::TYPE_UINT8_ARRAY_OID,
141 details: CatalogTypeDetails {
142 typ: CatalogType::Array {
143 element_reference: TYPE_UINT8.name,
144 },
145 array_id: None,
146 pg_metadata: None,
147 },
148};
149
150pub const TYPE_MZ_TIMESTAMP: BuiltinType<NameReference> = BuiltinType {
151 name: "mz_timestamp",
152 schema: MZ_CATALOG_SCHEMA,
153 oid: mz_pgrepr::oid::TYPE_MZ_TIMESTAMP_OID,
154 details: CatalogTypeDetails {
155 typ: CatalogType::MzTimestamp,
156 array_id: None,
157 pg_metadata: None,
158 },
159};
160
161pub const TYPE_MZ_TIMESTAMP_ARRAY: BuiltinType<NameReference> = BuiltinType {
162 name: "_mz_timestamp",
163 schema: MZ_CATALOG_SCHEMA,
164 oid: mz_pgrepr::oid::TYPE_MZ_TIMESTAMP_ARRAY_OID,
165 details: CatalogTypeDetails {
166 typ: CatalogType::Array {
167 element_reference: TYPE_MZ_TIMESTAMP.name,
168 },
169 array_id: None,
170 pg_metadata: None,
171 },
172};
173
174pub const TYPE_MZ_ACL_ITEM: BuiltinType<NameReference> = BuiltinType {
175 name: "mz_aclitem",
176 schema: MZ_CATALOG_SCHEMA,
177 oid: mz_pgrepr::oid::TYPE_MZ_ACL_ITEM_OID,
178 details: CatalogTypeDetails {
179 typ: CatalogType::MzAclItem,
180 array_id: None,
181 pg_metadata: None,
182 },
183};
184
185pub const TYPE_MZ_ACL_ITEM_ARRAY: BuiltinType<NameReference> = BuiltinType {
186 name: "_mz_aclitem",
187 schema: MZ_CATALOG_SCHEMA,
188 oid: mz_pgrepr::oid::TYPE_MZ_ACL_ITEM_ARRAY_OID,
189 details: CatalogTypeDetails {
190 typ: CatalogType::Array {
191 element_reference: TYPE_MZ_ACL_ITEM.name,
192 },
193 array_id: None,
194 pg_metadata: Some(CatalogTypePgMetadata {
195 typinput_oid: 750,
196 typreceive_oid: 2400,
197 }),
198 },
199};
200
201pub static MZ_ICEBERG_SINKS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
202 name: "mz_iceberg_sinks",
203 schema: MZ_CATALOG_SCHEMA,
204 oid: oid::TABLE_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 is_retained_metrics_object: false,
219 access: vec![PUBLIC_SELECT],
220 ontology: Some(Ontology {
221 entity_name: "iceberg_sink",
222 description: "Iceberg-specific sink configuration (namespace, table)",
223 links: &const {
224 [OntologyLink {
225 name: "details_of",
226 target: "sink",
227 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
228 }]
229 },
230 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
231 }),
232});
233
234pub static MZ_KAFKA_SINKS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
235 name: "mz_kafka_sinks",
236 schema: MZ_CATALOG_SCHEMA,
237 oid: oid::TABLE_MZ_KAFKA_SINKS_OID,
238 desc: RelationDesc::builder()
239 .with_column("id", SqlScalarType::String.nullable(false))
240 .with_column("topic", SqlScalarType::String.nullable(false))
241 .with_key(vec![0])
242 .finish(),
243 column_comments: BTreeMap::from_iter([
244 ("id", "The ID of the sink."),
245 (
246 "topic",
247 "The name of the Kafka topic into which the sink is writing.",
248 ),
249 ]),
250 is_retained_metrics_object: false,
251 access: vec![PUBLIC_SELECT],
252 ontology: Some(Ontology {
253 entity_name: "kafka_sink",
254 description: "Kafka-specific sink configuration (topic)",
255 links: &const {
256 [OntologyLink {
257 name: "details_of",
258 target: "sink",
259 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
260 }]
261 },
262 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
263 }),
264});
265pub static MZ_KAFKA_CONNECTIONS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
266 name: "mz_kafka_connections",
267 schema: MZ_CATALOG_SCHEMA,
268 oid: oid::TABLE_MZ_KAFKA_CONNECTIONS_OID,
269 desc: RelationDesc::builder()
270 .with_column("id", SqlScalarType::String.nullable(false))
271 .with_column(
272 "brokers",
273 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
274 )
275 .with_column("sink_progress_topic", SqlScalarType::String.nullable(false))
276 .finish(),
277 column_comments: BTreeMap::from_iter([
278 ("id", "The ID of the connection."),
279 (
280 "brokers",
281 "The addresses of the Kafka brokers to connect to.",
282 ),
283 (
284 "sink_progress_topic",
285 "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.",
286 ),
287 ]),
288 is_retained_metrics_object: false,
289 access: vec![PUBLIC_SELECT],
290 ontology: Some(Ontology {
291 entity_name: "kafka_connection",
292 description: "Kafka-specific connection configuration (brokers, progress topic)",
293 links: &const {
294 [OntologyLink {
295 name: "details_of",
296 target: "connection",
297 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
298 }]
299 },
300 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
301 }),
302});
303pub static MZ_KAFKA_SOURCES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
304 name: "mz_kafka_sources",
305 schema: MZ_CATALOG_SCHEMA,
306 oid: oid::TABLE_MZ_KAFKA_SOURCES_OID,
307 desc: RelationDesc::builder()
308 .with_column("id", SqlScalarType::String.nullable(false))
309 .with_column("group_id_prefix", SqlScalarType::String.nullable(false))
310 .with_column("topic", SqlScalarType::String.nullable(false))
311 .finish(),
312 column_comments: BTreeMap::from_iter([
313 (
314 "id",
315 "The ID of the Kafka source. Corresponds to `mz_catalog.mz_sources.id`.",
316 ),
317 (
318 "group_id_prefix",
319 "The value of the `GROUP ID PREFIX` connection option.",
320 ),
321 (
322 "topic",
323 "The name of the Kafka topic the source is reading from.",
324 ),
325 ]),
326 is_retained_metrics_object: false,
327 access: vec![PUBLIC_SELECT],
328 ontology: Some(Ontology {
329 entity_name: "kafka_source",
330 description: "Kafka-specific source configuration (topic, group ID)",
331 links: &const {
332 [OntologyLink {
333 name: "details_of",
334 target: "source",
335 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
336 }]
337 },
338 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
339 }),
340});
341
342pub static MZ_DATABASES: LazyLock<BuiltinMaterializedView> =
343 LazyLock::new(|| BuiltinMaterializedView {
344 name: "mz_databases",
345 schema: MZ_CATALOG_SCHEMA,
346 oid: oid::MV_MZ_DATABASES_OID,
347 desc: RelationDesc::builder()
348 .with_column("id", SqlScalarType::String.nullable(false))
349 .with_column("oid", SqlScalarType::Oid.nullable(false))
350 .with_column("name", SqlScalarType::String.nullable(false))
351 .with_column("owner_id", SqlScalarType::String.nullable(false))
352 .with_column(
353 "privileges",
354 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
355 )
356 .with_key(vec![0])
357 .with_key(vec![1])
358 .finish(),
359 column_comments: BTreeMap::from_iter([
360 ("id", "Materialize's unique ID for the database."),
361 ("oid", "A PostgreSQL-compatible OID for the database."),
362 ("name", "The name of the database."),
363 (
364 "owner_id",
365 "The role ID of the owner of the database. Corresponds to `mz_roles.id`.",
366 ),
367 ("privileges", "The privileges belonging to the database."),
368 ]),
369 sql: "
370IN CLUSTER mz_catalog_server
371WITH (
372 ASSERT NOT NULL id,
373 ASSERT NOT NULL oid,
374 ASSERT NOT NULL name,
375 ASSERT NOT NULL owner_id,
376 ASSERT NOT NULL privileges
377) AS
378SELECT
379 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
380 (data->'value'->>'oid')::oid AS oid,
381 data->'value'->>'name' AS name,
382 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
383 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges
384FROM mz_internal.mz_catalog_raw
385WHERE data->>'kind' = 'Database'",
386 is_retained_metrics_object: false,
387 access: vec![PUBLIC_SELECT],
388 ontology: Some(Ontology {
389 entity_name: "database",
390 description: "A top-level namespace that contains schemas",
391 links: &const {
392 [OntologyLink {
393 name: "owned_by",
394 target: "role",
395 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
396 }]
397 },
398 column_semantic_types: &const {
399 [
400 ("id", SemanticType::DatabaseId),
401 ("oid", SemanticType::OID),
402 ("owner_id", SemanticType::RoleId),
403 ]
404 },
405 }),
406 });
407
408pub static MZ_SCHEMAS: LazyLock<BuiltinMaterializedView> =
409 LazyLock::new(|| BuiltinMaterializedView {
410 name: "mz_schemas",
411 schema: MZ_CATALOG_SCHEMA,
412 oid: oid::MV_MZ_SCHEMAS_OID,
413 desc: RelationDesc::builder()
414 .with_column("id", SqlScalarType::String.nullable(false))
415 .with_column("oid", SqlScalarType::Oid.nullable(false))
416 .with_column("database_id", SqlScalarType::String.nullable(true))
417 .with_column("name", SqlScalarType::String.nullable(false))
418 .with_column("owner_id", SqlScalarType::String.nullable(false))
419 .with_column(
420 "privileges",
421 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
422 )
423 .with_key(vec![0])
424 .with_key(vec![1])
425 .finish(),
426 column_comments: BTreeMap::from_iter([
427 ("id", "Materialize's unique ID for the schema."),
428 ("oid", "A PostgreSQL-compatible oid for the schema."),
429 (
430 "database_id",
431 "The ID of the database containing the schema. Corresponds to `mz_databases.id`.",
432 ),
433 ("name", "The name of the schema."),
434 (
435 "owner_id",
436 "The role ID of the owner of the schema. Corresponds to `mz_roles.id`.",
437 ),
438 ("privileges", "The privileges belonging to the schema."),
439 ]),
440 sql: "
441IN CLUSTER mz_catalog_server
442WITH (
443 ASSERT NOT NULL id,
444 ASSERT NOT NULL oid,
445 ASSERT NOT NULL name,
446 ASSERT NOT NULL owner_id,
447 ASSERT NOT NULL privileges
448) AS
449SELECT
450 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
451 (data->'value'->>'oid')::oid AS oid,
452 CASE WHEN data->'value'->'database_id' != 'null'
453 THEN mz_internal.parse_catalog_id(data->'value'->'database_id')
454 END AS database_id,
455 data->'value'->>'name' AS name,
456 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
457 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges
458FROM mz_internal.mz_catalog_raw
459WHERE data->>'kind' = 'Schema'",
460 is_retained_metrics_object: false,
461 access: vec![PUBLIC_SELECT],
462 ontology: Some(Ontology {
463 entity_name: "schema",
464 description: "A namespace within a database that contains objects",
465 links: &const {
466 [
467 OntologyLink {
468 name: "in_database",
469 target: "database",
470 properties: LinkProperties::fk_nullable(
471 "database_id",
472 "id",
473 Cardinality::ManyToOne,
474 ),
475 },
476 OntologyLink {
477 name: "owned_by",
478 target: "role",
479 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
480 },
481 ]
482 },
483 column_semantic_types: &const {
484 [
485 ("id", SemanticType::SchemaId),
486 ("oid", SemanticType::OID),
487 ("database_id", SemanticType::DatabaseId),
488 ("owner_id", SemanticType::RoleId),
489 ]
490 },
491 }),
492 });
493
494pub static MZ_COLUMNS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
495 name: "mz_columns",
496 schema: MZ_CATALOG_SCHEMA,
497 oid: oid::TABLE_MZ_COLUMNS_OID,
498 desc: RelationDesc::builder()
499 .with_column("id", SqlScalarType::String.nullable(false)) .with_column("name", SqlScalarType::String.nullable(false))
501 .with_column("position", SqlScalarType::UInt64.nullable(false))
502 .with_column("nullable", SqlScalarType::Bool.nullable(false))
503 .with_column("type", SqlScalarType::String.nullable(false))
504 .with_column("default", SqlScalarType::String.nullable(true))
505 .with_column("type_oid", SqlScalarType::Oid.nullable(false))
506 .with_column("type_mod", SqlScalarType::Int32.nullable(false))
507 .finish(),
508 column_comments: BTreeMap::from_iter([
509 (
510 "id",
511 "The unique ID of the table, source, or view containing the column.",
512 ),
513 ("name", "The name of the column."),
514 (
515 "position",
516 "The 1-indexed position of the column in its containing table, source, or view.",
517 ),
518 ("nullable", "Can the column contain a `NULL` value?"),
519 ("type", "The data type of the column."),
520 ("default", "The default expression of the column."),
521 (
522 "type_oid",
523 "The OID of the type of the column (references `mz_types`).",
524 ),
525 ("type_mod", "The packed type identifier of the column."),
526 ]),
527 is_retained_metrics_object: false,
528 access: vec![PUBLIC_SELECT],
529 ontology: Some(Ontology {
530 entity_name: "column",
531 description: "A column of a relation, with its name, position, type, and nullability",
532 links: &const {
533 [OntologyLink {
534 name: "belongs_to_relation",
535 target: "object",
536 properties: LinkProperties::ForeignKey {
537 source_column: "id",
538 target_column: "id",
539 cardinality: Cardinality::ManyToOne,
540 source_id_type: None,
541 requires_mapping: None,
542 nullable: false,
543 note: Some("id in mz_columns is the relation ID, not a unique column ID"),
544 extra_key_columns: None,
545 },
546 }]
547 },
548 column_semantic_types: &const {
549 [
550 ("id", SemanticType::CatalogItemId),
551 ("type_oid", SemanticType::OID),
552 ]
553 },
554 }),
555});
556fn assert_safe_builtin_name(name: &str, kind: &str) {
563 assert!(
564 !name.contains('\'') && !name.contains('"') && !name.contains('\\'),
565 "builtin {kind} name {name:?} contains an unsupported character; \
566 mz_indexes reconstructs SQL via string concatenation and assumes \
567 names contain no quotes or backslashes"
568 );
569}
570
571const USER_INDEXES_CTE: &str = "\
574 user_indexes AS (
575 SELECT
576 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
577 (data->'value'->>'oid')::oid AS oid,
578 data->'value'->>'name' AS name,
579 parsed->>'on_id' AS on_id,
580 parsed->>'cluster_id' AS cluster_id,
581 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
582 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
583 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
584 FROM
585 mz_internal.mz_catalog_raw
586 CROSS JOIN LATERAL (
587 SELECT mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')
588 ) AS l(parsed)
589 WHERE
590 data->>'kind' = 'Item' AND
591 parsed->>'type' = 'index'
592 )";
593
594const CATALOG_SERVER_CLUSTER_CTE: &str = "\
597 catalog_server_cluster AS (
598 SELECT mz_internal.parse_catalog_id(data->'key'->'id') AS id
599 FROM mz_internal.mz_catalog_raw
600 WHERE data->>'kind' = 'Cluster' AND data->'value'->>'name' = 'mz_catalog_server'
601 )";
602
603const GID_MAPPING_CTES: &str = "\
606 builtin_index_gid_mappings AS (
607 SELECT
608 's' || (data->'value'->>'catalog_id') AS id,
609 data->'key'->>'object_name' AS name
610 FROM mz_internal.mz_catalog_raw
611 WHERE
612 data->>'kind' = 'GidMapping' AND
613 data->'key'->>'object_type' = '6'
614 ),
615 on_gid_mappings AS (
616 SELECT
617 's' || (data->'value'->>'catalog_id') AS id,
618 data->'key'->>'schema_name' AS schema_name,
619 data->'key'->>'object_name' AS object_name
620 FROM mz_internal.mz_catalog_raw
621 WHERE data->>'kind' = 'GidMapping'
622 )";
623
624pub(super) fn make_mz_indexes(
635 builtin_index_iter: impl Iterator<Item = &'static BuiltinIndex>,
636 builtin_log_iter: impl Iterator<Item = &'static BuiltinLog>,
637) -> BuiltinMaterializedView {
638 let builtin_index_values = builtin_index_iter
639 .map(|index| {
640 assert_safe_builtin_name(index.name, "index");
641 let create_sql_str = index.create_sql();
642 let stmt = mz_sql::parse::parse(&create_sql_str)
643 .unwrap_or_else(|e| panic!("invalid sql for builtin index {}: {e}", index.name))
644 .into_element()
645 .ast;
646 let Statement::CreateIndex(idx_stmt) = stmt else {
647 panic!("expected CreateIndex for builtin index {}", index.name);
648 };
649 let mz_sql::ast::RawItemName::Name(on_name) = idx_stmt.on_name else {
650 panic!("expected Name for on_name in builtin index {}", index.name);
651 };
652 assert_eq!(
653 on_name.0.len(),
654 2,
655 "expected schema.name format for on_name in builtin index {}",
656 index.name
657 );
658 let on_schema = on_name.0[0].as_str();
659 let on_name_str = on_name.0[1].as_str();
660 assert_safe_builtin_name(on_schema, "index `on` schema");
661 assert_safe_builtin_name(on_name_str, "index `on` object");
662 let key_exprs = idx_stmt
663 .key_parts
664 .unwrap_or_else(|| {
665 panic!("builtin index {} must have explicit key parts", index.name)
666 })
667 .iter()
668 .map(|e| e.to_ast_string_stable())
669 .join(", ");
670 let key_exprs_escaped = escaped_string_literal(&key_exprs);
675 format!(
676 "({}::oid, '{}', '{}', '{}', {key_exprs_escaped})",
677 index.oid, index.name, on_schema, on_name_str
678 )
679 })
680 .join(",");
681
682 let log_col_values = builtin_log_iter
683 .map(|log| {
684 assert_safe_builtin_name(log.name, "log");
685 let desc = log.variant.desc();
686 let index_by = log.variant.index_by();
687 let col_list = index_by
688 .iter()
689 .map(|&i| match desc.get_unambiguous_name(i) {
690 Some(name) => {
691 assert_safe_builtin_name(name, "log column");
692 format!("\"{}\"", name)
693 }
694 None => (i + 1).to_string(),
695 })
696 .join(", ");
697 format!("('{}', '{}')", log.name, col_list)
698 })
699 .join(",");
700
701 let builtin_indexes_cte = format!("\
705 builtin_indexes AS (
706 SELECT *, mz_internal.redact_sql(create_sql) AS redacted_create_sql
707 FROM (
708 SELECT
709 bigm.id AS id,
710 biv.oid AS oid,
711 biv.name AS name,
712 om.id AS on_id,
713 csc.id AS cluster_id,
714 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
715 'CREATE INDEX \"' || biv.name || '\" IN CLUSTER [' || csc.id || '] ON [' || om.id || ' AS \"' || biv.on_schema || '\".\"' || biv.on_name || '\"] (' || biv.key_exprs || ')' AS create_sql
716 FROM (VALUES {builtin_index_values}) AS biv(oid, name, on_schema, on_name, key_exprs)
717 JOIN builtin_index_gid_mappings bigm ON bigm.name = biv.name
718 JOIN on_gid_mappings om ON om.schema_name = biv.on_schema AND om.object_name = biv.on_name
719 CROSS JOIN catalog_server_cluster csc
720 ) AS t
721 )");
722
723 let introspection_source_indexes_cte = format!("\
724 introspection_source_indexes AS (
725 SELECT *, mz_internal.redact_sql(create_sql) AS redacted_create_sql
726 FROM (
727 SELECT
728 'si' || (isi.data->'value'->>'catalog_id') AS id,
729 (isi.data->'value'->>'oid')::oid AS oid,
730 idx_name || '_' || cluster_id || '_primary_idx' AS name,
731 's' || (gm.data->'value'->>'catalog_id') AS on_id,
732 cluster_id,
733 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
734 'CREATE INDEX \"' || idx_name || '_' || cluster_id || '_primary_idx\" IN CLUSTER [' || cluster_id || '] ON \"mz_introspection\".\"' || idx_name || '\" (' || lc.col_list || ')' AS create_sql
735 FROM mz_internal.mz_catalog_raw AS isi
736 CROSS JOIN LATERAL (
737 SELECT isi.data->'key'->>'name', mz_internal.parse_catalog_id(isi.data->'key'->'cluster_id')
738 ) AS l(idx_name, cluster_id)
739 JOIN mz_internal.mz_catalog_raw AS gm ON
740 gm.data->>'kind' = 'GidMapping' AND
741 gm.data->'key'->>'object_type' = '2' AND
742 gm.data->'key'->>'schema_name' = 'mz_introspection' AND
743 gm.data->'key'->>'object_name' = idx_name
744 JOIN (VALUES {log_col_values}) AS lc(log_name, col_list) ON lc.log_name = idx_name
745 WHERE isi.data->>'kind' = 'ClusterIntrospectionSourceIndex'
746 ) AS t
747 )");
748
749 let sql = format!(
750 "
751IN CLUSTER mz_catalog_server
752WITH (
753 ASSERT NOT NULL id,
754 ASSERT NOT NULL oid,
755 ASSERT NOT NULL name,
756 ASSERT NOT NULL on_id,
757 ASSERT NOT NULL cluster_id,
758 ASSERT NOT NULL owner_id,
759 ASSERT NOT NULL create_sql,
760 ASSERT NOT NULL redacted_create_sql
761) AS
762WITH
763{USER_INDEXES_CTE},
764{CATALOG_SERVER_CLUSTER_CTE},
765{GID_MAPPING_CTES},
766{builtin_indexes_cte},
767{introspection_source_indexes_cte}
768SELECT * FROM user_indexes
769UNION ALL
770SELECT * FROM builtin_indexes
771UNION ALL
772SELECT * FROM introspection_source_indexes
773"
774 );
775
776 BuiltinMaterializedView {
777 name: "mz_indexes",
778 schema: MZ_CATALOG_SCHEMA,
779 oid: oid::MV_MZ_INDEXES_OID,
780 desc: RelationDesc::builder()
781 .with_column("id", SqlScalarType::String.nullable(false))
782 .with_column("oid", SqlScalarType::Oid.nullable(false))
783 .with_column("name", SqlScalarType::String.nullable(false))
784 .with_column("on_id", SqlScalarType::String.nullable(false))
785 .with_column("cluster_id", SqlScalarType::String.nullable(false))
786 .with_column("owner_id", SqlScalarType::String.nullable(false))
787 .with_column("create_sql", SqlScalarType::String.nullable(false))
788 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
789 .with_key(vec![0])
790 .with_key(vec![1])
791 .finish(),
792 column_comments: BTreeMap::from_iter([
793 ("id", "Materialize's unique ID for the index."),
794 ("oid", "A PostgreSQL-compatible OID for the index."),
795 ("name", "The name of the index."),
796 (
797 "on_id",
798 "The ID of the relation on which the index is built.",
799 ),
800 (
801 "cluster_id",
802 "The ID of the cluster in which the index is built.",
803 ),
804 (
805 "owner_id",
806 "The role ID of the owner of the index. Corresponds to `mz_roles.id`.",
807 ),
808 ("create_sql", "The `CREATE` SQL statement for the index."),
809 (
810 "redacted_create_sql",
811 "The redacted `CREATE` SQL statement for the index.",
812 ),
813 ]),
814 sql: Box::leak(sql.into_boxed_str()),
815 is_retained_metrics_object: false,
816 access: vec![PUBLIC_SELECT],
817 ontology: Some(Ontology {
818 entity_name: "index",
819 description: "An in-memory index on a relation for fast lookups",
820 links: &const {
821 [
822 OntologyLink {
823 name: "owned_by",
824 target: "role",
825 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
826 },
827 OntologyLink {
828 name: "runs_on_cluster",
829 target: "cluster",
830 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
831 },
832 OntologyLink {
833 name: "indexes_relation",
834 target: "relation",
835 properties: LinkProperties::fk("on_id", "id", Cardinality::ManyToOne),
836 },
837 ]
838 },
839 column_semantic_types: &const {
840 [
841 ("id", SemanticType::CatalogItemId),
842 ("oid", SemanticType::OID),
843 ("on_id", SemanticType::CatalogItemId),
844 ("cluster_id", SemanticType::ClusterId),
845 ("owner_id", SemanticType::RoleId),
846 ("create_sql", SemanticType::SqlDefinition),
847 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
848 ]
849 },
850 }),
851 }
852}
853pub static MZ_INDEX_COLUMNS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
854 name: "mz_index_columns",
855 schema: MZ_CATALOG_SCHEMA,
856 oid: oid::TABLE_MZ_INDEX_COLUMNS_OID,
857 desc: RelationDesc::builder()
858 .with_column("index_id", SqlScalarType::String.nullable(false))
859 .with_column("index_position", SqlScalarType::UInt64.nullable(false))
860 .with_column("on_position", SqlScalarType::UInt64.nullable(true))
861 .with_column("on_expression", SqlScalarType::String.nullable(true))
862 .with_column("nullable", SqlScalarType::Bool.nullable(false))
863 .finish(),
864 column_comments: BTreeMap::from_iter([
865 (
866 "index_id",
867 "The ID of the index which contains this column. Corresponds to `mz_indexes.id`.",
868 ),
869 (
870 "index_position",
871 "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.)",
872 ),
873 (
874 "on_position",
875 "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.",
876 ),
877 (
878 "on_expression",
879 "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.",
880 ),
881 (
882 "nullable",
883 "Can this column of the index evaluate to `NULL`?",
884 ),
885 ]),
886 is_retained_metrics_object: false,
887 access: vec![PUBLIC_SELECT],
888 ontology: Some(Ontology {
889 entity_name: "index_column",
890 description: "A column or expression in an index, with its position",
891 links: &const {
892 [OntologyLink {
893 name: "belongs_to_index",
894 target: "index",
895 properties: LinkProperties::fk("index_id", "id", Cardinality::ManyToOne),
896 }]
897 },
898 column_semantic_types: &[("index_id", SemanticType::CatalogItemId)],
899 }),
900});
901pub static MZ_TABLES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
902 name: "mz_tables",
903 schema: MZ_CATALOG_SCHEMA,
904 oid: oid::TABLE_MZ_TABLES_OID,
905 desc: RelationDesc::builder()
906 .with_column("id", SqlScalarType::String.nullable(false))
907 .with_column("oid", SqlScalarType::Oid.nullable(false))
908 .with_column("schema_id", SqlScalarType::String.nullable(false))
909 .with_column("name", SqlScalarType::String.nullable(false))
910 .with_column("owner_id", SqlScalarType::String.nullable(false))
911 .with_column(
912 "privileges",
913 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
914 )
915 .with_column("create_sql", SqlScalarType::String.nullable(true))
916 .with_column("redacted_create_sql", SqlScalarType::String.nullable(true))
917 .with_column("source_id", SqlScalarType::String.nullable(true))
918 .with_key(vec![0])
919 .with_key(vec![1])
920 .finish(),
921 column_comments: BTreeMap::from_iter([
922 ("id", "Materialize's unique ID for the table."),
923 ("oid", "A PostgreSQL-compatible OID for the table."),
924 (
925 "schema_id",
926 "The ID of the schema to which the table belongs. Corresponds to `mz_schemas.id`.",
927 ),
928 ("name", "The name of the table."),
929 (
930 "owner_id",
931 "The role ID of the owner of the table. Corresponds to `mz_roles.id`.",
932 ),
933 ("privileges", "The privileges belonging to the table."),
934 ("create_sql", "The `CREATE` SQL statement for the table."),
935 (
936 "redacted_create_sql",
937 "The redacted `CREATE` SQL statement for the table.",
938 ),
939 (
940 "source_id",
941 "The ID of the source associated with the table, if any. Corresponds to `mz_sources.id`.",
942 ),
943 ]),
944 is_retained_metrics_object: true,
945 access: vec![PUBLIC_SELECT],
946 ontology: Some(Ontology {
947 entity_name: "table",
948 description: "A user-writable table that can be inserted into and updated",
949 links: &const {
950 [
951 OntologyLink {
952 name: "in_schema",
953 target: "schema",
954 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
955 },
956 OntologyLink {
957 name: "owned_by",
958 target: "role",
959 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
960 },
961 OntologyLink {
962 name: "created_by_source",
963 target: "source",
964 properties: LinkProperties::fk_nullable(
965 "source_id",
966 "id",
967 Cardinality::ManyToOne,
968 ),
969 },
970 ]
971 },
972 column_semantic_types: &const {
973 [
974 ("id", SemanticType::CatalogItemId),
975 ("oid", SemanticType::OID),
976 ("schema_id", SemanticType::SchemaId),
977 ("owner_id", SemanticType::RoleId),
978 ("create_sql", SemanticType::SqlDefinition),
979 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
980 ("source_id", SemanticType::CatalogItemId),
981 ]
982 },
983 }),
984});
985
986pub static MZ_CONNECTIONS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
987 BuiltinMaterializedView {
988 name: "mz_connections",
989 schema: MZ_CATALOG_SCHEMA,
990 oid: oid::MV_MZ_CONNECTIONS_OID,
991 desc: RelationDesc::builder()
992 .with_column("id", SqlScalarType::String.nullable(false))
993 .with_column("oid", SqlScalarType::Oid.nullable(false))
994 .with_column("schema_id", SqlScalarType::String.nullable(false))
995 .with_column("name", SqlScalarType::String.nullable(false))
996 .with_column("type", SqlScalarType::String.nullable(false))
997 .with_column("owner_id", SqlScalarType::String.nullable(false))
998 .with_column(
999 "privileges",
1000 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1001 )
1002 .with_column("create_sql", SqlScalarType::String.nullable(false))
1003 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
1004 .with_key(vec![0])
1005 .with_key(vec![1])
1006 .finish(),
1007 column_comments: BTreeMap::from_iter([
1008 ("id", "The unique ID of the connection."),
1009 ("oid", "A PostgreSQL-compatible OID for the connection."),
1010 (
1011 "schema_id",
1012 "The ID of the schema to which the connection belongs. Corresponds to `mz_schemas.id`.",
1013 ),
1014 ("name", "The name of the connection."),
1015 (
1016 "type",
1017 "The type of the connection: `confluent-schema-registry`, `kafka`, `postgres`, or `ssh-tunnel`.",
1018 ),
1019 (
1020 "owner_id",
1021 "The role ID of the owner of the connection. Corresponds to `mz_roles.id`.",
1022 ),
1023 ("privileges", "The privileges belonging to the connection."),
1024 (
1025 "create_sql",
1026 "The `CREATE` SQL statement for the connection.",
1027 ),
1028 (
1029 "redacted_create_sql",
1030 "The redacted `CREATE` SQL statement for the connection.",
1031 ),
1032 ]),
1033 sql: "
1034IN CLUSTER mz_catalog_server
1035WITH (
1036 ASSERT NOT NULL id,
1037 ASSERT NOT NULL oid,
1038 ASSERT NOT NULL schema_id,
1039 ASSERT NOT NULL name,
1040 ASSERT NOT NULL type,
1041 ASSERT NOT NULL owner_id,
1042 ASSERT NOT NULL privileges,
1043 ASSERT NOT NULL create_sql,
1044 ASSERT NOT NULL redacted_create_sql
1045) AS
1046SELECT
1047 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
1048 (data->'value'->>'oid')::oid AS oid,
1049 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
1050 data->'value'->>'name' AS name,
1051 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'connection_type' AS type,
1052 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
1053 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
1054 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
1055 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
1056FROM mz_internal.mz_catalog_raw
1057WHERE
1058 data->>'kind' = 'Item' AND
1059 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'type' = 'connection'",
1060 is_retained_metrics_object: false,
1061 access: vec![PUBLIC_SELECT],
1062 ontology: Some(Ontology {
1063 entity_name: "connection",
1064 description: "A reusable connection configuration to an external system",
1065 links: &const { [
1066 OntologyLink {
1067 name: "in_schema",
1068 target: "schema",
1069 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1070 },
1071 OntologyLink {
1072 name: "owned_by",
1073 target: "role",
1074 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1075 },
1076 ] },
1077 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)]},
1078 }),
1079 }
1080});
1081
1082pub static MZ_SSH_TUNNEL_CONNECTIONS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1083 name: "mz_ssh_tunnel_connections",
1084 schema: MZ_CATALOG_SCHEMA,
1085 oid: oid::TABLE_MZ_SSH_TUNNEL_CONNECTIONS_OID,
1086 desc: RelationDesc::builder()
1087 .with_column("id", SqlScalarType::String.nullable(false))
1088 .with_column("public_key_1", SqlScalarType::String.nullable(false))
1089 .with_column("public_key_2", SqlScalarType::String.nullable(false))
1090 .finish(),
1091 column_comments: BTreeMap::from_iter([
1092 ("id", "The ID of the connection."),
1093 (
1094 "public_key_1",
1095 "The first public key associated with the SSH tunnel.",
1096 ),
1097 (
1098 "public_key_2",
1099 "The second public key associated with the SSH tunnel.",
1100 ),
1101 ]),
1102 is_retained_metrics_object: false,
1103 access: vec![PUBLIC_SELECT],
1104 ontology: Some(Ontology {
1105 entity_name: "ssh_tunnel_connection",
1106 description: "SSH tunnel connection with public keys",
1107 links: &const {
1108 [OntologyLink {
1109 name: "details_of",
1110 target: "connection",
1111 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
1112 }]
1113 },
1114 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
1115 }),
1116});
1117pub static MZ_SINKS: LazyLock<BuiltinTable> = LazyLock::new(|| {
1120 BuiltinTable {
1121 name: "mz_sinks",
1122 schema: MZ_CATALOG_SCHEMA,
1123 oid: oid::TABLE_MZ_SINKS_OID,
1124 desc: RelationDesc::builder()
1125 .with_column("id", SqlScalarType::String.nullable(false))
1126 .with_column("oid", SqlScalarType::Oid.nullable(false))
1127 .with_column("schema_id", SqlScalarType::String.nullable(false))
1128 .with_column("name", SqlScalarType::String.nullable(false))
1129 .with_column("type", SqlScalarType::String.nullable(false))
1130 .with_column("connection_id", SqlScalarType::String.nullable(true))
1131 .with_column("size", SqlScalarType::String.nullable(true))
1132 .with_column("envelope_type", SqlScalarType::String.nullable(true))
1133 .with_column("format", SqlScalarType::String.nullable(true))
1136 .with_column("key_format", SqlScalarType::String.nullable(true))
1137 .with_column("value_format", SqlScalarType::String.nullable(true))
1138 .with_column("cluster_id", SqlScalarType::String.nullable(false))
1139 .with_column("owner_id", SqlScalarType::String.nullable(false))
1140 .with_column("create_sql", SqlScalarType::String.nullable(false))
1141 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
1142 .with_key(vec![0])
1143 .with_key(vec![1])
1144 .finish(),
1145 column_comments: BTreeMap::from_iter([
1146 ("id", "Materialize's unique ID for the sink."),
1147 ("oid", "A PostgreSQL-compatible OID for the sink."),
1148 (
1149 "schema_id",
1150 "The ID of the schema to which the sink belongs. Corresponds to `mz_schemas.id`.",
1151 ),
1152 ("name", "The name of the sink."),
1153 ("type", "The type of the sink: `kafka`."),
1154 (
1155 "connection_id",
1156 "The ID of the connection associated with the sink, if any. Corresponds to `mz_connections.id`.",
1157 ),
1158 ("size", "The size of the sink."),
1159 (
1160 "envelope_type",
1161 "The envelope of the sink: `upsert`, or `debezium`.",
1162 ),
1163 (
1164 "format",
1165 "*Deprecated* The format of the Kafka messages produced by the sink: `avro`, `json`, `text`, or `bytes`.",
1166 ),
1167 (
1168 "key_format",
1169 "The format of the Kafka message key for messages produced by the sink: `avro`, `json`, `bytes`, `text`, or `NULL`.",
1170 ),
1171 (
1172 "value_format",
1173 "The format of the Kafka message value for messages produced by the sink: `avro`, `json`, `text`, or `bytes`.",
1174 ),
1175 (
1176 "cluster_id",
1177 "The ID of the cluster maintaining the sink. Corresponds to `mz_clusters.id`.",
1178 ),
1179 (
1180 "owner_id",
1181 "The role ID of the owner of the sink. Corresponds to `mz_roles.id`.",
1182 ),
1183 ("create_sql", "The `CREATE` SQL statement for the sink."),
1184 (
1185 "redacted_create_sql",
1186 "The redacted `CREATE` SQL statement for the sink.",
1187 ),
1188 ]),
1189 is_retained_metrics_object: true,
1190 access: vec![PUBLIC_SELECT],
1191 ontology: Some(Ontology {
1192 entity_name: "sink",
1193 description: "An export of data from Materialize to an external system",
1194 links: &const {
1195 [
1196 OntologyLink {
1197 name: "in_schema",
1198 target: "schema",
1199 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1200 },
1201 OntologyLink {
1202 name: "owned_by",
1203 target: "role",
1204 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1205 },
1206 OntologyLink {
1207 name: "runs_on_cluster",
1208 target: "cluster",
1209 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
1210 },
1211 OntologyLink {
1212 name: "uses_connection",
1213 target: "connection",
1214 properties: LinkProperties::fk_nullable(
1215 "connection_id",
1216 "id",
1217 Cardinality::ManyToOne,
1218 ),
1219 },
1220 ]
1221 },
1222 column_semantic_types: &const {
1223 [
1224 ("id", SemanticType::CatalogItemId),
1225 ("oid", SemanticType::OID),
1226 ("schema_id", SemanticType::SchemaId),
1227 ("connection_id", SemanticType::CatalogItemId),
1228 ("cluster_id", SemanticType::ClusterId),
1229 ("owner_id", SemanticType::RoleId),
1230 ("create_sql", SemanticType::SqlDefinition),
1231 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
1232 ]
1233 },
1234 }),
1235 }
1236});
1237pub static MZ_VIEWS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1238 name: "mz_views",
1239 schema: MZ_CATALOG_SCHEMA,
1240 oid: oid::TABLE_MZ_VIEWS_OID,
1241 desc: RelationDesc::builder()
1242 .with_column("id", SqlScalarType::String.nullable(false))
1243 .with_column("oid", SqlScalarType::Oid.nullable(false))
1244 .with_column("schema_id", SqlScalarType::String.nullable(false))
1245 .with_column("name", SqlScalarType::String.nullable(false))
1246 .with_column("definition", SqlScalarType::String.nullable(false))
1247 .with_column("owner_id", SqlScalarType::String.nullable(false))
1248 .with_column(
1249 "privileges",
1250 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1251 )
1252 .with_column("create_sql", SqlScalarType::String.nullable(false))
1253 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
1254 .with_key(vec![0])
1255 .with_key(vec![1])
1256 .finish(),
1257 column_comments: BTreeMap::from_iter([
1258 ("id", "Materialize's unique ID for the view."),
1259 ("oid", "A PostgreSQL-compatible OID for the view."),
1260 (
1261 "schema_id",
1262 "The ID of the schema to which the view belongs. Corresponds to `mz_schemas.id`.",
1263 ),
1264 ("name", "The name of the view."),
1265 ("definition", "The view definition (a `SELECT` query)."),
1266 (
1267 "owner_id",
1268 "The role ID of the owner of the view. Corresponds to `mz_roles.id`.",
1269 ),
1270 ("privileges", "The privileges belonging to the view."),
1271 ("create_sql", "The `CREATE` SQL statement for the view."),
1272 (
1273 "redacted_create_sql",
1274 "The redacted `CREATE` SQL statement for the view.",
1275 ),
1276 ]),
1277 is_retained_metrics_object: false,
1278 access: vec![PUBLIC_SELECT],
1279 ontology: Some(Ontology {
1280 entity_name: "view",
1281 description: "A non-materialized view defined by a SQL query",
1282 links: &const {
1283 [
1284 OntologyLink {
1285 name: "in_schema",
1286 target: "schema",
1287 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1288 },
1289 OntologyLink {
1290 name: "owned_by",
1291 target: "role",
1292 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1293 },
1294 ]
1295 },
1296 column_semantic_types: &const {
1297 [
1298 ("id", SemanticType::CatalogItemId),
1299 ("oid", SemanticType::OID),
1300 ("schema_id", SemanticType::SchemaId),
1301 ("definition", SemanticType::SqlDefinition),
1302 ("owner_id", SemanticType::RoleId),
1303 ("create_sql", SemanticType::SqlDefinition),
1304 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
1305 ]
1306 },
1307 }),
1308});
1309
1310pub static MZ_MATERIALIZED_VIEWS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1311 BuiltinMaterializedView {
1312 name: "mz_materialized_views",
1313 schema: MZ_CATALOG_SCHEMA,
1314 oid: oid::MV_MZ_MATERIALIZED_VIEWS_OID,
1315 desc: RelationDesc::builder()
1316 .with_column("id", SqlScalarType::String.nullable(false))
1317 .with_column("oid", SqlScalarType::Oid.nullable(false))
1318 .with_column("schema_id", SqlScalarType::String.nullable(false))
1319 .with_column("name", SqlScalarType::String.nullable(false))
1320 .with_column("cluster_id", SqlScalarType::String.nullable(false))
1321 .with_column("definition", SqlScalarType::String.nullable(false))
1322 .with_column("owner_id", SqlScalarType::String.nullable(false))
1323 .with_column(
1324 "privileges",
1325 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1326 )
1327 .with_column("create_sql", SqlScalarType::String.nullable(false))
1328 .with_column("redacted_create_sql", SqlScalarType::String.nullable(false))
1329 .with_key(vec![0])
1330 .with_key(vec![1])
1331 .finish(),
1332 column_comments: BTreeMap::from_iter([
1333 ("id", "Materialize's unique ID for the materialized view."),
1334 (
1335 "oid",
1336 "A PostgreSQL-compatible OID for the materialized view.",
1337 ),
1338 (
1339 "schema_id",
1340 "The ID of the schema to which the materialized view belongs. Corresponds to `mz_schemas.id`.",
1341 ),
1342 ("name", "The name of the materialized view."),
1343 (
1344 "cluster_id",
1345 "The ID of the cluster maintaining the materialized view. Corresponds to `mz_clusters.id`.",
1346 ),
1347 (
1348 "definition",
1349 "The materialized view definition (a `SELECT` query).",
1350 ),
1351 (
1352 "owner_id",
1353 "The role ID of the owner of the materialized view. Corresponds to `mz_roles.id`.",
1354 ),
1355 (
1356 "privileges",
1357 "The privileges belonging to the materialized view.",
1358 ),
1359 (
1360 "create_sql",
1361 "The `CREATE` SQL statement for the materialized view.",
1362 ),
1363 (
1364 "redacted_create_sql",
1365 "The redacted `CREATE` SQL statement for the materialized view.",
1366 ),
1367 ]),
1368 sql: Box::leak(format!("
1369IN CLUSTER mz_catalog_server
1370WITH (
1371 ASSERT NOT NULL id,
1372 ASSERT NOT NULL oid,
1373 ASSERT NOT NULL schema_id,
1374 ASSERT NOT NULL name,
1375 ASSERT NOT NULL cluster_id,
1376 ASSERT NOT NULL definition,
1377 ASSERT NOT NULL owner_id,
1378 ASSERT NOT NULL privileges,
1379 ASSERT NOT NULL create_sql,
1380 ASSERT NOT NULL redacted_create_sql
1381) AS
1382WITH
1383 user_mvs AS (
1384 SELECT
1385 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
1386 (data->'value'->>'oid')::oid AS oid,
1387 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
1388 data->'value'->>'name' AS name,
1389 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'cluster_id' AS cluster_id,
1390 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'definition' AS definition,
1391 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
1392 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
1393 data->'value'->'definition'->'V1'->>'create_sql' AS create_sql,
1394 mz_internal.redact_sql(data->'value'->'definition'->'V1'->>'create_sql') AS redacted_create_sql
1395 FROM mz_internal.mz_catalog_raw
1396 WHERE
1397 data->>'kind' = 'Item' AND
1398 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'type' = 'materialized-view'
1399 ),
1400 builtin_mappings AS (
1401 SELECT
1402 data->'key'->>'schema_name' AS schema_name,
1403 data->'key'->>'object_name' AS name,
1404 's' || (data->'value'->>'catalog_id') AS id
1405 FROM mz_internal.mz_catalog_raw
1406 WHERE
1407 data->>'kind' = 'GidMapping' AND
1408 data->'key'->>'object_type' = '5'
1409 ),
1410 builtin_mvs AS (
1411 SELECT
1412 m.id,
1413 mv.oid,
1414 s.id AS schema_id,
1415 mv.name,
1416 c.id AS cluster_id,
1417 mv.definition,
1418 '{MZ_SYSTEM_ROLE_ID}' AS owner_id,
1419 mv.privileges,
1420 mv.create_sql,
1421 mz_internal.redact_sql(mv.create_sql) AS redacted_create_sql
1422 FROM mz_internal.mz_builtin_materialized_views mv
1423 JOIN builtin_mappings m USING (schema_name, name)
1424 JOIN mz_schemas s ON s.name = mv.schema_name
1425 JOIN mz_clusters c ON c.name = mv.cluster_name
1426 WHERE s.database_id IS NULL
1427 )
1428SELECT * FROM user_mvs
1429UNION ALL
1430SELECT * FROM builtin_mvs").into_boxed_str()),
1431 is_retained_metrics_object: false,
1432 access: vec![PUBLIC_SELECT],
1433 ontology: Some(Ontology {
1434 entity_name: "mv",
1435 description: "A materialized view maintained incrementally on a cluster",
1436 links: &const { [
1437 OntologyLink { name: "in_schema", target: "schema", properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne) },
1438 OntologyLink { name: "owned_by", target: "role", properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne) },
1439 OntologyLink { name: "runs_on_cluster", target: "cluster", properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne) },
1440 ] },
1441 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)]},
1442 }),
1443 }
1444});
1445pub static MZ_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1446 name: "mz_types",
1447 schema: MZ_CATALOG_SCHEMA,
1448 oid: oid::TABLE_MZ_TYPES_OID,
1449 desc: RelationDesc::builder()
1450 .with_column("id", SqlScalarType::String.nullable(false))
1451 .with_column("oid", SqlScalarType::Oid.nullable(false))
1452 .with_column("schema_id", SqlScalarType::String.nullable(false))
1453 .with_column("name", SqlScalarType::String.nullable(false))
1454 .with_column("category", SqlScalarType::String.nullable(false))
1455 .with_column("owner_id", SqlScalarType::String.nullable(false))
1456 .with_column(
1457 "privileges",
1458 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
1459 )
1460 .with_column("create_sql", SqlScalarType::String.nullable(true))
1461 .with_column("redacted_create_sql", SqlScalarType::String.nullable(true))
1462 .with_key(vec![0])
1463 .with_key(vec![1])
1464 .finish(),
1465 column_comments: BTreeMap::from_iter([
1466 ("id", "Materialize's unique ID for the type."),
1467 ("oid", "A PostgreSQL-compatible OID for the type."),
1468 (
1469 "schema_id",
1470 "The ID of the schema to which the type belongs. Corresponds to `mz_schemas.id`.",
1471 ),
1472 ("name", "The name of the type."),
1473 ("category", "The category of the type."),
1474 (
1475 "owner_id",
1476 "The role ID of the owner of the type. Corresponds to `mz_roles.id`.",
1477 ),
1478 ("privileges", "The privileges belonging to the type."),
1479 ("create_sql", "The `CREATE` SQL statement for the type."),
1480 (
1481 "redacted_create_sql",
1482 "The redacted `CREATE` SQL statement for the type.",
1483 ),
1484 ]),
1485 is_retained_metrics_object: false,
1486 access: vec![PUBLIC_SELECT],
1487 ontology: Some(Ontology {
1488 entity_name: "type",
1489 description: "A named data type (base, array, list, map, or pseudo)",
1490 links: &const {
1491 [
1492 OntologyLink {
1493 name: "in_schema",
1494 target: "schema",
1495 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
1496 },
1497 OntologyLink {
1498 name: "owned_by",
1499 target: "role",
1500 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
1501 },
1502 ]
1503 },
1504 column_semantic_types: &const {
1505 [
1506 ("id", SemanticType::CatalogItemId),
1507 ("oid", SemanticType::OID),
1508 ("schema_id", SemanticType::SchemaId),
1509 ("owner_id", SemanticType::RoleId),
1510 ("create_sql", SemanticType::SqlDefinition),
1511 ("redacted_create_sql", SemanticType::RedactedSqlDefinition),
1512 ]
1513 },
1514 }),
1515});
1516pub static MZ_ARRAY_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1517 name: "mz_array_types",
1518 schema: MZ_CATALOG_SCHEMA,
1519 oid: oid::TABLE_MZ_ARRAY_TYPES_OID,
1520 desc: RelationDesc::builder()
1521 .with_column("id", SqlScalarType::String.nullable(false))
1522 .with_column("element_id", SqlScalarType::String.nullable(false))
1523 .finish(),
1524 column_comments: BTreeMap::from_iter([
1525 ("id", "The ID of the array type."),
1526 ("element_id", "The ID of the array's element type."),
1527 ]),
1528 is_retained_metrics_object: false,
1529 access: vec![PUBLIC_SELECT],
1530 ontology: Some(Ontology {
1531 entity_name: "array_type",
1532 description: "An array type with its element type",
1533 links: &const {
1534 [
1535 OntologyLink {
1536 name: "detail_of",
1537 target: "type",
1538 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
1539 },
1540 OntologyLink {
1541 name: "has_element_type",
1542 target: "type",
1543 properties: LinkProperties::fk("element_id", "id", Cardinality::ManyToOne),
1544 },
1545 ]
1546 },
1547 column_semantic_types: &const {
1548 [
1549 ("id", SemanticType::CatalogItemId),
1550 ("element_id", SemanticType::CatalogItemId),
1551 ]
1552 },
1553 }),
1554});
1555pub static MZ_BASE_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1556 name: "mz_base_types",
1557 schema: MZ_CATALOG_SCHEMA,
1558 oid: oid::TABLE_MZ_BASE_TYPES_OID,
1559 desc: RelationDesc::builder()
1560 .with_column("id", SqlScalarType::String.nullable(false))
1561 .finish(),
1562 column_comments: BTreeMap::from_iter([("id", "The ID of the type.")]),
1563 is_retained_metrics_object: false,
1564 access: vec![PUBLIC_SELECT],
1565 ontology: Some(Ontology {
1566 entity_name: "base_type",
1567 description: "A primitive/base data type",
1568 links: &const { [] },
1569 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
1570 }),
1571});
1572pub static MZ_LIST_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1573 name: "mz_list_types",
1574 schema: MZ_CATALOG_SCHEMA,
1575 oid: oid::TABLE_MZ_LIST_TYPES_OID,
1576 desc: RelationDesc::builder()
1577 .with_column("id", SqlScalarType::String.nullable(false))
1578 .with_column("element_id", SqlScalarType::String.nullable(false))
1579 .with_column(
1580 "element_modifiers",
1581 SqlScalarType::List {
1582 element_type: Box::new(SqlScalarType::Int64),
1583 custom_id: None,
1584 }
1585 .nullable(true),
1586 )
1587 .finish(),
1588 column_comments: BTreeMap::from_iter([
1589 ("id", "The ID of the list type."),
1590 ("element_id", "The IID of the list's element type."),
1591 (
1592 "element_modifiers",
1593 "The element type modifiers, or `NULL` if none.",
1594 ),
1595 ]),
1596 is_retained_metrics_object: false,
1597 access: vec![PUBLIC_SELECT],
1598 ontology: Some(Ontology {
1599 entity_name: "list_type",
1600 description: "A list type with its element type",
1601 links: &const {
1602 [
1603 OntologyLink {
1604 name: "detail_of",
1605 target: "type",
1606 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
1607 },
1608 OntologyLink {
1609 name: "has_element_type",
1610 target: "type",
1611 properties: LinkProperties::fk("element_id", "id", Cardinality::ManyToOne),
1612 },
1613 ]
1614 },
1615 column_semantic_types: &const {
1616 [
1617 ("id", SemanticType::CatalogItemId),
1618 ("element_id", SemanticType::CatalogItemId),
1619 ]
1620 },
1621 }),
1622});
1623pub static MZ_MAP_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1624 name: "mz_map_types",
1625 schema: MZ_CATALOG_SCHEMA,
1626 oid: oid::TABLE_MZ_MAP_TYPES_OID,
1627 desc: RelationDesc::builder()
1628 .with_column("id", SqlScalarType::String.nullable(false))
1629 .with_column("key_id", SqlScalarType::String.nullable(false))
1630 .with_column("value_id", SqlScalarType::String.nullable(false))
1631 .with_column(
1632 "key_modifiers",
1633 SqlScalarType::List {
1634 element_type: Box::new(SqlScalarType::Int64),
1635 custom_id: None,
1636 }
1637 .nullable(true),
1638 )
1639 .with_column(
1640 "value_modifiers",
1641 SqlScalarType::List {
1642 element_type: Box::new(SqlScalarType::Int64),
1643 custom_id: None,
1644 }
1645 .nullable(true),
1646 )
1647 .finish(),
1648 column_comments: BTreeMap::from_iter([
1649 ("id", "The ID of the map type."),
1650 ("key_id", "The ID of the map's key type."),
1651 ("value_id", "The ID of the map's value type."),
1652 (
1653 "key_modifiers",
1654 "The key type modifiers, or `NULL` if none.",
1655 ),
1656 (
1657 "value_modifiers",
1658 "The value type modifiers, or `NULL` if none.",
1659 ),
1660 ]),
1661 is_retained_metrics_object: false,
1662 access: vec![PUBLIC_SELECT],
1663 ontology: Some(Ontology {
1664 entity_name: "map_type",
1665 description: "A map type with its key and value types",
1666 links: &const {
1667 [
1668 OntologyLink {
1669 name: "detail_of",
1670 target: "type",
1671 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
1672 },
1673 OntologyLink {
1674 name: "has_key_type",
1675 target: "type",
1676 properties: LinkProperties::fk("key_id", "id", Cardinality::ManyToOne),
1677 },
1678 OntologyLink {
1679 name: "has_value_type",
1680 target: "type",
1681 properties: LinkProperties::fk("value_id", "id", Cardinality::ManyToOne),
1682 },
1683 ]
1684 },
1685 column_semantic_types: &const {
1686 [
1687 ("id", SemanticType::CatalogItemId),
1688 ("key_id", SemanticType::CatalogItemId),
1689 ("value_id", SemanticType::CatalogItemId),
1690 ]
1691 },
1692 }),
1693});
1694pub static MZ_ROLES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1695 let sql = format!(
1699 "
1700IN CLUSTER mz_catalog_server
1701WITH (
1702 ASSERT NOT NULL id,
1703 ASSERT NOT NULL oid,
1704 ASSERT NOT NULL name,
1705 ASSERT NOT NULL inherit
1706) AS
1707SELECT
1708 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
1709 (data->'value'->>'oid')::oid AS oid,
1710 data->'value'->>'name' AS name,
1711 (data->'value'->'attributes'->>'inherit')::bool AS inherit,
1712 COALESCE(
1713 (data->'value'->'attributes'->>'login')::bool,
1714 data->'value'->>'name' IN ('{system}', '{support}')
1715 ) AS rolcanlogin,
1716 COALESCE(
1717 (data->'value'->'attributes'->>'superuser')::bool,
1718 CASE WHEN data->'value'->>'name' IN ('{system}', '{support}') THEN true END
1719 ) AS rolsuper
1720FROM mz_internal.mz_catalog_raw
1721WHERE data->>'kind' = 'Role' AND data->'key'->'id' != '\"Public\"'::jsonb",
1722 system = SYSTEM_USER_NAME,
1723 support = SUPPORT_USER_NAME,
1724 );
1725
1726 BuiltinMaterializedView {
1727 name: "mz_roles",
1728 schema: MZ_CATALOG_SCHEMA,
1729 oid: oid::MV_MZ_ROLES_OID,
1730 desc: RelationDesc::builder()
1731 .with_column("id", SqlScalarType::String.nullable(false))
1732 .with_column("oid", SqlScalarType::Oid.nullable(false))
1733 .with_column("name", SqlScalarType::String.nullable(false))
1734 .with_column("inherit", SqlScalarType::Bool.nullable(false))
1735 .with_column("rolcanlogin", SqlScalarType::Bool.nullable(true))
1736 .with_column("rolsuper", SqlScalarType::Bool.nullable(true))
1737 .with_key(vec![0])
1738 .with_key(vec![1])
1739 .finish(),
1740 column_comments: BTreeMap::from_iter([
1741 ("id", "Materialize's unique ID for the role."),
1742 ("oid", "A PostgreSQL-compatible OID for the role."),
1743 ("name", "The name of the role."),
1744 (
1745 "inherit",
1746 "Indicates whether the role has inheritance of privileges.",
1747 ),
1748 ("rolcanlogin", "Indicates whether the role can log in."),
1749 ("rolsuper", "Indicates whether the role is a superuser."),
1750 ]),
1751 sql: Box::leak(sql.into_boxed_str()),
1752 is_retained_metrics_object: false,
1753 access: vec![PUBLIC_SELECT],
1754 ontology: Some(Ontology {
1755 entity_name: "role",
1756 description: "A user or role for authentication and access control",
1757 links: &const { [] },
1758 column_semantic_types: &const { [("id", SemanticType::RoleId), ("oid", SemanticType::OID)] },
1759 }),
1760 }
1761});
1762
1763pub static MZ_ROLE_MEMBERS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1764 BuiltinMaterializedView {
1765 name: "mz_role_members",
1766 schema: MZ_CATALOG_SCHEMA,
1767 oid: oid::MV_MZ_ROLE_MEMBERS_OID,
1768 desc: RelationDesc::builder()
1769 .with_column("role_id", SqlScalarType::String.nullable(false))
1770 .with_column("member", SqlScalarType::String.nullable(false))
1771 .with_column("grantor", SqlScalarType::String.nullable(false))
1772 .finish(),
1773 column_comments: BTreeMap::from_iter([
1774 (
1775 "role_id",
1776 "The ID of the role the `member` is a member of. Corresponds to `mz_roles.id`.",
1777 ),
1778 (
1779 "member",
1780 "The ID of the role that is a member of `role_id`. Corresponds to `mz_roles.id`.",
1781 ),
1782 (
1783 "grantor",
1784 "The ID of the role that granted membership of `member` to `role_id`. Corresponds to `mz_roles.id`.",
1785 ),
1786 ]),
1787 sql: "
1788IN CLUSTER mz_catalog_server
1789WITH (
1790 ASSERT NOT NULL role_id,
1791 ASSERT NOT NULL member,
1792 ASSERT NOT NULL grantor
1793) AS
1794SELECT
1795 mz_internal.parse_catalog_id(entry->'key') AS role_id,
1796 mz_internal.parse_catalog_id(data->'key'->'id') AS member,
1797 mz_internal.parse_catalog_id(entry->'value') AS grantor
1798FROM
1799 mz_internal.mz_catalog_raw,
1800 jsonb_array_elements(data->'value'->'membership'->'map') AS entry
1801WHERE data->>'kind' = 'Role'",
1802 is_retained_metrics_object: false,
1803 access: vec![PUBLIC_SELECT],
1804 ontology: Some(Ontology {
1805 entity_name: "role_membership",
1806 description: "A membership grant: one role is a member of another role",
1807 links: &const {
1808 [
1809 OntologyLink {
1810 name: "group_role",
1811 target: "role",
1812 properties: LinkProperties::fk("role_id", "id", Cardinality::ManyToOne),
1813 },
1814 OntologyLink {
1815 name: "member_role",
1816 target: "role",
1817 properties: LinkProperties::fk("member", "id", Cardinality::ManyToOne),
1818 },
1819 OntologyLink {
1820 name: "granted_by",
1821 target: "role",
1822 properties: LinkProperties::fk("grantor", "id", Cardinality::ManyToOne),
1823 },
1824 ]
1825 },
1826 column_semantic_types: &const {
1827 [
1828 ("role_id", SemanticType::RoleId),
1829 ("member", SemanticType::RoleId),
1830 ("grantor", SemanticType::RoleId),
1831 ]
1832 },
1833 }),
1834 }
1835});
1836
1837pub static MZ_ROLE_PARAMETERS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
1838 BuiltinMaterializedView {
1839 name: "mz_role_parameters",
1840 schema: MZ_CATALOG_SCHEMA,
1841 oid: oid::MV_MZ_ROLE_PARAMETERS_OID,
1842 desc: RelationDesc::builder()
1843 .with_column("role_id", SqlScalarType::String.nullable(false))
1844 .with_column("parameter_name", SqlScalarType::String.nullable(false))
1845 .with_column("parameter_value", SqlScalarType::String.nullable(false))
1846 .finish(),
1847 column_comments: BTreeMap::from_iter([
1848 (
1849 "role_id",
1850 "The ID of the role whose configuration parameter default is set. Corresponds to `mz_roles.id`.",
1851 ),
1852 (
1853 "parameter_name",
1854 "The configuration parameter name. One of the supported configuration parameters.",
1855 ),
1856 (
1857 "parameter_value",
1858 "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.",
1859 ),
1860 ]),
1861 sql: "
1862IN CLUSTER mz_catalog_server
1863WITH (
1864 ASSERT NOT NULL role_id,
1865 ASSERT NOT NULL parameter_name,
1866 ASSERT NOT NULL parameter_value
1867) AS
1868SELECT
1869 mz_internal.parse_catalog_id(data->'key'->'id') AS role_id,
1870 entry->>'key' AS parameter_name,
1871 CASE
1872 WHEN entry->'val' ? 'Flat' THEN entry->'val'->>'Flat'
1873 ELSE (
1874 SELECT pg_catalog.string_agg(t.elem, ', ' ORDER BY t.ord)
1875 FROM jsonb_array_elements_text(entry->'val'->'SqlSet')
1876 WITH ORDINALITY AS t(elem, ord)
1877 )
1878 END AS parameter_value
1879FROM
1880 mz_internal.mz_catalog_raw,
1881 jsonb_array_elements(data->'value'->'vars'->'entries') AS entry
1882WHERE data->>'kind' = 'Role'",
1883 is_retained_metrics_object: false,
1884 access: vec![PUBLIC_SELECT],
1885 ontology: Some(Ontology {
1886 entity_name: "role_parameter",
1887 description: "A session parameter default set for a role",
1888 links: &const {
1889 [OntologyLink {
1890 name: "default_parameter_setting_of",
1891 target: "role",
1892 properties: LinkProperties::fk("role_id", "id", Cardinality::ManyToOne),
1893 }]
1894 },
1895 column_semantic_types: &[("role_id", SemanticType::RoleId)],
1896 }),
1897 }
1898});
1899pub static MZ_ROLE_AUTH: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1900 name: "mz_role_auth",
1901 schema: MZ_CATALOG_SCHEMA,
1902 oid: oid::TABLE_MZ_ROLE_AUTH_OID,
1903 desc: RelationDesc::builder()
1904 .with_column("role_id", SqlScalarType::String.nullable(false))
1905 .with_column("role_oid", SqlScalarType::Oid.nullable(false))
1906 .with_column("password_hash", SqlScalarType::String.nullable(true))
1907 .with_column(
1908 "updated_at",
1909 SqlScalarType::TimestampTz { precision: None }.nullable(false),
1910 )
1911 .finish(),
1912 column_comments: BTreeMap::from_iter([
1913 (
1914 "role_id",
1915 "The ID of the role. Corresponds to `mz_roles.id`.",
1916 ),
1917 ("role_oid", "A PostgreSQL-compatible OID for the role."),
1918 (
1919 "password_hash",
1920 "The hashed password for the role, if any. Uses the `SCRAM-SHA-256` algorithm.",
1921 ),
1922 (
1923 "updated_at",
1924 "The time at which the password was last updated.",
1925 ),
1926 ]),
1927 is_retained_metrics_object: false,
1928 access: vec![rbac::owner_privilege(ObjectType::Table, MZ_SYSTEM_ROLE_ID)],
1929 ontology: None,
1930});
1931pub static MZ_PSEUDO_TYPES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
1932 name: "mz_pseudo_types",
1933 schema: MZ_CATALOG_SCHEMA,
1934 oid: oid::TABLE_MZ_PSEUDO_TYPES_OID,
1935 desc: RelationDesc::builder()
1936 .with_column("id", SqlScalarType::String.nullable(false))
1937 .finish(),
1938 column_comments: BTreeMap::from_iter([("id", "The ID of the type.")]),
1939 is_retained_metrics_object: false,
1940 access: vec![PUBLIC_SELECT],
1941 ontology: Some(Ontology {
1942 entity_name: "pseudo_type",
1943 description: "A pseudo-type used in function signatures",
1944 links: &const { [] },
1945 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
1946 }),
1947});
1948pub static MZ_FUNCTIONS: LazyLock<BuiltinTable> = LazyLock::new(|| {
1949 BuiltinTable {
1950 name: "mz_functions",
1951 schema: MZ_CATALOG_SCHEMA,
1952 oid: oid::TABLE_MZ_FUNCTIONS_OID,
1953 desc: RelationDesc::builder()
1954 .with_column("id", SqlScalarType::String.nullable(false)) .with_column("oid", SqlScalarType::Oid.nullable(false))
1956 .with_column("schema_id", SqlScalarType::String.nullable(false))
1957 .with_column("name", SqlScalarType::String.nullable(false))
1958 .with_column(
1959 "argument_type_ids",
1960 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
1961 )
1962 .with_column(
1963 "variadic_argument_type_id",
1964 SqlScalarType::String.nullable(true),
1965 )
1966 .with_column("return_type_id", SqlScalarType::String.nullable(true))
1967 .with_column("returns_set", SqlScalarType::Bool.nullable(false))
1968 .with_column("owner_id", SqlScalarType::String.nullable(false))
1969 .finish(),
1970 column_comments: BTreeMap::from_iter([
1971 ("id", "Materialize's unique ID for the function."),
1972 ("oid", "A PostgreSQL-compatible OID for the function."),
1973 (
1974 "schema_id",
1975 "The ID of the schema to which the function belongs. Corresponds to `mz_schemas.id`.",
1976 ),
1977 ("name", "The name of the function."),
1978 (
1979 "argument_type_ids",
1980 "The ID of each argument's type. Each entry refers to `mz_types.id`.",
1981 ),
1982 (
1983 "variadic_argument_type_id",
1984 "The ID of the variadic argument's type, or `NULL` if the function does not have a variadic argument. Refers to `mz_types.id`.",
1985 ),
1986 (
1987 "return_type_id",
1988 "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`].",
1989 ),
1990 (
1991 "returns_set",
1992 "Whether the function returns a set, i.e. the function is a table function.",
1993 ),
1994 (
1995 "owner_id",
1996 "The role ID of the owner of the function. Corresponds to `mz_roles.id`.",
1997 ),
1998 ]),
1999 is_retained_metrics_object: false,
2000 access: vec![PUBLIC_SELECT],
2001 ontology: Some(Ontology {
2002 entity_name: "function",
2003 description: "A built-in or user-defined function",
2004 links: &const {
2005 [
2006 OntologyLink {
2007 name: "in_schema",
2008 target: "schema",
2009 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
2010 },
2011 OntologyLink {
2012 name: "owned_by",
2013 target: "role",
2014 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
2015 },
2016 OntologyLink {
2017 name: "returns_type",
2018 target: "type",
2019 properties: LinkProperties::fk_nullable(
2020 "return_type_id",
2021 "id",
2022 Cardinality::ManyToOne,
2023 ),
2024 },
2025 OntologyLink {
2026 name: "has_variadic_arg_type",
2027 target: "type",
2028 properties: LinkProperties::fk_nullable(
2029 "variadic_argument_type_id",
2030 "id",
2031 Cardinality::ManyToOne,
2032 ),
2033 },
2034 ]
2035 },
2036 column_semantic_types: &const {
2037 [
2038 ("id", SemanticType::CatalogItemId),
2039 ("oid", SemanticType::OID),
2040 ("schema_id", SemanticType::SchemaId),
2041 ("variadic_argument_type_id", SemanticType::CatalogItemId),
2042 ("return_type_id", SemanticType::CatalogItemId),
2043 ("owner_id", SemanticType::RoleId),
2044 ]
2045 },
2046 }),
2047 }
2048});
2049pub static MZ_OPERATORS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2050 name: "mz_operators",
2051 schema: MZ_CATALOG_SCHEMA,
2052 oid: oid::TABLE_MZ_OPERATORS_OID,
2053 desc: RelationDesc::builder()
2054 .with_column("oid", SqlScalarType::Oid.nullable(false))
2055 .with_column("name", SqlScalarType::String.nullable(false))
2056 .with_column(
2057 "argument_type_ids",
2058 SqlScalarType::Array(Box::new(SqlScalarType::String)).nullable(false),
2059 )
2060 .with_column("return_type_id", SqlScalarType::String.nullable(true))
2061 .finish(),
2062 column_comments: BTreeMap::new(),
2063 is_retained_metrics_object: false,
2064 access: vec![PUBLIC_SELECT],
2065 ontology: Some(Ontology {
2066 entity_name: "operator",
2067 description: "A built-in SQL operator",
2068 links: &const {
2069 [OntologyLink {
2070 name: "returns_type",
2071 target: "type",
2072 properties: LinkProperties::fk_nullable(
2073 "return_type_id",
2074 "id",
2075 Cardinality::ManyToOne,
2076 ),
2077 }]
2078 },
2079 column_semantic_types: &const {
2080 [
2081 ("oid", SemanticType::OID),
2082 ("return_type_id", SemanticType::CatalogItemId),
2083 ]
2084 },
2085 }),
2086});
2087
2088pub static MZ_CLUSTERS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2089 BuiltinMaterializedView {
2090 name: "mz_clusters",
2091 schema: MZ_CATALOG_SCHEMA,
2092 oid: oid::MV_MZ_CLUSTERS_OID,
2093 desc: RelationDesc::builder()
2094 .with_column("id", SqlScalarType::String.nullable(false))
2095 .with_column("name", SqlScalarType::String.nullable(false))
2096 .with_column("owner_id", SqlScalarType::String.nullable(false))
2097 .with_column(
2098 "privileges",
2099 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
2100 )
2101 .with_column("managed", SqlScalarType::Bool.nullable(false))
2102 .with_column("size", SqlScalarType::String.nullable(true))
2103 .with_column("replication_factor", SqlScalarType::UInt32.nullable(true))
2104 .with_column("disk", SqlScalarType::Bool.nullable(true))
2105 .with_column(
2106 "availability_zones",
2107 SqlScalarType::List {
2108 element_type: Box::new(SqlScalarType::String),
2109 custom_id: None,
2110 }
2111 .nullable(true),
2112 )
2113 .with_column(
2114 "introspection_debugging",
2115 SqlScalarType::Bool.nullable(true),
2116 )
2117 .with_column(
2118 "introspection_interval",
2119 SqlScalarType::Interval.nullable(true),
2120 )
2121 .with_key(vec![0])
2122 .finish(),
2123 column_comments: BTreeMap::from_iter([
2124 ("id", "Materialize's unique ID for the cluster."),
2125 ("name", "The name of the cluster."),
2126 (
2127 "owner_id",
2128 "The role ID of the owner of the cluster. Corresponds to `mz_roles.id`.",
2129 ),
2130 ("privileges", "The privileges belonging to the cluster."),
2131 (
2132 "managed",
2133 "Whether the cluster is a managed cluster with automatically managed replicas.",
2134 ),
2135 (
2136 "size",
2137 "If the cluster is managed, the desired size of the cluster's replicas. `NULL` for unmanaged clusters.",
2138 ),
2139 (
2140 "replication_factor",
2141 "If the cluster is managed, the desired number of replicas of the cluster. `NULL` for unmanaged clusters.",
2142 ),
2143 (
2144 "disk",
2145 "**Unstable** If the cluster is managed, `true` if the replicas have the `DISK` option . `NULL` for unmanaged clusters.",
2146 ),
2147 (
2148 "availability_zones",
2149 "**Unstable** If the cluster is managed, the list of availability zones specified in `AVAILABILITY ZONES`. `NULL` for unmanaged clusters.",
2150 ),
2151 (
2152 "introspection_debugging",
2153 "Whether introspection of the gathering of the introspection data is enabled.",
2154 ),
2155 (
2156 "introspection_interval",
2157 "The interval at which to collect introspection data.",
2158 ),
2159 ]),
2160 sql: "
2188IN CLUSTER mz_catalog_server
2189WITH (
2190 ASSERT NOT NULL id,
2191 ASSERT NOT NULL name,
2192 ASSERT NOT NULL owner_id,
2193 ASSERT NOT NULL privileges,
2194 ASSERT NOT NULL managed
2195) AS
2196SELECT
2197 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
2198 data->'value'->>'name' AS name,
2199 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
2200 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges,
2201 jsonb_typeof(data->'value'->'config'->'variant') = 'object' AS managed,
2202 data->'value'->'config'->'variant'->'Managed'->>'size' AS size,
2203 (data->'value'->'config'->'variant'->'Managed'->>'replication_factor')::uint4 AS replication_factor,
2204 CASE
2205 WHEN jsonb_typeof(data->'value'->'config'->'variant') = 'object' THEN
2206 NOT COALESCE(internal.swap_enabled, false)
2207 AND COALESCE(internal.disk_bytes, 0) != 0
2208 END AS disk,
2209 CASE
2210 WHEN jsonb_array_length(data->'value'->'config'->'variant'->'Managed'->'availability_zones') > 0 THEN
2211 (
2212 SELECT mz_catalog.list_agg(az.value ORDER BY az.ord)
2213 FROM jsonb_array_elements_text(data->'value'->'config'->'variant'->'Managed'->'availability_zones')
2214 WITH ORDINALITY AS az(value, ord)
2215 )
2216 END AS availability_zones,
2217 (data->'value'->'config'->'variant'->'Managed'->'logging'->>'log_logging')::bool AS introspection_debugging,
2218 CASE
2219 WHEN data->'value'->'config'->'variant'->'Managed'->'logging'->'interval' != 'null'::jsonb THEN
2220 (
2221 (data->'value'->'config'->'variant'->'Managed'->'logging'->'interval'->>'secs')
2222 || ' seconds '
2223 || ((data->'value'->'config'->'variant'->'Managed'->'logging'->'interval'->>'nanos')::bigint / 1000)::text
2224 || ' microseconds'
2225 )::interval
2226 END AS introspection_interval
2227FROM (
2228 SELECT data FROM mz_internal.mz_catalog_raw WHERE data->>'kind' = 'Cluster'
2229) raw
2230LEFT JOIN mz_internal.mz_cluster_replica_size_internal internal
2231 ON internal.size = data->'value'->'config'->'variant'->'Managed'->>'size'",
2232 is_retained_metrics_object: false,
2233 access: vec![PUBLIC_SELECT],
2234 ontology: Some(Ontology {
2235 entity_name: "cluster",
2236 description: "A compute cluster that runs dataflows for sources, sinks, MVs, and indexes",
2237 links: &const {
2238 [
2239 OntologyLink {
2240 name: "owned_by",
2241 target: "role",
2242 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
2243 },
2244 OntologyLink {
2245 name: "has_size",
2246 target: "replica_size",
2247 properties: LinkProperties::fk_nullable("size", "size", Cardinality::ManyToOne),
2248 },
2249 ]
2250 },
2251 column_semantic_types: &const {
2252 [
2253 ("id", SemanticType::ClusterId),
2254 ("owner_id", SemanticType::RoleId),
2255 ]
2256 },
2257 }),
2258 }
2259});
2260
2261pub static MZ_SECRETS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2262 BuiltinMaterializedView {
2263 name: "mz_secrets",
2264 schema: MZ_CATALOG_SCHEMA,
2265 oid: oid::MV_MZ_SECRETS_OID,
2266 desc: RelationDesc::builder()
2267 .with_column("id", SqlScalarType::String.nullable(false))
2268 .with_column("oid", SqlScalarType::Oid.nullable(false))
2269 .with_column("schema_id", SqlScalarType::String.nullable(false))
2270 .with_column("name", SqlScalarType::String.nullable(false))
2271 .with_column("owner_id", SqlScalarType::String.nullable(false))
2272 .with_column(
2273 "privileges",
2274 SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false),
2275 )
2276 .finish(),
2277 column_comments: BTreeMap::from_iter([
2278 ("id", "The unique ID of the secret."),
2279 ("oid", "A PostgreSQL-compatible oid for the secret."),
2280 (
2281 "schema_id",
2282 "The ID of the schema to which the secret belongs. Corresponds to `mz_schemas.id`.",
2283 ),
2284 ("name", "The name of the secret."),
2285 (
2286 "owner_id",
2287 "The role ID of the owner of the secret. Corresponds to `mz_roles.id`.",
2288 ),
2289 ("privileges", "The privileges belonging to the secret."),
2290 ]),
2291 sql: "
2292IN CLUSTER mz_catalog_server
2293WITH (
2294 ASSERT NOT NULL id,
2295 ASSERT NOT NULL oid,
2296 ASSERT NOT NULL schema_id,
2297 ASSERT NOT NULL name,
2298 ASSERT NOT NULL owner_id,
2299 ASSERT NOT NULL privileges
2300) AS
2301SELECT
2302 mz_internal.parse_catalog_id(data->'key'->'gid') AS id,
2303 (data->'value'->>'oid')::oid AS oid,
2304 mz_internal.parse_catalog_id(data->'value'->'schema_id') AS schema_id,
2305 data->'value'->>'name' AS name,
2306 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
2307 mz_internal.parse_catalog_privileges(data->'value'->'privileges') AS privileges
2308FROM mz_internal.mz_catalog_raw
2309WHERE
2310 data->>'kind' = 'Item' AND
2311 mz_internal.parse_catalog_create_sql(data->'value'->'definition'->'V1'->>'create_sql')->>'type' = 'secret'",
2312 is_retained_metrics_object: false,
2313 access: vec![PUBLIC_SELECT],
2314 ontology: Some(Ontology {
2315 entity_name: "secret",
2316 description: "A user-defined secret containing sensitive configuration (e.g., credentials)",
2317 links: &const { [
2318 OntologyLink {
2319 name: "in_schema",
2320 target: "schema",
2321 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
2322 },
2323 OntologyLink {
2324 name: "owned_by",
2325 target: "role",
2326 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
2327 },
2328 ] },
2329 column_semantic_types: &const {[("id", SemanticType::CatalogItemId), ("oid", SemanticType::OID), ("schema_id", SemanticType::SchemaId), ("owner_id", SemanticType::RoleId)]},
2330 }),
2331 }
2332});
2333
2334pub static MZ_CLUSTER_REPLICAS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2335 BuiltinMaterializedView {
2336 name: "mz_cluster_replicas",
2337 schema: MZ_CATALOG_SCHEMA,
2338 oid: oid::MV_MZ_CLUSTER_REPLICAS_OID,
2339 desc: RelationDesc::builder()
2340 .with_column("id", SqlScalarType::String.nullable(false))
2341 .with_column("name", SqlScalarType::String.nullable(false))
2342 .with_column("cluster_id", SqlScalarType::String.nullable(false))
2343 .with_column("size", SqlScalarType::String.nullable(true))
2344 .with_column("availability_zone", SqlScalarType::String.nullable(true))
2347 .with_column("owner_id", SqlScalarType::String.nullable(false))
2348 .with_column("disk", SqlScalarType::Bool.nullable(true))
2349 .with_key(vec![0])
2350 .finish(),
2351 column_comments: BTreeMap::from_iter([
2352 ("id", "Materialize's unique ID for the cluster replica."),
2353 ("name", "The name of the cluster replica."),
2354 (
2355 "cluster_id",
2356 "The ID of the cluster to which the replica belongs. Corresponds to `mz_clusters.id`.",
2357 ),
2358 (
2359 "size",
2360 "The cluster replica's size, selected during creation.",
2361 ),
2362 (
2363 "availability_zone",
2364 "The availability zones the replica is provisioned in, comma-separated. `NULL` if nothing constrains the replica's placement.",
2365 ),
2366 (
2367 "owner_id",
2368 "The role ID of the owner of the cluster replica. Corresponds to `mz_roles.id`.",
2369 ),
2370 ("disk", "If the replica has a local disk."),
2371 ]),
2372 sql: "
2396IN CLUSTER mz_catalog_server
2397WITH (
2398 ASSERT NOT NULL id,
2399 ASSERT NOT NULL name,
2400 ASSERT NOT NULL cluster_id,
2401 ASSERT NOT NULL owner_id
2402) AS
2403SELECT
2404 mz_internal.parse_catalog_id(data->'key'->'id') AS id,
2405 data->'value'->>'name' AS name,
2406 mz_internal.parse_catalog_id(data->'value'->'cluster_id') AS cluster_id,
2407 data->'value'->'config'->'location'->'Managed'->>'size' AS size,
2408 CASE
2409 WHEN jsonb_array_length(data->'value'->'config'->'location'->'Managed'->'availability_zones') > 0 THEN
2410 (
2411 SELECT pg_catalog.string_agg(az.value, ',' ORDER BY az.ord)
2412 FROM jsonb_array_elements_text(data->'value'->'config'->'location'->'Managed'->'availability_zones')
2413 WITH ORDINALITY AS az(value, ord)
2414 )
2415 END AS availability_zone,
2416 mz_internal.parse_catalog_id(data->'value'->'owner_id') AS owner_id,
2417 CASE
2418 WHEN data->'value'->'config'->'location' ? 'Managed' THEN
2419 NOT COALESCE(internal.swap_enabled, false)
2420 AND COALESCE(internal.disk_bytes, 0) != 0
2421 END AS disk
2422FROM (
2423 SELECT data FROM mz_internal.mz_catalog_raw WHERE data->>'kind' = 'ClusterReplica'
2424) raw
2425LEFT JOIN mz_internal.mz_cluster_replica_size_internal internal
2426 ON internal.size = data->'value'->'config'->'location'->'Managed'->>'size'",
2427 is_retained_metrics_object: true,
2428 access: vec![PUBLIC_SELECT],
2429 ontology: Some(Ontology {
2430 entity_name: "replica",
2431 description: "A physical replica of a cluster providing fault tolerance",
2432 links: &const {
2433 [
2434 OntologyLink {
2435 name: "owned_by",
2436 target: "role",
2437 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
2438 },
2439 OntologyLink {
2440 name: "belongs_to_cluster",
2441 target: "cluster",
2442 properties: LinkProperties::fk("cluster_id", "id", Cardinality::ManyToOne),
2443 },
2444 OntologyLink {
2445 name: "has_size",
2446 target: "replica_size",
2447 properties: LinkProperties::fk_nullable(
2448 "size",
2449 "size",
2450 Cardinality::ManyToOne,
2451 ),
2452 },
2453 ]
2454 },
2455 column_semantic_types: &const {
2456 [
2457 ("id", SemanticType::ReplicaId),
2458 ("cluster_id", SemanticType::ClusterId),
2459 ("owner_id", SemanticType::RoleId),
2460 ]
2461 },
2462 }),
2463 }
2464});
2465
2466pub static MZ_CLUSTER_REPLICA_SIZES: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2467 name: "mz_cluster_replica_sizes",
2468 schema: MZ_CATALOG_SCHEMA,
2469 oid: oid::TABLE_MZ_CLUSTER_REPLICA_SIZES_OID,
2470 desc: RelationDesc::builder()
2471 .with_column("size", SqlScalarType::String.nullable(false))
2472 .with_column("processes", SqlScalarType::UInt64.nullable(false))
2473 .with_column("workers", SqlScalarType::UInt64.nullable(false))
2474 .with_column("cpu_nano_cores", SqlScalarType::UInt64.nullable(false))
2475 .with_column("memory_bytes", SqlScalarType::UInt64.nullable(false))
2476 .with_column("disk_bytes", SqlScalarType::UInt64.nullable(true))
2477 .with_column(
2478 "credits_per_hour",
2479 SqlScalarType::Numeric { max_scale: None }.nullable(false),
2480 )
2481 .finish(),
2482 column_comments: BTreeMap::from_iter([
2483 ("size", "The human-readable replica size."),
2484 ("processes", "The number of processes in the replica."),
2485 (
2486 "workers",
2487 "The number of Timely Dataflow workers per process.",
2488 ),
2489 (
2490 "cpu_nano_cores",
2491 "The CPU allocation per process, in billionths of a vCPU core.",
2492 ),
2493 (
2494 "memory_bytes",
2495 "The RAM allocation per process, in billionths of a vCPU core.",
2496 ),
2497 ("disk_bytes", "The disk allocation per process."),
2498 (
2499 "credits_per_hour",
2500 "The number of compute credits consumed per hour.",
2501 ),
2502 ]),
2503 is_retained_metrics_object: true,
2504 access: vec![PUBLIC_SELECT],
2505 ontology: Some(Ontology {
2506 entity_name: "replica_size",
2507 description: "Available cluster replica sizes with CPU, memory, and credit cost",
2508 links: &const { [] },
2509 column_semantic_types: &const {
2510 [
2511 ("memory_bytes", SemanticType::ByteCount),
2512 ("disk_bytes", SemanticType::ByteCount),
2513 ("credits_per_hour", SemanticType::CreditRate),
2514 ]
2515 },
2516 }),
2517});
2518
2519pub static MZ_AUDIT_EVENTS: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2520 BuiltinMaterializedView {
2521 name: "mz_audit_events",
2522 schema: MZ_CATALOG_SCHEMA,
2523 oid: oid::MV_MZ_AUDIT_EVENTS_OID,
2524 desc: RelationDesc::builder()
2525 .with_column("id", SqlScalarType::UInt64.nullable(false))
2526 .with_column("event_type", SqlScalarType::String.nullable(false))
2527 .with_column("object_type", SqlScalarType::String.nullable(false))
2528 .with_column("details", SqlScalarType::Jsonb.nullable(false))
2529 .with_column("user", SqlScalarType::String.nullable(true))
2530 .with_column(
2531 "occurred_at",
2532 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2533 )
2534 .with_key(vec![0])
2535 .finish(),
2536 column_comments: BTreeMap::from_iter([
2537 (
2538 "id",
2539 "Materialize's unique, monotonically increasing ID for the event.",
2540 ),
2541 (
2542 "event_type",
2543 "The type of the event: `create`, `drop`, `alter`, `grant`, `revoke`, or `comment`.",
2544 ),
2545 (
2546 "object_type",
2547 "The type of the affected object: `cluster`, `cluster-replica`, `connection`, `continual-task`, `database`, `func`, `index`, `materialized-view`, `network-policy`, `role`, `schema`, `secret`, `sink`, `source`, `system`, `table`, `type`, or `view`.",
2548 ),
2549 (
2550 "details",
2551 "Additional details about the event. The shape of the details varies based on `event_type` and `object_type`.",
2552 ),
2553 (
2554 "user",
2555 "The user who triggered the event, or `NULL` if triggered by the system.",
2556 ),
2557 (
2558 "occurred_at",
2559 "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.",
2560 ),
2561 ]),
2562 sql: "
2584IN CLUSTER mz_catalog_server
2585WITH (
2586 ASSERT NOT NULL id,
2587 ASSERT NOT NULL event_type,
2588 ASSERT NOT NULL object_type,
2589 ASSERT NOT NULL details,
2590 ASSERT NOT NULL occurred_at
2591) AS
2592WITH ev AS (
2593 SELECT data->'key'->'event'->'V1' AS e
2594 FROM mz_internal.mz_catalog_raw
2595 WHERE data->>'kind' = 'AuditLog'
2596)
2597SELECT
2598 (e->>'id')::uint8 AS id,
2599 CASE (e->>'event_type')
2600 WHEN '1' THEN 'create'
2601 WHEN '2' THEN 'drop'
2602 WHEN '3' THEN 'alter'
2603 WHEN '4' THEN 'grant'
2604 WHEN '5' THEN 'revoke'
2605 WHEN '6' THEN 'comment'
2606 END AS event_type,
2607 CASE (e->>'object_type')
2608 WHEN '1' THEN 'cluster'
2609 WHEN '2' THEN 'cluster-replica'
2610 WHEN '3' THEN 'connection'
2611 WHEN '4' THEN 'database'
2612 WHEN '5' THEN 'func'
2613 WHEN '6' THEN 'index'
2614 WHEN '7' THEN 'materialized-view'
2615 WHEN '8' THEN 'role'
2616 WHEN '9' THEN 'secret'
2617 WHEN '10' THEN 'schema'
2618 WHEN '11' THEN 'sink'
2619 WHEN '12' THEN 'source'
2620 WHEN '13' THEN 'table'
2621 WHEN '14' THEN 'type'
2622 WHEN '15' THEN 'view'
2623 WHEN '16' THEN 'system'
2624 WHEN '17' THEN 'continual-task'
2625 WHEN '18' THEN 'network-policy'
2626 END AS object_type,
2627 mz_internal.parse_catalog_audit_log_details(e->'details') AS details,
2628 e->'user'->>'inner' AS \"user\",
2629 -- `occurred_at` is serialized by `proto::EpochMillis` as
2630 -- `{\"millis\": <u64>}`; reach through `'millis'` to get the integer.
2631 to_timestamp(((e->'occurred_at'->>'millis')::float8) / 1000.0) AS occurred_at
2632FROM ev",
2633 is_retained_metrics_object: false,
2634 access: vec![PUBLIC_SELECT],
2635 ontology: Some(Ontology {
2636 entity_name: "audit_event",
2637 description: "An audit log entry recording a DDL operation",
2638 links: &const { [] },
2639 column_semantic_types: &const {
2640 [
2641 ("object_type", SemanticType::ObjectType),
2642 ("occurred_at", SemanticType::WallclockTimestamp),
2643 ]
2644 },
2645 }),
2646 }
2647});
2648
2649pub static MZ_EGRESS_IPS: LazyLock<BuiltinTable> = LazyLock::new(|| BuiltinTable {
2650 name: "mz_egress_ips",
2651 schema: MZ_CATALOG_SCHEMA,
2652 oid: oid::TABLE_MZ_EGRESS_IPS_OID,
2653 desc: RelationDesc::builder()
2654 .with_column("egress_ip", SqlScalarType::String.nullable(false))
2655 .with_column("prefix_length", SqlScalarType::Int32.nullable(false))
2656 .with_column("cidr", SqlScalarType::String.nullable(false))
2657 .finish(),
2658 column_comments: BTreeMap::from_iter([
2659 ("egress_ip", "The start of the range of IP addresses."),
2660 (
2661 "prefix_length",
2662 "The number of leading bits in the CIDR netmask.",
2663 ),
2664 ("cidr", "The CIDR representation."),
2665 ]),
2666 is_retained_metrics_object: false,
2667 access: vec![PUBLIC_SELECT],
2668 ontology: Some(Ontology {
2669 entity_name: "egress_ip",
2670 description: "IP addresses used for outbound connections from Materialize",
2671 links: &const { [] },
2672 column_semantic_types: &[],
2673 }),
2674});
2675
2676pub static MZ_AWS_PRIVATELINK_CONNECTIONS: LazyLock<BuiltinTable> =
2677 LazyLock::new(|| BuiltinTable {
2678 name: "mz_aws_privatelink_connections",
2679 schema: MZ_CATALOG_SCHEMA,
2680 oid: oid::TABLE_MZ_AWS_PRIVATELINK_CONNECTIONS_OID,
2681 desc: RelationDesc::builder()
2682 .with_column("id", SqlScalarType::String.nullable(false))
2683 .with_column("principal", SqlScalarType::String.nullable(false))
2684 .finish(),
2685 column_comments: BTreeMap::from_iter([
2686 ("id", "The ID of the connection."),
2687 (
2688 "principal",
2689 "The AWS Principal that Materialize will use to connect to the VPC endpoint.",
2690 ),
2691 ]),
2692 is_retained_metrics_object: false,
2693 access: vec![PUBLIC_SELECT],
2694 ontology: Some(Ontology {
2695 entity_name: "aws_privatelink_connection",
2696 description: "AWS PrivateLink connection configuration",
2697 links: &const {
2698 [OntologyLink {
2699 name: "details_of",
2700 target: "connection",
2701 properties: LinkProperties::fk("id", "id", Cardinality::OneToOne),
2702 }]
2703 },
2704 column_semantic_types: &[("id", SemanticType::CatalogItemId)],
2705 }),
2706 });
2707
2708pub static MZ_CLUSTER_REPLICA_FRONTIERS: LazyLock<BuiltinSource> =
2709 LazyLock::new(|| BuiltinSource {
2710 name: "mz_cluster_replica_frontiers",
2711 schema: MZ_CATALOG_SCHEMA,
2712 oid: oid::SOURCE_MZ_CLUSTER_REPLICA_FRONTIERS_OID,
2713 data_source: IntrospectionType::ReplicaFrontiers.into(),
2714 desc: RelationDesc::builder()
2715 .with_column("object_id", SqlScalarType::String.nullable(false))
2716 .with_column("replica_id", SqlScalarType::String.nullable(false))
2717 .with_column("write_frontier", SqlScalarType::MzTimestamp.nullable(true))
2718 .finish(),
2719 column_comments: BTreeMap::from_iter([
2720 (
2721 "object_id",
2722 "The ID of the source, sink, index, materialized view, or subscription.",
2723 ),
2724 ("replica_id", "The ID of a cluster replica."),
2725 (
2726 "write_frontier",
2727 "The next timestamp at which the output may change.",
2728 ),
2729 ]),
2730 is_retained_metrics_object: false,
2731 access: vec![PUBLIC_SELECT],
2732 ontology: None,
2733 });
2734
2735pub static MZ_CLUSTER_REPLICA_FRONTIERS_IND: LazyLock<BuiltinIndex> =
2736 LazyLock::new(|| BuiltinIndex {
2737 name: "mz_cluster_replica_frontiers_ind",
2738 schema: MZ_CATALOG_SCHEMA,
2739 oid: oid::INDEX_MZ_CLUSTER_REPLICA_FRONTIERS_IND_OID,
2740 sql: "IN CLUSTER mz_catalog_server ON mz_catalog.mz_cluster_replica_frontiers (object_id)",
2741 is_retained_metrics_object: false,
2742 });
2743
2744pub static MZ_DEFAULT_PRIVILEGES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2745 BuiltinMaterializedView {
2746 name: "mz_default_privileges",
2747 schema: MZ_CATALOG_SCHEMA,
2748 oid: oid::MV_MZ_DEFAULT_PRIVILEGES_OID,
2749 desc: RelationDesc::builder()
2750 .with_column("role_id", SqlScalarType::String.nullable(false))
2751 .with_column("database_id", SqlScalarType::String.nullable(true))
2752 .with_column("schema_id", SqlScalarType::String.nullable(true))
2753 .with_column("object_type", SqlScalarType::String.nullable(false))
2754 .with_column("grantee", SqlScalarType::String.nullable(false))
2755 .with_column("privileges", SqlScalarType::String.nullable(false))
2756 .finish(),
2757 column_comments: BTreeMap::from_iter([
2758 (
2759 "role_id",
2760 "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.",
2761 ),
2762 (
2763 "database_id",
2764 "Privileges described in this row will be granted only on objects in the database identified by `database_id` if non-null.",
2765 ),
2766 (
2767 "schema_id",
2768 "Privileges described in this row will be granted only on objects in the schema identified by `schema_id` if non-null.",
2769 ),
2770 (
2771 "object_type",
2772 "Privileges described in this row will be granted only on objects of type `object_type`.",
2773 ),
2774 (
2775 "grantee",
2776 "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.",
2777 ),
2778 ("privileges", "The set of privileges that will be granted."),
2779 ]),
2780 sql: "
2788IN CLUSTER mz_catalog_server
2789WITH (
2790 ASSERT NOT NULL role_id,
2791 ASSERT NOT NULL object_type,
2792 ASSERT NOT NULL grantee,
2793 ASSERT NOT NULL privileges
2794) AS
2795SELECT
2796 mz_internal.parse_catalog_id(data->'key'->'role_id') AS role_id,
2797 CASE WHEN data->'key'->'database_id' != 'null'::jsonb
2798 THEN mz_internal.parse_catalog_id(data->'key'->'database_id') END AS database_id,
2799 CASE WHEN data->'key'->'schema_id' != 'null'::jsonb
2800 THEN mz_internal.parse_catalog_id(data->'key'->'schema_id') END AS schema_id,
2801 CASE data->'key'->>'object_type'
2802 WHEN '1' THEN 'table'
2803 WHEN '2' THEN 'view'
2804 WHEN '3' THEN 'materialized view'
2805 WHEN '4' THEN 'source'
2806 WHEN '5' THEN 'sink'
2807 WHEN '6' THEN 'index'
2808 WHEN '7' THEN 'type'
2809 WHEN '8' THEN 'role'
2810 WHEN '9' THEN 'cluster'
2811 WHEN '10' THEN 'cluster replica'
2812 WHEN '11' THEN 'secret'
2813 WHEN '12' THEN 'connection'
2814 WHEN '13' THEN 'database'
2815 WHEN '14' THEN 'schema'
2816 WHEN '15' THEN 'function'
2817 -- variant 16 reserved/unused in mz_catalog_protos::ObjectType.
2818 WHEN '17' THEN 'network policy'
2819 END AS object_type,
2820 mz_internal.parse_catalog_id(data->'key'->'grantee') AS grantee,
2821 mz_internal.parse_catalog_acl_mode(data->'value'->'privileges') AS privileges
2822FROM mz_internal.mz_catalog_raw
2823WHERE data->>'kind' = 'DefaultPrivileges'",
2824 is_retained_metrics_object: false,
2825 access: vec![PUBLIC_SELECT],
2826 ontology: Some(Ontology {
2827 entity_name: "default_privilege",
2828 description: "A default privilege rule applied to newly created objects",
2829 links: &const {
2830 [
2831 OntologyLink {
2832 name: "default_priv_for_role",
2833 target: "role",
2834 properties: LinkProperties::fk("role_id", "id", Cardinality::ManyToOne),
2835 },
2836 OntologyLink {
2837 name: "default_priv_in_database",
2838 target: "database",
2839 properties: LinkProperties::fk_nullable(
2840 "database_id",
2841 "id",
2842 Cardinality::ManyToOne,
2843 ),
2844 },
2845 OntologyLink {
2846 name: "default_priv_in_schema",
2847 target: "schema",
2848 properties: LinkProperties::fk_nullable(
2849 "schema_id",
2850 "id",
2851 Cardinality::ManyToOne,
2852 ),
2853 },
2854 OntologyLink {
2855 name: "default_priv_granted_to",
2856 target: "role",
2857 properties: LinkProperties::fk("grantee", "id", Cardinality::ManyToOne),
2858 },
2859 ]
2860 },
2861 column_semantic_types: &const {
2862 [
2863 ("role_id", SemanticType::RoleId),
2864 ("database_id", SemanticType::DatabaseId),
2865 ("schema_id", SemanticType::SchemaId),
2866 ("object_type", SemanticType::ObjectType),
2867 ("grantee", SemanticType::RoleId),
2868 ]
2869 },
2870 }),
2871 }
2872});
2873
2874pub static MZ_SYSTEM_PRIVILEGES: LazyLock<BuiltinMaterializedView> = LazyLock::new(|| {
2875 BuiltinMaterializedView {
2876 name: "mz_system_privileges",
2877 schema: MZ_CATALOG_SCHEMA,
2878 oid: oid::MV_MZ_SYSTEM_PRIVILEGES_OID,
2879 desc: RelationDesc::builder()
2880 .with_column("privileges", SqlScalarType::MzAclItem.nullable(false))
2881 .finish(),
2882 column_comments: BTreeMap::from_iter([(
2883 "privileges",
2884 "The privileges belonging to the system.",
2885 )]),
2886 sql: "
2890IN CLUSTER mz_catalog_server
2891WITH (
2892 ASSERT NOT NULL privileges
2893) AS
2894SELECT
2895 unnest(mz_internal.parse_catalog_privileges(
2896 jsonb_build_array(
2897 jsonb_build_object(
2898 'grantee', data->'key'->'grantee',
2899 'grantor', data->'key'->'grantor',
2900 'acl_mode', data->'value'->'acl_mode'
2901 )
2902 )
2903 )) AS privileges
2904FROM mz_internal.mz_catalog_raw
2905WHERE data->>'kind' = 'SystemPrivileges'",
2906 is_retained_metrics_object: false,
2907 access: vec![PUBLIC_SELECT],
2908 ontology: Some(Ontology {
2909 entity_name: "system_privilege",
2910 description: "A system-level privilege grant",
2911 links: &const { [] },
2912 column_semantic_types: &[],
2913 }),
2914 }
2915});
2916
2917pub static MZ_STORAGE_USAGE: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
2918 name: "mz_storage_usage",
2919 schema: MZ_CATALOG_SCHEMA,
2920 oid: oid::VIEW_MZ_STORAGE_USAGE_OID,
2921 desc: RelationDesc::builder()
2922 .with_column("object_id", SqlScalarType::String.nullable(false))
2923 .with_column("size_bytes", SqlScalarType::UInt64.nullable(false))
2924 .with_column(
2925 "collection_timestamp",
2926 SqlScalarType::TimestampTz { precision: None }.nullable(false),
2927 )
2928 .with_key(vec![0, 2])
2929 .finish(),
2930 column_comments: BTreeMap::from_iter([
2931 (
2932 "object_id",
2933 "The ID of the table, source, or materialized view.",
2934 ),
2935 (
2936 "size_bytes",
2937 "The number of storage bytes used by the object.",
2938 ),
2939 (
2940 "collection_timestamp",
2941 "The time at which storage usage of the object was assessed.",
2942 ),
2943 ]),
2944 sql: "
2945SELECT
2946 object_id,
2947 sum(size_bytes)::uint8 AS size_bytes,
2948 collection_timestamp
2949FROM
2950 mz_internal.mz_storage_shards
2951 JOIN mz_internal.mz_storage_usage_by_shard USING (shard_id)
2952GROUP BY object_id, collection_timestamp",
2953 access: vec![PUBLIC_SELECT],
2954 ontology: Some(Ontology {
2955 entity_name: "storage_usage",
2956 description: "Historical storage usage per object over time",
2957 links: &const {
2958 [OntologyLink {
2959 name: "storage_usage_of",
2960 target: "object",
2961 properties: LinkProperties::fk("object_id", "id", Cardinality::ManyToOne),
2962 }]
2963 },
2964 column_semantic_types: &const {
2965 [
2966 ("object_id", SemanticType::CatalogItemId),
2967 ("size_bytes", SemanticType::ByteCount),
2968 ("collection_timestamp", SemanticType::WallclockTimestamp),
2969 ]
2970 },
2971 }),
2972});
2973
2974pub static MZ_RECENT_STORAGE_USAGE: LazyLock<BuiltinView> = LazyLock::new(|| {
2975 BuiltinView {
2976 name: "mz_recent_storage_usage",
2977 schema: MZ_CATALOG_SCHEMA,
2978 oid: oid::VIEW_MZ_RECENT_STORAGE_USAGE_OID,
2979 desc: RelationDesc::builder()
2980 .with_column("object_id", SqlScalarType::String.nullable(false))
2981 .with_column("size_bytes", SqlScalarType::UInt64.nullable(true))
2982 .with_key(vec![0])
2983 .finish(),
2984 column_comments: BTreeMap::from_iter([
2985 ("object_id", "The ID of the table, source, or materialized view."),
2986 ("size_bytes", "The number of storage bytes used by the object in the most recent assessment."),
2987 ]),
2988 sql: "
2989WITH
2990
2991recent_storage_usage_by_shard AS (
2992 SELECT shard_id, size_bytes, collection_timestamp
2993 FROM mz_internal.mz_storage_usage_by_shard
2994 -- Restricting to the last 6 hours makes it feasible to index the view.
2995 WHERE collection_timestamp + '6 hours' >= mz_now()
2996),
2997
2998most_recent_collection_timestamp_by_shard AS (
2999 SELECT shard_id, max(collection_timestamp) AS collection_timestamp
3000 FROM recent_storage_usage_by_shard
3001 GROUP BY shard_id
3002)
3003
3004SELECT
3005 object_id,
3006 sum(size_bytes)::uint8 AS size_bytes
3007FROM
3008 mz_internal.mz_storage_shards
3009 LEFT JOIN most_recent_collection_timestamp_by_shard
3010 ON mz_storage_shards.shard_id = most_recent_collection_timestamp_by_shard.shard_id
3011 LEFT JOIN recent_storage_usage_by_shard
3012 ON mz_storage_shards.shard_id = recent_storage_usage_by_shard.shard_id
3013 AND most_recent_collection_timestamp_by_shard.collection_timestamp = recent_storage_usage_by_shard.collection_timestamp
3014GROUP BY object_id",
3015 access: vec![PUBLIC_SELECT],
3016 ontology: Some(Ontology {
3017 entity_name: "recent_storage",
3018 description: "Most recent storage usage snapshot per object",
3019 links: &const { [
3020 OntologyLink { name: "recent_storage_of", target: "object", properties: LinkProperties::fk("object_id", "id", Cardinality::OneToOne) },
3021 ] },
3022 column_semantic_types: &const {[("object_id", SemanticType::CatalogItemId), ("size_bytes", SemanticType::ByteCount)]},
3023 }),
3024}
3025});
3026
3027pub static MZ_RECENT_STORAGE_USAGE_IND: LazyLock<BuiltinIndex> = LazyLock::new(|| BuiltinIndex {
3028 name: "mz_recent_storage_usage_ind",
3029 schema: MZ_CATALOG_SCHEMA,
3030 oid: oid::INDEX_MZ_RECENT_STORAGE_USAGE_IND_OID,
3031 sql: "IN CLUSTER mz_catalog_server ON mz_catalog.mz_recent_storage_usage (object_id)",
3032 is_retained_metrics_object: false,
3033});
3034
3035pub static MZ_RELATIONS: LazyLock<BuiltinView> = LazyLock::new(|| {
3036 BuiltinView {
3037 name: "mz_relations",
3038 schema: MZ_CATALOG_SCHEMA,
3039 oid: oid::VIEW_MZ_RELATIONS_OID,
3040 desc: RelationDesc::builder()
3041 .with_column("id", SqlScalarType::String.nullable(false))
3042 .with_column("oid", SqlScalarType::Oid.nullable(false))
3043 .with_column("schema_id", SqlScalarType::String.nullable(false))
3044 .with_column("name", SqlScalarType::String.nullable(false))
3045 .with_column("type", SqlScalarType::String.nullable(false))
3046 .with_column("owner_id", SqlScalarType::String.nullable(false))
3047 .with_column("cluster_id", SqlScalarType::String.nullable(true))
3048 .with_column("privileges", SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(false))
3049 .finish(),
3050 column_comments: BTreeMap::from_iter([
3051 ("id", "Materialize's unique ID for the relation."),
3052 ("oid", "A PostgreSQL-compatible OID for the relation."),
3053 ("schema_id", "The ID of the schema to which the relation belongs. Corresponds to `mz_schemas.id`."),
3054 ("name", "The name of the relation."),
3055 ("type", "The type of the relation: either `table`, `source`, `view`, or `materialized-view`."),
3056 ("owner_id", "The role ID of the owner of the relation. Corresponds to `mz_roles.id`."),
3057 ("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."),
3058 ("privileges", "The privileges belonging to the relation."),
3059 ]),
3060 sql: "
3061 SELECT id, oid, schema_id, name, 'table' AS type, owner_id, NULL::text AS cluster_id, privileges FROM mz_catalog.mz_tables
3062UNION ALL SELECT id, oid, schema_id, name, 'source', owner_id, cluster_id, privileges FROM mz_catalog.mz_sources
3063UNION ALL SELECT id, oid, schema_id, name, 'view', owner_id, NULL::text, privileges FROM mz_catalog.mz_views
3064UNION ALL SELECT id, oid, schema_id, name, 'materialized-view', owner_id, cluster_id, privileges FROM mz_catalog.mz_materialized_views",
3065 access: vec![PUBLIC_SELECT],
3066 ontology: Some(Ontology {
3067 entity_name: "relation",
3068 description: "Union of all relation types: tables, sources, views, MVs (convenience view)",
3069 links: &const { [
3070 OntologyLink { name: "union_includes", target: "table", properties: LinkProperties::union_disc("type", "table") },
3071 OntologyLink { name: "union_includes", target: "source", properties: LinkProperties::union_disc("type", "source") },
3072 OntologyLink { name: "union_includes", target: "view", properties: LinkProperties::union_disc("type", "view") },
3073 OntologyLink { name: "union_includes", target: "mv", properties: LinkProperties::union_disc("type", "materialized-view") },
3074 ] },
3075 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)]},
3076 }),
3077 }
3078});
3079
3080pub static MZ_OBJECTS: LazyLock<BuiltinView> = LazyLock::new(|| {
3081 BuiltinView {
3082 name: "mz_objects",
3083 schema: MZ_CATALOG_SCHEMA,
3084 oid: oid::VIEW_MZ_OBJECTS_OID,
3085 desc: RelationDesc::builder()
3086 .with_column("id", SqlScalarType::String.nullable(false))
3087 .with_column("oid", SqlScalarType::Oid.nullable(false))
3088 .with_column("schema_id", SqlScalarType::String.nullable(false))
3089 .with_column("name", SqlScalarType::String.nullable(false))
3090 .with_column("type", SqlScalarType::String.nullable(false))
3091 .with_column("owner_id", SqlScalarType::String.nullable(false))
3092 .with_column("cluster_id", SqlScalarType::String.nullable(true))
3093 .with_column("privileges", SqlScalarType::Array(Box::new(SqlScalarType::MzAclItem)).nullable(true))
3094 .finish(),
3095 column_comments: BTreeMap::from_iter([
3096 ("id", "Materialize's unique ID for the object."),
3097 ("oid", "A PostgreSQL-compatible OID for the object."),
3098 ("schema_id", "The ID of the schema to which the object belongs. Corresponds to `mz_schemas.id`."),
3099 ("name", "The name of the object."),
3100 ("type", "The type of the object: one of `table`, `source`, `view`, `materialized-view`, `sink`, `index`, `connection`, `secret`, `type`, or `function`."),
3101 ("owner_id", "The role ID of the owner of the object. Corresponds to `mz_roles.id`."),
3102 ("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."),
3103 ("privileges", "The privileges belonging to the object."),
3104 ]),
3105 sql:
3106 "SELECT id, oid, schema_id, name, type, owner_id, cluster_id, privileges FROM mz_catalog.mz_relations
3107UNION ALL
3108 SELECT id, oid, schema_id, name, 'sink', owner_id, cluster_id, NULL::mz_catalog.mz_aclitem[] FROM mz_catalog.mz_sinks
3109UNION ALL
3110 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[]
3111 FROM mz_catalog.mz_indexes
3112 JOIN mz_catalog.mz_relations ON mz_indexes.on_id = mz_relations.id
3113UNION ALL
3114 SELECT id, oid, schema_id, name, 'connection', owner_id, NULL::text, privileges FROM mz_catalog.mz_connections
3115UNION ALL
3116 SELECT id, oid, schema_id, name, 'type', owner_id, NULL::text, privileges FROM mz_catalog.mz_types
3117UNION ALL
3118 SELECT id, oid, schema_id, name, 'function', owner_id, NULL::text, NULL::mz_catalog.mz_aclitem[] FROM mz_catalog.mz_functions
3119UNION ALL
3120 SELECT id, oid, schema_id, name, 'secret', owner_id, NULL::text, privileges FROM mz_catalog.mz_secrets",
3121 access: vec![PUBLIC_SELECT],
3122 ontology: Some(Ontology {
3123 entity_name: "object",
3124 description: "Union of all object types: relations, indexes, connections, etc. (convenience view)",
3125 links: &const {
3126 [
3127 OntologyLink {
3128 name: "union_includes",
3129 target: "relation",
3130 properties: LinkProperties::Union {
3131 discriminator_column: None,
3132 discriminator_value: None,
3133 note: Some("covers all mz_relations rows (table, source, view, mv)"),
3134 },
3135 },
3136 OntologyLink {
3137 name: "union_includes",
3138 target: "table",
3139 properties: LinkProperties::union_disc("type", "table"),
3140 },
3141 OntologyLink {
3142 name: "union_includes",
3143 target: "source",
3144 properties: LinkProperties::union_disc("type", "source"),
3145 },
3146 OntologyLink {
3147 name: "union_includes",
3148 target: "view",
3149 properties: LinkProperties::union_disc("type", "view"),
3150 },
3151 OntologyLink {
3152 name: "union_includes",
3153 target: "mv",
3154 properties: LinkProperties::union_disc("type", "materialized-view"),
3155 },
3156 OntologyLink {
3157 name: "union_includes",
3158 target: "sink",
3159 properties: LinkProperties::union_disc("type", "sink"),
3160 },
3161 OntologyLink {
3162 name: "union_includes",
3163 target: "index",
3164 properties: LinkProperties::union_disc("type", "index"),
3165 },
3166 OntologyLink {
3167 name: "union_includes",
3168 target: "connection",
3169 properties: LinkProperties::union_disc("type", "connection"),
3170 },
3171 OntologyLink {
3172 name: "union_includes",
3173 target: "type",
3174 properties: LinkProperties::union_disc("type", "type"),
3175 },
3176 OntologyLink {
3177 name: "union_includes",
3178 target: "function",
3179 properties: LinkProperties::union_disc("type", "function"),
3180 },
3181 OntologyLink {
3182 name: "union_includes",
3183 target: "secret",
3184 properties: LinkProperties::union_disc("type", "secret"),
3185 },
3186 OntologyLink {
3187 name: "in_schema",
3188 target: "schema",
3189 properties: LinkProperties::fk("schema_id", "id", Cardinality::ManyToOne),
3190 },
3191 OntologyLink {
3192 name: "owned_by",
3193 target: "role",
3194 properties: LinkProperties::fk("owner_id", "id", Cardinality::ManyToOne),
3195 },
3196 OntologyLink {
3197 name: "on_cluster",
3198 target: "cluster",
3199 properties: LinkProperties::fk_nullable(
3200 "cluster_id",
3201 "id",
3202 Cardinality::ManyToOne,
3203 ),
3204 },
3205 ]
3206 },
3207 column_semantic_types: &const {
3208 [
3209 ("id", SemanticType::CatalogItemId),
3210 ("oid", SemanticType::OID),
3211 ("schema_id", SemanticType::SchemaId),
3212 ("type", SemanticType::ObjectType),
3213 ("owner_id", SemanticType::RoleId),
3214 ("cluster_id", SemanticType::ClusterId),
3215 ]
3216 },
3217 }),
3218 }
3219});
3220
3221pub static MZ_TIMEZONE_ABBREVIATIONS: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3222 name: "mz_timezone_abbreviations",
3223 schema: MZ_CATALOG_SCHEMA,
3224 oid: oid::VIEW_MZ_TIMEZONE_ABBREVIATIONS_OID,
3225 desc: RelationDesc::builder()
3226 .with_column("abbreviation", SqlScalarType::String.nullable(false))
3227 .with_column("utc_offset", SqlScalarType::Interval.nullable(true))
3228 .with_column("dst", SqlScalarType::Bool.nullable(true))
3229 .with_column("timezone_name", SqlScalarType::String.nullable(true))
3230 .with_key(vec![0])
3231 .finish(),
3232 column_comments: BTreeMap::from_iter([
3233 ("abbreviation", "The timezone abbreviation."),
3234 (
3235 "utc_offset",
3236 "The UTC offset of the timezone or `NULL` if fixed.",
3237 ),
3238 (
3239 "dst",
3240 "Whether the timezone is in daylight savings or `NULL` if fixed.",
3241 ),
3242 (
3243 "timezone_name",
3244 "The full name of the non-fixed timezone or `NULL` if not fixed.",
3245 ),
3246 ]),
3247 sql: format!(
3248 "SELECT * FROM ({}) _ (abbreviation, utc_offset, dst, timezone_name)",
3249 mz_pgtz::abbrev::MZ_CATALOG_TIMEZONE_ABBREVIATIONS_SQL,
3250 )
3251 .leak(),
3252 access: vec![PUBLIC_SELECT],
3253 ontology: None,
3254});
3255
3256pub static MZ_TIMEZONE_NAMES: LazyLock<BuiltinView> = LazyLock::new(|| BuiltinView {
3257 name: "mz_timezone_names",
3258 schema: MZ_CATALOG_SCHEMA,
3259 oid: oid::VIEW_MZ_TIMEZONE_NAMES_OID,
3260 desc: RelationDesc::builder()
3261 .with_column("name", SqlScalarType::String.nullable(false))
3262 .with_key(vec![0])
3263 .finish(),
3264 column_comments: BTreeMap::from_iter([("name", "The timezone name.")]),
3265 sql: format!(
3266 "SELECT * FROM ({}) _ (name)",
3267 mz_pgtz::timezone::MZ_CATALOG_TIMEZONE_NAMES_SQL,
3268 )
3269 .leak(),
3270 access: vec![PUBLIC_SELECT],
3271 ontology: None,
3272});
3273
3274pub const MZ_DATABASES_IND: BuiltinIndex = BuiltinIndex {
3275 name: "mz_databases_ind",
3276 schema: MZ_CATALOG_SCHEMA,
3277 oid: oid::INDEX_MZ_DATABASES_IND_OID,
3278 sql: "IN CLUSTER mz_catalog_server
3279ON mz_catalog.mz_databases (name)",
3280 is_retained_metrics_object: false,
3281};
3282
3283pub const MZ_SCHEMAS_IND: BuiltinIndex = BuiltinIndex {
3284 name: "mz_schemas_ind",
3285 schema: MZ_CATALOG_SCHEMA,
3286 oid: oid::INDEX_MZ_SCHEMAS_IND_OID,
3287 sql: "IN CLUSTER mz_catalog_server
3288ON mz_catalog.mz_schemas (database_id)",
3289 is_retained_metrics_object: false,
3290};
3291
3292pub const MZ_CONNECTIONS_IND: BuiltinIndex = BuiltinIndex {
3293 name: "mz_connections_ind",
3294 schema: MZ_CATALOG_SCHEMA,
3295 oid: oid::INDEX_MZ_CONNECTIONS_IND_OID,
3296 sql: "IN CLUSTER mz_catalog_server
3297ON mz_catalog.mz_connections (schema_id)",
3298 is_retained_metrics_object: false,
3299};
3300
3301pub const MZ_TABLES_IND: BuiltinIndex = BuiltinIndex {
3302 name: "mz_tables_ind",
3303 schema: MZ_CATALOG_SCHEMA,
3304 oid: oid::INDEX_MZ_TABLES_IND_OID,
3305 sql: "IN CLUSTER mz_catalog_server
3306ON mz_catalog.mz_tables (schema_id)",
3307 is_retained_metrics_object: false,
3308};
3309
3310pub const MZ_TYPES_IND: BuiltinIndex = BuiltinIndex {
3311 name: "mz_types_ind",
3312 schema: MZ_CATALOG_SCHEMA,
3313 oid: oid::INDEX_MZ_TYPES_IND_OID,
3314 sql: "IN CLUSTER mz_catalog_server
3315ON mz_catalog.mz_types (schema_id)",
3316 is_retained_metrics_object: false,
3317};
3318
3319pub const MZ_OBJECTS_IND: BuiltinIndex = BuiltinIndex {
3320 name: "mz_objects_ind",
3321 schema: MZ_CATALOG_SCHEMA,
3322 oid: oid::INDEX_MZ_OBJECTS_IND_OID,
3323 sql: "IN CLUSTER mz_catalog_server
3324ON mz_catalog.mz_objects (schema_id)",
3325 is_retained_metrics_object: false,
3326};
3327
3328pub const MZ_COLUMNS_IND: BuiltinIndex = BuiltinIndex {
3329 name: "mz_columns_ind",
3330 schema: MZ_CATALOG_SCHEMA,
3331 oid: oid::INDEX_MZ_COLUMNS_IND_OID,
3332 sql: "IN CLUSTER mz_catalog_server
3333ON mz_catalog.mz_columns (name)",
3334 is_retained_metrics_object: false,
3335};
3336
3337pub const MZ_SECRETS_IND: BuiltinIndex = BuiltinIndex {
3338 name: "mz_secrets_ind",
3339 schema: MZ_CATALOG_SCHEMA,
3340 oid: oid::INDEX_MZ_SECRETS_IND_OID,
3341 sql: "IN CLUSTER mz_catalog_server
3342ON mz_catalog.mz_secrets (name)",
3343 is_retained_metrics_object: false,
3344};
3345
3346pub const MZ_VIEWS_IND: BuiltinIndex = BuiltinIndex {
3347 name: "mz_views_ind",
3348 schema: MZ_CATALOG_SCHEMA,
3349 oid: oid::INDEX_MZ_VIEWS_IND_OID,
3350 sql: "IN CLUSTER mz_catalog_server
3351ON mz_catalog.mz_views (schema_id)",
3352 is_retained_metrics_object: false,
3353};
3354
3355pub const MZ_CLUSTERS_IND: BuiltinIndex = BuiltinIndex {
3356 name: "mz_clusters_ind",
3357 schema: MZ_CATALOG_SCHEMA,
3358 oid: oid::INDEX_MZ_CLUSTERS_IND_OID,
3359 sql: "IN CLUSTER mz_catalog_server
3360ON mz_catalog.mz_clusters (id)",
3361 is_retained_metrics_object: false,
3362};
3363
3364pub const MZ_INDEXES_IND: BuiltinIndex = BuiltinIndex {
3365 name: "mz_indexes_ind",
3366 schema: MZ_CATALOG_SCHEMA,
3367 oid: oid::INDEX_MZ_INDEXES_IND_OID,
3368 sql: "IN CLUSTER mz_catalog_server
3369ON mz_catalog.mz_indexes (id)",
3370 is_retained_metrics_object: false,
3371};
3372
3373pub const MZ_ROLES_IND: BuiltinIndex = BuiltinIndex {
3374 name: "mz_roles_ind",
3375 schema: MZ_CATALOG_SCHEMA,
3376 oid: oid::INDEX_MZ_ROLES_IND_OID,
3377 sql: "IN CLUSTER mz_catalog_server
3378ON mz_catalog.mz_roles (id)",
3379 is_retained_metrics_object: false,
3380};
3381
3382pub const MZ_SOURCES_IND: BuiltinIndex = BuiltinIndex {
3383 name: "mz_sources_ind",
3384 schema: MZ_CATALOG_SCHEMA,
3385 oid: oid::INDEX_MZ_SOURCES_IND_OID,
3386 sql: "IN CLUSTER mz_catalog_server
3387ON mz_catalog.mz_sources (id)",
3388 is_retained_metrics_object: true,
3389};
3390
3391pub const MZ_SINKS_IND: BuiltinIndex = BuiltinIndex {
3392 name: "mz_sinks_ind",
3393 schema: MZ_CATALOG_SCHEMA,
3394 oid: oid::INDEX_MZ_SINKS_IND_OID,
3395 sql: "IN CLUSTER mz_catalog_server
3396ON mz_catalog.mz_sinks (id)",
3397 is_retained_metrics_object: true,
3398};
3399
3400pub const MZ_MATERIALIZED_VIEWS_IND: BuiltinIndex = BuiltinIndex {
3401 name: "mz_materialized_views_ind",
3402 schema: MZ_CATALOG_SCHEMA,
3403 oid: oid::INDEX_MZ_MATERIALIZED_VIEWS_IND_OID,
3404 sql: "IN CLUSTER mz_catalog_server
3405ON mz_catalog.mz_materialized_views (id)",
3406 is_retained_metrics_object: false,
3407};
3408
3409pub const MZ_CLUSTER_REPLICAS_IND: BuiltinIndex = BuiltinIndex {
3410 name: "mz_cluster_replicas_ind",
3411 schema: MZ_CATALOG_SCHEMA,
3412 oid: oid::INDEX_MZ_CLUSTER_REPLICAS_IND_OID,
3413 sql: "IN CLUSTER mz_catalog_server
3414ON mz_catalog.mz_cluster_replicas (id)",
3415 is_retained_metrics_object: true,
3416};
3417
3418pub const MZ_CLUSTER_REPLICA_SIZES_IND: BuiltinIndex = BuiltinIndex {
3419 name: "mz_cluster_replica_sizes_ind",
3420 schema: MZ_CATALOG_SCHEMA,
3421 oid: oid::INDEX_MZ_CLUSTER_REPLICA_SIZES_IND_OID,
3422 sql: "IN CLUSTER mz_catalog_server
3423ON mz_catalog.mz_cluster_replica_sizes (size)",
3424 is_retained_metrics_object: true,
3425};
3426
3427pub const MZ_KAFKA_SOURCES_IND: BuiltinIndex = BuiltinIndex {
3428 name: "mz_kafka_sources_ind",
3429 schema: MZ_CATALOG_SCHEMA,
3430 oid: oid::INDEX_MZ_KAFKA_SOURCES_IND_OID,
3431 sql: "IN CLUSTER mz_catalog_server
3432ON mz_catalog.mz_kafka_sources (id)",
3433 is_retained_metrics_object: true,
3434};
3435
3436#[cfg(test)]
3437mod tests {
3438 use mz_catalog_protos::objects::ObjectType as ProtoObjectType;
3439 use mz_sql::catalog::ObjectType as SqlObjectType;
3440
3441 use crate::builtin::mz_catalog::MZ_DEFAULT_PRIVILEGES;
3442
3443 #[mz_ore::test]
3451 fn object_type_case_matches_proto_display() {
3452 fn expected_for(proto: ProtoObjectType) -> Option<SqlObjectType> {
3456 match proto {
3457 ProtoObjectType::Unknown => None,
3458 ProtoObjectType::Table => Some(SqlObjectType::Table),
3459 ProtoObjectType::View => Some(SqlObjectType::View),
3460 ProtoObjectType::MaterializedView => Some(SqlObjectType::MaterializedView),
3461 ProtoObjectType::Source => Some(SqlObjectType::Source),
3462 ProtoObjectType::Sink => Some(SqlObjectType::Sink),
3463 ProtoObjectType::Index => Some(SqlObjectType::Index),
3464 ProtoObjectType::Type => Some(SqlObjectType::Type),
3465 ProtoObjectType::Role => Some(SqlObjectType::Role),
3466 ProtoObjectType::Cluster => Some(SqlObjectType::Cluster),
3467 ProtoObjectType::ClusterReplica => Some(SqlObjectType::ClusterReplica),
3468 ProtoObjectType::Secret => Some(SqlObjectType::Secret),
3469 ProtoObjectType::Connection => Some(SqlObjectType::Connection),
3470 ProtoObjectType::Database => Some(SqlObjectType::Database),
3471 ProtoObjectType::Schema => Some(SqlObjectType::Schema),
3472 ProtoObjectType::Func => Some(SqlObjectType::Func),
3473 ProtoObjectType::NetworkPolicy => Some(SqlObjectType::NetworkPolicy),
3474 }
3475 }
3476
3477 let variants: &[ProtoObjectType] = &[
3482 ProtoObjectType::Unknown,
3483 ProtoObjectType::Table,
3484 ProtoObjectType::View,
3485 ProtoObjectType::MaterializedView,
3486 ProtoObjectType::Source,
3487 ProtoObjectType::Sink,
3488 ProtoObjectType::Index,
3489 ProtoObjectType::Type,
3490 ProtoObjectType::Role,
3491 ProtoObjectType::Cluster,
3492 ProtoObjectType::ClusterReplica,
3493 ProtoObjectType::Secret,
3494 ProtoObjectType::Connection,
3495 ProtoObjectType::Database,
3496 ProtoObjectType::Schema,
3497 ProtoObjectType::Func,
3498 ProtoObjectType::NetworkPolicy,
3499 ];
3500
3501 let sql = MZ_DEFAULT_PRIVILEGES.sql;
3502 for &proto in variants {
3503 #[allow(clippy::as_conversions)]
3506 let repr = proto as u8;
3507 match expected_for(proto) {
3508 Some(sql_ty) => {
3509 let display = sql_ty.to_string().to_lowercase();
3510 let one_space = format!("WHEN '{repr}' THEN '{display}'");
3514 let two_spaces = format!("WHEN '{repr}' THEN '{display}'");
3515 assert!(
3516 sql.contains(&one_space) || sql.contains(&two_spaces),
3517 "missing CASE arm for `{proto:?}`: expected \
3518 `WHEN '{repr}' THEN '{display}'` (or with double space) \
3519 in MZ_DEFAULT_PRIVILEGES.sql",
3520 );
3521 }
3522 None => {
3523 let pattern = format!("WHEN '{repr}'");
3524 assert!(
3525 !sql.contains(&pattern),
3526 "unexpected CASE arm for sentinel `{proto:?}`: \
3527 found `{pattern}` in MZ_DEFAULT_PRIVILEGES.sql",
3528 );
3529 }
3530 }
3531 }
3532 }
3533}