1use std::collections::hash_map::Entry::{Occupied, Vacant};
16use std::collections::{HashMap, HashSet};
17use std::sync::Arc;
18
19use itertools::Itertools;
20use risingwave_common::catalog::{FunctionId, IndexId, ObjectId, StreamJobStatus, TableId};
21use risingwave_common::types::DataType;
22use risingwave_connector::sink::catalog::SinkCatalog;
23pub use risingwave_expr::sig::*;
24use risingwave_pb::catalog::{
25 PbConnection, PbFunction, PbIndex, PbSchema, PbSecret, PbSink, PbSource, PbSubscription,
26 PbTable, PbView,
27};
28use risingwave_pb::user::grant_privilege::Object;
29
30use super::subscription_catalog::SubscriptionCatalog;
31use super::{OwnedByUserCatalog, OwnedGrantObject, SubscriptionId};
32use crate::catalog::connection_catalog::ConnectionCatalog;
33use crate::catalog::function_catalog::FunctionCatalog;
34use crate::catalog::index_catalog::IndexCatalog;
35use crate::catalog::secret_catalog::SecretCatalog;
36use crate::catalog::source_catalog::SourceCatalog;
37use crate::catalog::system_catalog::SystemTableCatalog;
38use crate::catalog::table_catalog::TableCatalog;
39use crate::catalog::view_catalog::ViewCatalog;
40use crate::catalog::{ConnectionId, DatabaseId, SchemaId, SecretId, SinkId, SourceId, ViewId};
41use crate::expr::{Expr, ExprImpl, infer_type_name, infer_type_with_sigmap};
42use crate::user::user_catalog::UserCatalog;
43use crate::user::{UserId, has_access_to_object};
44
45#[derive(Clone, Debug)]
46pub struct SchemaCatalog {
47 id: SchemaId,
48 pub name: String,
49 pub database_id: DatabaseId,
50 table_by_name: HashMap<String, Arc<TableCatalog>>,
52 table_by_id: HashMap<TableId, Arc<TableCatalog>>,
54 source_by_name: HashMap<String, Arc<SourceCatalog>>,
55 source_by_id: HashMap<SourceId, Arc<SourceCatalog>>,
56 sink_by_name: HashMap<String, Arc<SinkCatalog>>,
57 sink_by_id: HashMap<SinkId, Arc<SinkCatalog>>,
58 table_incoming_sinks: HashMap<TableId, HashSet<SinkId>>,
60 subscription_by_name: HashMap<String, Arc<SubscriptionCatalog>>,
61 subscription_by_id: HashMap<SubscriptionId, Arc<SubscriptionCatalog>>,
62 index_by_name: HashMap<String, Arc<IndexCatalog>>,
63 index_by_id: HashMap<IndexId, Arc<IndexCatalog>>,
64 indexes_by_table_id: HashMap<TableId, Vec<Arc<IndexCatalog>>>,
65 view_by_name: HashMap<String, Arc<ViewCatalog>>,
66 view_by_id: HashMap<ViewId, Arc<ViewCatalog>>,
67 function_registry: FunctionRegistry,
68 function_by_name: HashMap<String, HashMap<Vec<DataType>, Arc<FunctionCatalog>>>,
69 function_by_id: HashMap<FunctionId, Arc<FunctionCatalog>>,
70 connection_by_name: HashMap<String, Arc<ConnectionCatalog>>,
71 connection_by_id: HashMap<ConnectionId, Arc<ConnectionCatalog>>,
72 secret_by_name: HashMap<String, Arc<SecretCatalog>>,
73 secret_by_id: HashMap<SecretId, Arc<SecretCatalog>>,
74
75 _secret_source_ref: HashMap<SecretId, Vec<SourceId>>,
76 _secret_sink_ref: HashMap<SecretId, Vec<SinkId>>,
77
78 connection_source_ref: HashMap<ConnectionId, Vec<SourceId>>,
80 connection_sink_ref: HashMap<ConnectionId, Vec<SinkId>>,
82 system_table_by_name: HashMap<String, Arc<SystemTableCatalog>>,
84 pub owner: UserId,
85}
86
87impl SchemaCatalog {
88 pub fn create_table(&mut self, prost: &PbTable) -> Arc<TableCatalog> {
89 let name = prost.name.clone();
90 let id = prost.id;
91 let table: TableCatalog = prost.into();
92 let table_ref = Arc::new(table);
93
94 self.table_by_name
95 .try_insert(name, table_ref.clone())
96 .unwrap();
97 self.table_by_id.try_insert(id, table_ref.clone()).unwrap();
98 table_ref
99 }
100
101 pub fn create_sys_table(&mut self, sys_table: Arc<SystemTableCatalog>) {
102 self.system_table_by_name
103 .try_insert(sys_table.name.clone(), sys_table)
104 .unwrap();
105 }
106
107 pub fn create_sys_view(&mut self, sys_view: Arc<ViewCatalog>) {
108 self.view_by_name
109 .try_insert(sys_view.name().to_owned(), sys_view.clone())
110 .unwrap();
111 self.view_by_id
112 .try_insert(sys_view.id, sys_view.clone())
113 .unwrap();
114 }
115
116 pub fn update_table(&mut self, prost: &PbTable) -> Arc<TableCatalog> {
117 let name = prost.name.clone();
118 let id = prost.id;
119 let table: TableCatalog = prost.into();
120 let table_ref = Arc::new(table);
121
122 let old_table = self.table_by_id.get(&id).unwrap();
123 if old_table.name() != name
125 && let Some(t) = self.table_by_name.get(old_table.name())
126 && t.id == id
127 {
128 self.table_by_name.remove(old_table.name());
129 }
130
131 self.table_by_name.insert(name, table_ref.clone());
132 self.table_by_id.insert(id, table_ref.clone());
133 table_ref
134 }
135
136 pub fn update_index(&mut self, prost: &PbIndex) {
137 let name = prost.name.clone();
138 let id = prost.id;
139 let old_index = self.index_by_id.get(&id).unwrap();
140 let index_table = self.get_created_table_by_id(prost.index_table_id).unwrap();
141 let primary_table = self
142 .get_created_table_by_id(prost.primary_table_id)
143 .unwrap();
144 let index: IndexCatalog = IndexCatalog::build_from(prost, index_table, primary_table);
145 let index_ref = Arc::new(index);
146
147 if old_index.name != name
149 && let Some(idx) = self.index_by_name.get(&old_index.name)
150 && idx.id == id
151 {
152 self.index_by_name.remove(&old_index.name);
153 }
154 self.index_by_name.insert(name, index_ref.clone());
155 self.index_by_id.insert(id, index_ref.clone());
156
157 match self.indexes_by_table_id.entry(index_ref.primary_table.id) {
158 Occupied(mut entry) => {
159 let pos = entry
160 .get()
161 .iter()
162 .position(|x| x.id == index_ref.id)
163 .unwrap();
164 *entry.get_mut().get_mut(pos).unwrap() = index_ref;
165 }
166 Vacant(_entry) => {
167 unreachable!()
168 }
169 };
170 }
171
172 pub fn drop_table(&mut self, id: TableId) {
173 if let Some(table_ref) = self.table_by_id.remove(&id) {
174 self.table_by_name.remove(&table_ref.name).unwrap();
175 self.indexes_by_table_id.remove(&table_ref.id);
176 } else {
177 tracing::warn!(
178 %id,
179 "table not found when dropping, frontend might not be notified yet"
180 );
181 }
182 }
183
184 pub fn create_index(&mut self, prost: &PbIndex) {
185 let name = prost.name.clone();
186 let id = prost.id;
187 let index_table = self.get_table_by_id(prost.index_table_id).unwrap();
188 let primary_table = self
189 .get_created_table_by_id(prost.primary_table_id)
190 .unwrap();
191 let index: IndexCatalog = IndexCatalog::build_from(prost, index_table, primary_table);
192 let index_ref = Arc::new(index);
193
194 self.index_by_name
195 .try_insert(name, index_ref.clone())
196 .unwrap();
197 self.index_by_id.try_insert(id, index_ref.clone()).unwrap();
198 match self.indexes_by_table_id.entry(index_ref.primary_table.id) {
199 Occupied(mut entry) => {
200 entry.get_mut().push(index_ref);
201 }
202 Vacant(entry) => {
203 entry.insert(vec![index_ref]);
204 }
205 };
206 }
207
208 pub fn drop_index(&mut self, id: IndexId) {
209 let Some(index_ref) = self.index_by_id.remove(&id) else {
210 tracing::warn!(
211 %id,
212 "index not found when dropping, frontend might not be notified yet"
213 );
214 return;
215 };
216 self.index_by_name.remove(&index_ref.name).unwrap();
217 match self.indexes_by_table_id.entry(index_ref.primary_table.id) {
218 Occupied(mut entry) => {
219 let pos = entry
220 .get_mut()
221 .iter()
222 .position(|x| x.id == index_ref.id)
223 .unwrap();
224 entry.get_mut().remove(pos);
225 }
226 Vacant(_entry) => (),
227 };
228 }
229
230 pub fn create_source(&mut self, prost: &PbSource) {
231 let name = prost.name.clone();
232 let id = prost.id;
233 let source = SourceCatalog::from(prost);
234 let source_ref = Arc::new(source);
235
236 if let Some(connection_id) = source_ref.connection_id {
237 self.connection_source_ref
238 .entry(connection_id)
239 .and_modify(|sources| sources.push(source_ref.id))
240 .or_insert(vec![source_ref.id]);
241 }
242
243 self.source_by_name
244 .try_insert(name, source_ref.clone())
245 .unwrap();
246 self.source_by_id.try_insert(id, source_ref).unwrap();
247 }
248
249 pub fn drop_source(&mut self, id: SourceId) {
250 let Some(source_ref) = self.source_by_id.remove(&id) else {
251 tracing::warn!(
252 %id,
253 "source not found when dropping, frontend might not be notified yet"
254 );
255 return;
256 };
257 self.source_by_name.remove(&source_ref.name).unwrap();
258 if let Some(connection_id) = source_ref.connection_id
259 && let Occupied(mut e) = self.connection_source_ref.entry(connection_id)
260 {
261 let source_ids = e.get_mut();
262 source_ids.retain_mut(|sid| *sid != id);
263 if source_ids.is_empty() {
264 e.remove_entry();
265 }
266 }
267 }
268
269 pub fn update_source(&mut self, prost: &PbSource) {
270 let name = prost.name.clone();
271 let id = prost.id;
272 let source = SourceCatalog::from(prost);
273 let source_ref = Arc::new(source);
274
275 let old_source = self.source_by_id.get(&id).unwrap();
276 if old_source.name != name
278 && let Some(src) = self.source_by_name.get(&old_source.name)
279 && src.id == id
280 {
281 self.source_by_name.remove(&old_source.name);
282 }
283
284 self.source_by_name.insert(name, source_ref.clone());
285 self.source_by_id.insert(id, source_ref);
286 }
287
288 pub fn create_sink(&mut self, prost: &PbSink) {
289 let name = prost.name.clone();
290 let id = prost.id;
291 let sink = SinkCatalog::from(prost);
292 let sink_ref = Arc::new(sink);
293
294 if let Some(connection_id) = sink_ref.connection_id {
295 self.connection_sink_ref
296 .entry(connection_id)
297 .and_modify(|sinks| sinks.push(id))
298 .or_insert(vec![id]);
299 }
300
301 if let Some(target_table) = sink_ref.target_table {
302 assert!(
303 self.table_incoming_sinks
304 .entry(target_table)
305 .or_default()
306 .insert(sink_ref.id)
307 );
308 }
309
310 self.sink_by_name
311 .try_insert(name, sink_ref.clone())
312 .unwrap();
313 self.sink_by_id.try_insert(id, sink_ref).unwrap();
314 }
315
316 pub fn drop_sink(&mut self, id: SinkId) {
317 if let Some(sink_ref) = self.sink_by_id.remove(&id) {
318 self.sink_by_name.remove(&sink_ref.name).unwrap();
319 if let Some(connection_id) = sink_ref.connection_id
320 && let Occupied(mut e) = self.connection_sink_ref.entry(connection_id)
321 {
322 let sink_ids = e.get_mut();
323 sink_ids.retain_mut(|sid| *sid != id);
324 if sink_ids.is_empty() {
325 e.remove_entry();
326 }
327 }
328 if let Some(target_table) = sink_ref.target_table {
329 let incoming_sinks = self
330 .table_incoming_sinks
331 .get_mut(&target_table)
332 .expect("should exists");
333 assert!(incoming_sinks.remove(&sink_ref.id));
334 if incoming_sinks.is_empty() {
335 self.table_incoming_sinks.remove(&target_table);
336 }
337 }
338 } else {
339 tracing::warn!(
340 %id,
341 "sink not found when dropping, frontend might not be notified yet"
342 );
343 }
344 }
345
346 pub fn update_sink(&mut self, prost: &PbSink) {
347 let name = prost.name.clone();
348 let id = prost.id;
349 let sink = SinkCatalog::from(prost);
350 let sink_ref = Arc::new(sink);
351
352 let old_sink = self.sink_by_id.get(&id).unwrap();
353 assert_eq!(sink_ref.target_table, old_sink.target_table);
354 if old_sink.name != name
356 && let Some(s) = self.sink_by_name.get(&old_sink.name)
357 && s.id == id
358 {
359 self.sink_by_name.remove(&old_sink.name);
360 }
361
362 self.sink_by_name.insert(name, sink_ref.clone());
363 self.sink_by_id.insert(id, sink_ref);
364 }
365
366 pub fn table_incoming_sinks(&self, table_id: TableId) -> Option<&HashSet<SinkId>> {
367 self.table_incoming_sinks.get(&table_id)
368 }
369
370 pub fn create_subscription(&mut self, prost: &PbSubscription) {
371 let name = prost.name.clone();
372 let id = prost.id;
373 let subscription_catalog = SubscriptionCatalog::from(prost);
374 let subscription_ref = Arc::new(subscription_catalog);
375
376 self.subscription_by_name
377 .try_insert(name, subscription_ref.clone())
378 .unwrap();
379 self.subscription_by_id
380 .try_insert(id, subscription_ref)
381 .unwrap();
382 }
383
384 pub fn drop_subscription(&mut self, id: SubscriptionId) {
385 let subscription_ref = self.subscription_by_id.remove(&id);
386 if let Some(subscription_ref) = subscription_ref {
387 self.subscription_by_name.remove(&subscription_ref.name);
388 }
389 }
390
391 pub fn update_subscription(&mut self, prost: &PbSubscription) {
392 let name = prost.name.clone();
393 let id = prost.id;
394 let subscription = SubscriptionCatalog::from(prost);
395 let subscription_ref = Arc::new(subscription);
396
397 let old_subscription = self.subscription_by_id.get(&id).unwrap();
398 if old_subscription.name != name
400 && let Some(s) = self.subscription_by_name.get(&old_subscription.name)
401 && s.id == id
402 {
403 self.subscription_by_name.remove(&old_subscription.name);
404 }
405
406 self.subscription_by_name
407 .insert(name, subscription_ref.clone());
408 self.subscription_by_id.insert(id, subscription_ref);
409 }
410
411 pub fn create_view(&mut self, prost: &PbView) {
412 let name = prost.name.clone();
413 let id = prost.id;
414 let view = ViewCatalog::from(prost);
415 let view_ref = Arc::new(view);
416
417 self.view_by_name
418 .try_insert(name, view_ref.clone())
419 .unwrap();
420 self.view_by_id.try_insert(id, view_ref).unwrap();
421 }
422
423 pub fn drop_view(&mut self, id: ViewId) {
424 let view_ref = self.view_by_id.remove(&id).unwrap();
425 self.view_by_name.remove(&view_ref.name).unwrap();
426 }
427
428 pub fn update_view(&mut self, prost: &PbView) {
429 let name = prost.name.clone();
430 let id = prost.id;
431 let view = ViewCatalog::from(prost);
432 let view_ref = Arc::new(view);
433
434 let old_view = self.view_by_id.get(&id).unwrap();
435 if old_view.name != name
437 && let Some(v) = self.view_by_name.get(old_view.name())
438 && v.id == id
439 {
440 self.view_by_name.remove(&old_view.name);
441 }
442
443 self.view_by_name.insert(name, view_ref.clone());
444 self.view_by_id.insert(id, view_ref);
445 }
446
447 pub fn get_func_sign(func: &FunctionCatalog) -> FuncSign {
448 FuncSign {
449 name: FuncName::Udf(func.name.clone()),
450 inputs_type: func
451 .arg_types
452 .iter()
453 .map(|t| t.clone().into())
454 .collect_vec(),
455 variadic: false,
456 ret_type: func.return_type.clone().into(),
457 build: FuncBuilder::Udf,
458 type_infer: |_| Ok(DataType::Boolean),
460 deprecated: false,
461 }
462 }
463
464 pub fn create_function(&mut self, prost: &PbFunction) {
465 let name = prost.name.clone();
466 let id = prost.id;
467 let function = FunctionCatalog::from(prost);
468 let args = function.arg_types.clone();
469 let function_ref = Arc::new(function);
470
471 self.function_registry
472 .insert(Self::get_func_sign(&function_ref));
473 self.function_by_name
474 .entry(name)
475 .or_default()
476 .try_insert(args, function_ref.clone())
477 .expect("function already exists with same argument types");
478 self.function_by_id
479 .try_insert(id, function_ref)
480 .expect("function id exists");
481 }
482
483 pub fn drop_function(&mut self, id: FunctionId) {
484 let function_ref = self
485 .function_by_id
486 .remove(&id)
487 .expect("function not found by id");
488
489 self.function_registry
490 .remove(Self::get_func_sign(&function_ref))
491 .expect("function not found in registry");
492
493 self.function_by_name
494 .get_mut(&function_ref.name)
495 .expect("function not found by name")
496 .remove(&function_ref.arg_types)
497 .expect("function not found by argument types");
498 }
499
500 pub fn update_function(&mut self, prost: &PbFunction) {
501 let name = prost.name.clone();
502 let id = prost.id;
503 let function = FunctionCatalog::from(prost);
504 let function_ref = Arc::new(function);
505
506 let old_function_by_id = self.function_by_id.get(&id).unwrap();
507 let old_function_by_name = self
508 .function_by_name
509 .get_mut(&old_function_by_id.name)
510 .unwrap();
511 if old_function_by_id.name != name
513 && let Some(f) = old_function_by_name.get(&old_function_by_id.arg_types)
514 && f.id == id
515 {
516 old_function_by_name.remove(&old_function_by_id.arg_types);
517 if old_function_by_name.is_empty() {
518 self.function_by_name.remove(&old_function_by_id.name);
519 }
520 }
521
522 self.function_by_name
523 .entry(name)
524 .or_default()
525 .insert(old_function_by_id.arg_types.clone(), function_ref.clone());
526 self.function_by_id.insert(id, function_ref);
527 }
528
529 pub fn create_connection(&mut self, prost: &PbConnection) {
530 let name = prost.name.clone();
531 let id = prost.id;
532 let connection = ConnectionCatalog::from(prost);
533 let connection_ref = Arc::new(connection);
534 self.connection_by_name
535 .try_insert(name, connection_ref.clone())
536 .unwrap();
537 self.connection_by_id
538 .try_insert(id, connection_ref)
539 .unwrap();
540 }
541
542 pub fn update_connection(&mut self, prost: &PbConnection) {
543 let name = prost.name.clone();
544 let id = prost.id;
545 let connection = ConnectionCatalog::from(prost);
546 let connection_ref = Arc::new(connection);
547
548 let old_connection = self.connection_by_id.get(&id).unwrap();
549 if old_connection.name != name
551 && let Some(conn) = self.connection_by_name.get(&old_connection.name)
552 && conn.id == id
553 {
554 self.connection_by_name.remove(&old_connection.name);
555 }
556
557 self.connection_by_name.insert(name, connection_ref.clone());
558 self.connection_by_id.insert(id, connection_ref);
559 }
560
561 pub fn drop_connection(&mut self, connection_id: ConnectionId) {
562 let connection_ref = self
563 .connection_by_id
564 .remove(&connection_id)
565 .expect("connection not found by id");
566 self.connection_by_name
567 .remove(&connection_ref.name)
568 .expect("connection not found by name");
569 }
570
571 pub fn create_secret(&mut self, prost: &PbSecret) {
572 let name = prost.name.clone();
573 let id = prost.id;
574 let secret = SecretCatalog::from(prost);
575 let secret_ref = Arc::new(secret);
576
577 self.secret_by_id
578 .try_insert(id, secret_ref.clone())
579 .unwrap();
580 self.secret_by_name.try_insert(name, secret_ref).unwrap();
581 }
582
583 pub fn update_secret(&mut self, prost: &PbSecret) {
584 let name = prost.name.clone();
585 let id = prost.id;
586 let secret = SecretCatalog::from(prost);
587 let secret_ref = Arc::new(secret);
588
589 let old_secret = self.secret_by_id.get(&id).unwrap();
590 if old_secret.name != name
592 && let Some(s) = self.secret_by_name.get(&old_secret.name)
593 && s.id == id
594 {
595 self.secret_by_name.remove(&old_secret.name);
596 }
597
598 self.secret_by_name.insert(name, secret_ref.clone());
599 self.secret_by_id.insert(id, secret_ref);
600 }
601
602 pub fn drop_secret(&mut self, secret_id: SecretId) {
603 let secret_ref = self
604 .secret_by_id
605 .remove(&secret_id)
606 .expect("secret not found by id");
607 self.secret_by_name
608 .remove(&secret_ref.name)
609 .expect("secret not found by name");
610 }
611
612 pub fn iter_object_ids(&self) -> impl Iterator<Item = ObjectId> + '_ {
613 self.table_by_id
614 .keys()
615 .map(|id| id.as_object_id())
616 .chain(self.source_by_id.keys().map(|id| id.as_object_id()))
617 .chain(self.sink_by_id.keys().map(|id| id.as_object_id()))
618 .chain(self.subscription_by_id.keys().map(|id| id.as_object_id()))
619 .chain(self.index_by_id.keys().map(|id| id.as_object_id()))
620 .chain(self.view_by_id.keys().map(|id| id.as_object_id()))
621 .chain(self.function_by_id.keys().map(|id| id.as_object_id()))
622 .chain(self.connection_by_id.keys().map(|id| id.as_object_id()))
623 .chain(self.secret_by_id.keys().map(|id| id.as_object_id()))
624 }
625
626 pub fn iter_all(&self) -> impl Iterator<Item = &Arc<TableCatalog>> {
627 self.table_by_name.values()
628 }
629
630 pub fn iter_user_table(&self) -> impl Iterator<Item = &Arc<TableCatalog>> {
631 self.table_by_name.values().filter(|v| v.is_user_table())
632 }
633
634 pub fn iter_user_table_with_acl<'a>(
635 &'a self,
636 user: &'a UserCatalog,
637 ) -> impl Iterator<Item = &'a Arc<TableCatalog>> {
638 self.table_by_name
639 .values()
640 .filter(|v| v.is_user_table() && has_access_to_object(user, v.id, v.owner))
641 }
642
643 pub fn iter_internal_table(&self) -> impl Iterator<Item = &Arc<TableCatalog>> {
644 self.table_by_name
645 .values()
646 .filter(|v| v.is_internal_table())
647 }
648
649 pub fn iter_internal_table_with_acl<'a>(
650 &'a self,
651 user: &'a UserCatalog,
652 ) -> impl Iterator<Item = &'a Arc<TableCatalog>> {
653 self.table_by_name
654 .values()
655 .filter(|v| v.is_internal_table() && has_access_to_object(user, v.id, v.owner))
656 }
657
658 pub fn iter_table_mv_indices(&self) -> impl Iterator<Item = &Arc<TableCatalog>> {
660 self.table_by_name
661 .values()
662 .filter(|v| !v.is_internal_table())
663 }
664
665 pub fn iter_table_mv_indices_with_acl<'a>(
666 &'a self,
667 user: &'a UserCatalog,
668 ) -> impl Iterator<Item = &'a Arc<TableCatalog>> {
669 self.table_by_name
670 .values()
671 .filter(|v| !v.is_internal_table() && has_access_to_object(user, v.id, v.owner))
672 }
673
674 pub fn iter_all_mvs(&self) -> impl Iterator<Item = &Arc<TableCatalog>> {
676 self.table_by_name.values().filter(|v| v.is_mview())
677 }
678
679 pub fn iter_all_mvs_with_acl<'a>(
680 &'a self,
681 user: &'a UserCatalog,
682 ) -> impl Iterator<Item = &'a Arc<TableCatalog>> {
683 self.table_by_name
684 .values()
685 .filter(|v| v.is_mview() && has_access_to_object(user, v.id, v.owner))
686 }
687
688 pub fn iter_created_mvs(&self) -> impl Iterator<Item = &Arc<TableCatalog>> {
690 self.table_by_name
691 .values()
692 .filter(|v| v.is_mview() && v.is_created())
693 }
694
695 pub fn iter_created_mvs_with_acl<'a>(
696 &'a self,
697 user: &'a UserCatalog,
698 ) -> impl Iterator<Item = &'a Arc<TableCatalog>> {
699 self.table_by_name
700 .values()
701 .filter(|v| v.is_mview() && v.is_created() && has_access_to_object(user, v.id, v.owner))
702 }
703
704 pub fn iter_index(&self) -> impl Iterator<Item = &Arc<IndexCatalog>> {
706 self.index_by_name.values()
707 }
708
709 pub fn iter_index_with_acl<'a>(
710 &'a self,
711 user: &'a UserCatalog,
712 ) -> impl Iterator<Item = &'a Arc<IndexCatalog>> {
713 self.index_by_name
714 .values()
715 .filter(|idx| has_access_to_object(user, idx.id, idx.owner()))
716 }
717
718 pub fn iter_source(&self) -> impl Iterator<Item = &Arc<SourceCatalog>> {
720 self.source_by_name.values()
721 }
722
723 pub fn iter_source_with_acl<'a>(
724 &'a self,
725 user: &'a UserCatalog,
726 ) -> impl Iterator<Item = &'a Arc<SourceCatalog>> {
727 self.source_by_name
728 .values()
729 .filter(|s| has_access_to_object(user, s.id, s.owner))
730 }
731
732 pub fn iter_sink(&self) -> impl Iterator<Item = &Arc<SinkCatalog>> {
733 self.sink_by_name.values()
734 }
735
736 pub fn iter_sink_with_acl<'a>(
737 &'a self,
738 user: &'a UserCatalog,
739 ) -> impl Iterator<Item = &'a Arc<SinkCatalog>> {
740 self.sink_by_name
741 .values()
742 .filter(|s| has_access_to_object(user, s.id, s.owner))
743 }
744
745 pub fn iter_subscription(&self) -> impl Iterator<Item = &Arc<SubscriptionCatalog>> {
746 self.subscription_by_name.values()
747 }
748
749 pub fn iter_subscription_with_acl<'a>(
750 &'a self,
751 user: &'a UserCatalog,
752 ) -> impl Iterator<Item = &'a Arc<SubscriptionCatalog>> {
753 self.subscription_by_name
754 .values()
755 .filter(|s| has_access_to_object(user, s.id, s.owner))
756 }
757
758 pub fn iter_view(&self) -> impl Iterator<Item = &Arc<ViewCatalog>> {
759 self.view_by_name.values()
760 }
761
762 pub fn iter_view_with_acl<'a>(
763 &'a self,
764 user: &'a UserCatalog,
765 ) -> impl Iterator<Item = &'a Arc<ViewCatalog>> {
766 self.view_by_name
767 .values()
768 .filter(|v| v.is_system_view() || has_access_to_object(user, v.id, v.owner))
769 }
770
771 pub fn iter_function(&self) -> impl Iterator<Item = &Arc<FunctionCatalog>> {
772 self.function_by_name.values().flat_map(|v| v.values())
773 }
774
775 pub fn iter_function_with_acl<'a>(
776 &'a self,
777 user: &'a UserCatalog,
778 ) -> impl Iterator<Item = &'a Arc<FunctionCatalog>> {
779 self.function_by_name
780 .values()
781 .flat_map(|v| v.values())
782 .filter(|f| has_access_to_object(user, f.id, f.owner))
783 }
784
785 pub fn iter_connections(&self) -> impl Iterator<Item = &Arc<ConnectionCatalog>> {
786 self.connection_by_name.values()
787 }
788
789 pub fn iter_connections_with_acl<'a>(
790 &'a self,
791 user: &'a UserCatalog,
792 ) -> impl Iterator<Item = &'a Arc<ConnectionCatalog>> {
793 self.connection_by_name
794 .values()
795 .filter(|c| has_access_to_object(user, c.id, c.owner))
796 }
797
798 pub fn iter_secret(&self) -> impl Iterator<Item = &Arc<SecretCatalog>> {
799 self.secret_by_name.values()
800 }
801
802 pub fn iter_secret_with_acl<'a>(
803 &'a self,
804 user: &'a UserCatalog,
805 ) -> impl Iterator<Item = &'a Arc<SecretCatalog>> {
806 self.secret_by_name
807 .values()
808 .filter(|s| has_access_to_object(user, s.id, s.owner))
809 }
810
811 pub fn iter_system_tables(&self) -> impl Iterator<Item = &Arc<SystemTableCatalog>> {
812 self.system_table_by_name.values()
813 }
814
815 pub fn get_table_by_name(
816 &self,
817 table_name: &str,
818 bind_creating_relations: bool,
819 ) -> Option<&Arc<TableCatalog>> {
820 self.table_by_name
821 .get(table_name)
822 .filter(|&table| bind_creating_relations || table.is_created())
823 }
824
825 pub fn get_any_table_by_name(&self, table_name: &str) -> Option<&Arc<TableCatalog>> {
826 self.get_table_by_name(table_name, true)
827 }
828
829 pub fn get_created_table_by_name(&self, table_name: &str) -> Option<&Arc<TableCatalog>> {
830 self.get_table_by_name(table_name, false)
831 }
832
833 pub fn get_table_by_id(&self, table_id: TableId) -> Option<&Arc<TableCatalog>> {
834 self.table_by_id.get(&table_id)
835 }
836
837 pub fn get_created_table_by_id(&self, table_id: TableId) -> Option<&Arc<TableCatalog>> {
838 self.table_by_id
839 .get(&table_id)
840 .filter(|&table| table.stream_job_status == StreamJobStatus::Created)
841 }
842
843 pub fn get_view_by_name(&self, view_name: &str) -> Option<&Arc<ViewCatalog>> {
844 self.view_by_name.get(view_name)
845 }
846
847 pub fn get_view_by_id(&self, view_id: ViewId) -> Option<&Arc<ViewCatalog>> {
848 self.view_by_id.get(&view_id)
849 }
850
851 pub fn get_source_by_name(&self, source_name: &str) -> Option<&Arc<SourceCatalog>> {
852 self.source_by_name.get(source_name)
853 }
854
855 pub fn get_source_by_id(&self, source_id: SourceId) -> Option<&Arc<SourceCatalog>> {
856 self.source_by_id.get(&source_id)
857 }
858
859 pub fn get_sink_by_name(
860 &self,
861 sink_name: &str,
862 bind_creating: bool,
863 ) -> Option<&Arc<SinkCatalog>> {
864 self.sink_by_name
865 .get(sink_name)
866 .filter(|s| bind_creating || s.is_created())
867 }
868
869 pub fn get_any_sink_by_name(&self, sink_name: &str) -> Option<&Arc<SinkCatalog>> {
870 self.get_sink_by_name(sink_name, true)
871 }
872
873 pub fn get_created_sink_by_name(&self, sink_name: &str) -> Option<&Arc<SinkCatalog>> {
874 self.get_sink_by_name(sink_name, false)
875 }
876
877 pub fn get_sink_by_id(&self, sink_id: SinkId) -> Option<&Arc<SinkCatalog>> {
878 self.sink_by_id.get(&sink_id)
879 }
880
881 pub fn get_subscription_by_name(
882 &self,
883 subscription_name: &str,
884 ) -> Option<&Arc<SubscriptionCatalog>> {
885 self.subscription_by_name.get(subscription_name)
886 }
887
888 pub fn get_subscription_by_id(
889 &self,
890 subscription_id: SubscriptionId,
891 ) -> Option<&Arc<SubscriptionCatalog>> {
892 self.subscription_by_id.get(&subscription_id)
893 }
894
895 pub fn get_index_by_name(
896 &self,
897 index_name: &str,
898 bind_creating: bool,
899 ) -> Option<&Arc<IndexCatalog>> {
900 self.index_by_name
901 .get(index_name)
902 .filter(|i| bind_creating || i.is_created())
903 }
904
905 pub fn get_any_index_by_name(&self, index_name: &str) -> Option<&Arc<IndexCatalog>> {
906 self.get_index_by_name(index_name, true)
907 }
908
909 pub fn get_created_index_by_name(&self, index_name: &str) -> Option<&Arc<IndexCatalog>> {
910 self.get_index_by_name(index_name, false)
911 }
912
913 pub fn get_index_by_id(&self, index_id: IndexId) -> Option<&Arc<IndexCatalog>> {
914 self.index_by_id.get(&index_id)
915 }
916
917 pub fn get_indexes_by_table_id(
918 &self,
919 table_id: TableId,
920 include_creating: bool,
921 ) -> Vec<Arc<IndexCatalog>> {
922 self.indexes_by_table_id
923 .get(&table_id)
924 .cloned()
925 .unwrap_or_default()
926 .into_iter()
927 .filter(|i| include_creating || i.is_created())
928 .collect()
929 }
930
931 pub fn get_any_indexes_by_table_id(&self, table_id: TableId) -> Vec<Arc<IndexCatalog>> {
932 self.get_indexes_by_table_id(table_id, true)
933 }
934
935 pub fn get_created_indexes_by_table_id(&self, table_id: TableId) -> Vec<Arc<IndexCatalog>> {
936 self.get_indexes_by_table_id(table_id, false)
937 }
938
939 pub fn get_system_table_by_name(&self, table_name: &str) -> Option<&Arc<SystemTableCatalog>> {
940 self.system_table_by_name.get(table_name)
941 }
942
943 pub fn get_table_name_by_id(&self, table_id: TableId) -> Option<String> {
944 self.table_by_id
945 .get(&table_id)
946 .map(|table| table.name.clone())
947 }
948
949 pub fn get_function_by_id(&self, function_id: FunctionId) -> Option<&Arc<FunctionCatalog>> {
950 self.function_by_id.get(&function_id)
951 }
952
953 pub fn get_function_by_name_inputs(
954 &self,
955 name: &str,
956 inputs: &mut [ExprImpl],
957 ) -> Option<&Arc<FunctionCatalog>> {
958 infer_type_with_sigmap(
959 FuncName::Udf(name.to_owned()),
960 inputs,
961 &self.function_registry,
962 )
963 .ok()?;
964 let args = inputs.iter().map(|x| x.return_type()).collect_vec();
965 self.function_by_name.get(name)?.get(&args)
966 }
967
968 pub fn get_function_by_name_args(
969 &self,
970 name: &str,
971 args: &[DataType],
972 ) -> Option<&Arc<FunctionCatalog>> {
973 let args = args.iter().map(|x| Some(x.clone())).collect_vec();
974 let func = infer_type_name(
975 &self.function_registry,
976 FuncName::Udf(name.to_owned()),
977 &args,
978 )
979 .ok()?;
980
981 let args = func
982 .inputs_type
983 .iter()
984 .filter_map(|x| {
985 if let SigDataType::Exact(t) = x {
986 Some(t.clone())
987 } else {
988 None
989 }
990 })
991 .collect_vec();
992
993 self.function_by_name.get(name)?.get(&args)
994 }
995
996 pub fn get_functions_by_name(&self, name: &str) -> Option<Vec<&Arc<FunctionCatalog>>> {
997 let functions = self.function_by_name.get(name)?;
998 if functions.is_empty() {
999 return None;
1000 }
1001 Some(functions.values().collect())
1002 }
1003
1004 pub fn get_connection_by_id(
1005 &self,
1006 connection_id: ConnectionId,
1007 ) -> Option<&Arc<ConnectionCatalog>> {
1008 self.connection_by_id.get(&connection_id)
1009 }
1010
1011 pub fn get_connection_by_name(&self, connection_name: &str) -> Option<&Arc<ConnectionCatalog>> {
1012 self.connection_by_name.get(connection_name)
1013 }
1014
1015 pub fn get_secret_by_name(&self, secret_name: &str) -> Option<&Arc<SecretCatalog>> {
1016 self.secret_by_name.get(secret_name)
1017 }
1018
1019 pub fn get_secret_by_id(&self, secret_id: SecretId) -> Option<&Arc<SecretCatalog>> {
1020 self.secret_by_id.get(&secret_id)
1021 }
1022
1023 pub fn get_source_ids_by_connection(
1025 &self,
1026 connection_id: ConnectionId,
1027 ) -> Option<Vec<SourceId>> {
1028 self.connection_source_ref
1029 .get(&connection_id)
1030 .map(|c| c.to_owned())
1031 }
1032
1033 pub fn get_sink_ids_by_connection(&self, connection_id: ConnectionId) -> Option<Vec<SinkId>> {
1035 self.connection_sink_ref
1036 .get(&connection_id)
1037 .map(|s| s.to_owned())
1038 }
1039
1040 pub fn get_grant_object_by_oid(&self, oid: ObjectId) -> Option<OwnedGrantObject> {
1041 #[expect(clippy::manual_map)]
1042 if let Some(table) = self.get_created_table_by_id(oid.as_table_id()) {
1043 Some(OwnedGrantObject {
1044 owner: table.owner,
1045 object: Object::TableId(oid.as_table_id()),
1046 })
1047 } else if let Some(index) = self.get_index_by_id(oid.as_index_id()) {
1048 Some(OwnedGrantObject {
1049 owner: index.owner(),
1050 object: Object::TableId(oid.as_table_id()),
1051 })
1052 } else if let Some(source) = self.get_source_by_id(oid.as_source_id()) {
1053 Some(OwnedGrantObject {
1054 owner: source.owner,
1055 object: Object::SourceId(oid.as_source_id()),
1056 })
1057 } else if let Some(sink) = self.get_sink_by_id(oid.as_sink_id()) {
1058 Some(OwnedGrantObject {
1059 owner: sink.owner,
1060 object: Object::SinkId(oid.as_sink_id()),
1061 })
1062 } else if let Some(view) = self.get_view_by_id(oid.as_view_id()) {
1063 Some(OwnedGrantObject {
1064 owner: view.owner,
1065 object: Object::ViewId(oid.as_view_id()),
1066 })
1067 } else if let Some(function) = self.get_function_by_id(oid.as_function_id()) {
1068 Some(OwnedGrantObject {
1069 owner: function.owner(),
1070 object: Object::FunctionId(oid.as_function_id()),
1071 })
1072 } else if let Some(subscription) = self.get_subscription_by_id(oid.as_subscription_id()) {
1073 Some(OwnedGrantObject {
1074 owner: subscription.owner,
1075 object: Object::SubscriptionId(oid.as_subscription_id()),
1076 })
1077 } else if let Some(connection) = self.get_connection_by_id(oid.as_connection_id()) {
1078 Some(OwnedGrantObject {
1079 owner: connection.owner,
1080 object: Object::ConnectionId(oid.as_connection_id()),
1081 })
1082 } else if let Some(secret) = self.get_secret_by_id(oid.as_secret_id()) {
1083 Some(OwnedGrantObject {
1084 owner: secret.owner,
1085 object: Object::SecretId(oid.as_secret_id()),
1086 })
1087 } else {
1088 None
1089 }
1090 }
1091
1092 pub fn contains_object(&self, oid: ObjectId) -> bool {
1093 self.table_by_id.contains_key(&oid.as_table_id())
1094 || self.index_by_id.contains_key(&oid.as_index_id())
1095 || self.source_by_id.contains_key(&oid.as_source_id())
1096 || self.sink_by_id.contains_key(&oid.as_sink_id())
1097 || self.view_by_id.contains_key(&oid.as_view_id())
1098 || self.function_by_id.contains_key(&oid.as_function_id())
1099 || self
1100 .subscription_by_id
1101 .contains_key(&oid.as_subscription_id())
1102 || self.connection_by_id.contains_key(&oid.as_connection_id())
1103 }
1104
1105 pub fn id(&self) -> SchemaId {
1106 self.id
1107 }
1108
1109 pub fn database_id(&self) -> DatabaseId {
1110 self.database_id
1111 }
1112
1113 pub fn name(&self) -> String {
1114 self.name.clone()
1115 }
1116}
1117
1118impl OwnedByUserCatalog for SchemaCatalog {
1119 fn owner(&self) -> UserId {
1120 self.owner
1121 }
1122}
1123
1124impl From<&PbSchema> for SchemaCatalog {
1125 fn from(schema: &PbSchema) -> Self {
1126 Self {
1127 id: schema.id,
1128 owner: schema.owner,
1129 name: schema.name.clone(),
1130 database_id: schema.database_id,
1131 table_by_name: HashMap::new(),
1132 table_by_id: HashMap::new(),
1133 source_by_name: HashMap::new(),
1134 source_by_id: HashMap::new(),
1135 sink_by_name: HashMap::new(),
1136 sink_by_id: HashMap::new(),
1137 table_incoming_sinks: HashMap::new(),
1138 index_by_name: HashMap::new(),
1139 index_by_id: HashMap::new(),
1140 indexes_by_table_id: HashMap::new(),
1141 system_table_by_name: HashMap::new(),
1142 view_by_name: HashMap::new(),
1143 view_by_id: HashMap::new(),
1144 function_registry: FunctionRegistry::default(),
1145 function_by_name: HashMap::new(),
1146 function_by_id: HashMap::new(),
1147 connection_by_name: HashMap::new(),
1148 connection_by_id: HashMap::new(),
1149 secret_by_name: HashMap::new(),
1150 secret_by_id: HashMap::new(),
1151 _secret_source_ref: HashMap::new(),
1152 _secret_sink_ref: HashMap::new(),
1153 connection_source_ref: HashMap::new(),
1154 connection_sink_ref: HashMap::new(),
1155 subscription_by_name: HashMap::new(),
1156 subscription_by_id: HashMap::new(),
1157 }
1158 }
1159}
1160
1161#[cfg(test)]
1162mod tests {
1163 use risingwave_pb::catalog::PbSchema;
1164
1165 use super::SchemaCatalog;
1166
1167 #[test]
1168 fn test_drop_missing_relation_is_idempotent() {
1169 let mut schema = SchemaCatalog::from(&PbSchema::default());
1170 schema.drop_index(1.into());
1171 schema.drop_source(2.into());
1172 }
1173}