risingwave_meta/controller/catalog/
list_op.rs1use risingwave_common::catalog::FragmentTypeMask;
16use risingwave_common::id::JobId;
17use risingwave_meta_model::refresh_job::{self, RefreshState};
18use risingwave_pb::meta::ObjectDependency as PbObjectDependency;
19use sea_orm::prelude::DateTime;
20
21use super::*;
22use crate::controller::fragment::FragmentTypeMaskExt;
23use crate::controller::utils::load_streaming_jobs_by_ids;
24
25impl CatalogController {
26 pub async fn list_time_travel_table_ids(&self) -> MetaResult<Vec<TableId>> {
27 self.inner.read().await.list_time_travel_table_ids().await
28 }
29
30 pub async fn list_refresh_jobs(&self) -> MetaResult<Vec<refresh_job::Model>> {
31 let inner = self.inner.read().await;
32 Ok(RefreshJob::find().all(&inner.db).await?)
33 }
34
35 pub async fn list_refreshing_jobs(
37 &self,
38 database_id: Option<DatabaseId>,
39 ) -> MetaResult<Vec<refresh_job::Model>> {
40 let inner = self.inner.read().await;
41 let database_cond = database_id
42 .map(|database_id| object::Column::DatabaseId.eq(database_id))
43 .unwrap_or_else(|| SimpleExpr::from(true));
44 Ok(RefreshJob::find()
45 .join(JoinType::InnerJoin, refresh_job::Relation::Table.def())
46 .join(JoinType::InnerJoin, table::Relation::Object1.def())
47 .filter(
48 refresh_job::Column::CurrentStatus
49 .ne(RefreshState::Idle)
50 .and(database_cond),
51 )
52 .all(&inner.db)
53 .await?)
54 }
55
56 pub async fn get_refresh_job_state(
58 &self,
59 table_id: TableId,
60 ) -> MetaResult<Option<RefreshState>> {
61 let inner = self.inner.read().await;
62 let state: Option<(RefreshState,)> = RefreshJob::find_by_id(table_id)
63 .select_only()
64 .select_column(refresh_job::Column::CurrentStatus)
65 .into_tuple()
66 .one(&inner.db)
67 .await?;
68 Ok(state.map(|(state,)| state))
69 }
70
71 pub async fn list_refreshable_table_ids(&self) -> MetaResult<Vec<TableId>> {
72 let inner = self.inner.read().await;
73 Ok(Table::find()
74 .select_only()
75 .column(table::Column::TableId)
76 .filter(table::Column::Refreshable.eq(true))
77 .into_tuple()
78 .all(&inner.db)
79 .await?)
80 }
81
82 pub async fn list_stream_job_desc_for_telemetry(
83 &self,
84 ) -> MetaResult<Vec<MetaTelemetryJobDesc>> {
85 let inner = self.inner.read().await;
86 let info: Vec<(TableId, Option<Property>)> = Table::find()
87 .select_only()
88 .column(table::Column::TableId)
89 .column(source::Column::WithProperties)
90 .join(JoinType::LeftJoin, table::Relation::Source.def())
91 .filter(
92 table::Column::TableType
93 .eq(TableType::Table)
94 .or(table::Column::TableType.eq(TableType::MaterializedView)),
95 )
96 .into_tuple()
97 .all(&inner.db)
98 .await?;
99
100 Ok(info
101 .into_iter()
102 .map(|(table_id, properties)| {
103 let connector_info = if let Some(inner_props) = properties {
104 inner_props
105 .inner_ref()
106 .get(UPSTREAM_SOURCE_KEY)
107 .map(|v| v.to_lowercase())
108 } else {
109 None
110 };
111 MetaTelemetryJobDesc {
112 table_id,
113 connector: connector_info,
114 optimization: vec![],
115 }
116 })
117 .collect())
118 }
119
120 pub async fn list_creating_jobs(
121 &self,
122 include_initial: bool,
123 database_id: Option<DatabaseId>,
124 ) -> MetaResult<Vec<(JobId, String, DateTime, CreateType, bool)>> {
125 let inner = self.inner.read().await;
126 let status_cond = if include_initial {
127 streaming_job::Column::JobStatus.is_in([JobStatus::Initial, JobStatus::Creating])
128 } else {
129 streaming_job::Column::JobStatus.eq(JobStatus::Creating)
130 };
131 let database_cond = database_id
132 .map(|database_id| object::Column::DatabaseId.eq(database_id))
133 .unwrap_or_else(|| SimpleExpr::from(true));
134 let filter_cond = status_cond.and(database_cond);
135 let object_columns = [object::Column::InitializedAt];
136 let streaming_job_columns = [
137 streaming_job::Column::CreateType,
138 streaming_job::Column::IsServerlessBackfill,
139 ];
140 let mut table_info: Vec<(JobId, String, DateTime, CreateType, bool)> = Table::find()
141 .select_only()
142 .columns([table::Column::TableId, table::Column::Definition])
143 .columns(object_columns)
144 .columns(streaming_job_columns)
145 .join(JoinType::LeftJoin, table::Relation::Object1.def())
146 .join(JoinType::LeftJoin, object::Relation::StreamingJob.def())
147 .filter(filter_cond.clone())
148 .into_tuple()
149 .all(&inner.db)
150 .await?;
151 let sink_info: Vec<(JobId, String, DateTime, CreateType, bool)> = Sink::find()
152 .select_only()
153 .columns([sink::Column::SinkId, sink::Column::Definition])
154 .columns(object_columns)
155 .columns(streaming_job_columns)
156 .join(JoinType::LeftJoin, sink::Relation::Object.def())
157 .join(JoinType::LeftJoin, object::Relation::StreamingJob.def())
158 .filter(filter_cond)
159 .into_tuple()
160 .all(&inner.db)
161 .await?;
162
163 table_info.extend(sink_info);
164
165 Ok(table_info)
166 }
167
168 pub async fn list_databases(&self) -> MetaResult<Vec<PbDatabase>> {
169 let inner = self.inner.read().await;
170 inner.list_databases().await
171 }
172
173 pub async fn list_all_object_dependencies(&self) -> MetaResult<Vec<PbObjectDependency>> {
174 let inner = self.inner.read().await;
175 let txn = inner.db.begin().await?;
176 let dependencies = list_object_dependencies(&txn, true).await?;
177 txn.commit().await?;
178 Ok(dependencies)
179 }
180
181 pub async fn list_created_object_dependencies(&self) -> MetaResult<Vec<PbObjectDependency>> {
182 let inner = self.inner.read().await;
183 let txn = inner.db.begin().await?;
184 let dependencies = list_object_dependencies(&txn, false).await?;
185 txn.commit().await?;
186 Ok(dependencies)
187 }
188
189 pub async fn list_schemas(&self) -> MetaResult<Vec<PbSchema>> {
190 let inner = self.inner.read().await;
191 inner.list_schemas().await
192 }
193
194 pub async fn list_all_state_tables(&self) -> MetaResult<Vec<PbTable>> {
196 let inner = self.inner.read().await;
197 inner.list_all_state_tables().await
198 }
199
200 pub async fn list_readonly_table_ids(&self, schema_id: SchemaId) -> MetaResult<Vec<TableId>> {
201 let inner = self.inner.read().await;
202 let table_ids: Vec<TableId> = Table::find()
203 .select_only()
204 .column(table::Column::TableId)
205 .join(JoinType::InnerJoin, table::Relation::Object1.def())
206 .filter(
207 object::Column::SchemaId
208 .eq(schema_id)
209 .and(table::Column::TableType.ne(TableType::Table)),
210 )
211 .into_tuple()
212 .all(&inner.db)
213 .await?;
214 Ok(table_ids)
215 }
216
217 pub async fn list_dml_table_ids(&self, schema_id: SchemaId) -> MetaResult<Vec<TableId>> {
218 let inner = self.inner.read().await;
219 let table_ids: Vec<TableId> = Table::find()
220 .select_only()
221 .column(table::Column::TableId)
222 .join(JoinType::InnerJoin, table::Relation::Object1.def())
223 .filter(
224 object::Column::SchemaId
225 .eq(schema_id)
226 .and(table::Column::TableType.eq(TableType::Table)),
227 )
228 .into_tuple()
229 .all(&inner.db)
230 .await?;
231 Ok(table_ids)
232 }
233
234 pub async fn list_view_ids(&self, schema_id: SchemaId) -> MetaResult<Vec<ViewId>> {
235 let inner = self.inner.read().await;
236 let view_ids: Vec<ViewId> = View::find()
237 .select_only()
238 .column(view::Column::ViewId)
239 .join(JoinType::InnerJoin, view::Relation::Object.def())
240 .filter(object::Column::SchemaId.eq(schema_id))
241 .into_tuple()
242 .all(&inner.db)
243 .await?;
244 Ok(view_ids)
245 }
246
247 pub async fn list_tables_by_type(&self, table_type: TableType) -> MetaResult<Vec<PbTable>> {
249 let inner = self.inner.read().await;
250 let table_objs = Table::find()
251 .find_also_related(Object)
252 .filter(table::Column::TableType.eq(table_type))
253 .all(&inner.db)
254 .await?;
255 let streaming_jobs = load_streaming_jobs_by_ids(
256 &inner.db,
257 table_objs.iter().map(|(table, _)| table.job_id()),
258 )
259 .await?;
260 Ok(table_objs
261 .into_iter()
262 .map(|(table, obj)| {
263 let job_id = table.job_id();
264 let streaming_job = streaming_jobs.get(&job_id).cloned();
265 ObjectModel(table, obj.unwrap(), streaming_job).into()
266 })
267 .collect())
268 }
269
270 pub async fn list_sources(&self) -> MetaResult<Vec<PbSource>> {
271 let inner = self.inner.read().await;
272 inner.list_sources().await
273 }
274
275 pub async fn list_source_id_with_shared_types(&self) -> MetaResult<HashMap<SourceId, bool>> {
277 let inner = self.inner.read().await;
278 let source_ids: Vec<(SourceId, Option<StreamSourceInfo>)> = Source::find()
279 .select_only()
280 .columns([source::Column::SourceId, source::Column::SourceInfo])
281 .into_tuple()
282 .all(&inner.db)
283 .await?;
284
285 Ok(source_ids
286 .into_iter()
287 .map(|(source_id, info)| {
288 (
289 source_id,
290 info.map(|info| info.to_protobuf().cdc_source_job)
291 .unwrap_or(false),
292 )
293 })
294 .collect())
295 }
296
297 pub async fn list_connections(&self) -> MetaResult<Vec<PbConnection>> {
298 let inner = self.inner.read().await;
299 let conn_objs = Connection::find()
300 .find_also_related(Object)
301 .all(&inner.db)
302 .await?;
303 Ok(conn_objs
304 .into_iter()
305 .map(|(conn, obj)| ObjectModel(conn, obj.unwrap(), None).into())
306 .collect())
307 }
308
309 pub async fn list_source_ids(&self, schema_id: SchemaId) -> MetaResult<Vec<SourceId>> {
310 let inner = self.inner.read().await;
311 let source_ids: Vec<SourceId> = Source::find()
312 .select_only()
313 .column(source::Column::SourceId)
314 .join(JoinType::InnerJoin, source::Relation::Object.def())
315 .filter(object::Column::SchemaId.eq(schema_id))
316 .into_tuple()
317 .all(&inner.db)
318 .await?;
319 Ok(source_ids)
320 }
321
322 pub async fn list_indexes(&self) -> MetaResult<Vec<PbIndex>> {
323 let inner = self.inner.read().await;
324 inner.list_indexes().await
325 }
326
327 pub async fn list_sinks(&self) -> MetaResult<Vec<PbSink>> {
328 let inner = self.inner.read().await;
329 inner.list_sinks().await
330 }
331
332 pub async fn list_subscriptions(&self) -> MetaResult<Vec<PbSubscription>> {
333 let inner = self.inner.read().await;
334 inner.list_subscriptions().await
335 }
336
337 pub async fn list_views(&self) -> MetaResult<Vec<PbView>> {
338 let inner = self.inner.read().await;
339 inner.list_views().await
340 }
341
342 pub async fn list_users(&self) -> MetaResult<Vec<PbUserInfo>> {
343 let inner = self.inner.read().await;
344 inner.list_users().await
345 }
346
347 pub async fn list_functions(&self) -> MetaResult<Vec<PbFunction>> {
348 let inner = self.inner.read().await;
349 inner.list_functions().await
350 }
351
352 pub async fn list_unmigrated_tables(&self) -> MetaResult<Vec<PbTable>> {
355 let inner = self.inner.read().await;
356
357 let table_objs = Table::find()
358 .filter(table::Column::TableType.eq(TableType::Table))
359 .find_also_related(Object)
360 .join(JoinType::InnerJoin, object::Relation::Fragment.def())
361 .filter(FragmentTypeMask::intersects(FragmentTypeFlag::Mview).and(
362 FragmentTypeMask::disjoint(FragmentTypeFlag::UpstreamSinkUnion),
363 ))
364 .all(&inner.db)
365 .await?;
366 let streaming_jobs = load_streaming_jobs_by_ids(
367 &inner.db,
368 table_objs.iter().map(|(table, _)| table.job_id()),
369 )
370 .await?;
371
372 Ok(table_objs
373 .into_iter()
374 .map(|(table, obj)| {
375 let job_id = table.job_id();
376 let streaming_job = streaming_jobs.get(&job_id).cloned();
377 ObjectModel(table, obj.unwrap(), streaming_job).into()
378 })
379 .collect())
380 }
381
382 pub async fn list_sink_ids(&self, database_id: Option<DatabaseId>) -> MetaResult<Vec<SinkId>> {
383 let inner = self.inner.read().await;
384
385 let mut query = Sink::find().select_only().column(sink::Column::SinkId);
386
387 if let Some(database_id) = database_id {
388 query = query
389 .join(JoinType::InnerJoin, sink::Relation::Object.def())
390 .filter(object::Column::DatabaseId.eq(database_id));
391 }
392
393 let sink_ids: Vec<SinkId> = query.into_tuple().all(&inner.db).await?;
394
395 Ok(sink_ids)
396 }
397}