1use std::pin::Pin;
16use std::sync::Arc;
17use std::task::{Context, Poll};
18
19use futures::stream::{self, BoxStream};
20use futures::{Stream, StreamExt};
21use itertools::Itertools;
22use pgwire::pg_field_descriptor::PgFieldDescriptor;
23use pgwire::pg_response::StatementType::{self, ABORT, BEGIN, COMMIT, ROLLBACK, START_TRANSACTION};
24use pgwire::pg_response::{PgResponse, PgResponseBuilder, RowSetResult};
25use pgwire::pg_server::BoxedError;
26use pgwire::types::{Format, Row};
27use risingwave_common::catalog::{AlterDatabaseParam, ICEBERG_SINK_PREFIX};
28use risingwave_common::types::Fields;
29use risingwave_common::util::iter_util::ZipEqFast;
30use risingwave_common::{bail, bail_not_implemented};
31use risingwave_pb::meta::PbThrottleTarget;
32use risingwave_sqlparser::ast::*;
33use thiserror_ext::AsReport;
34use util::get_table_catalog_by_table_name;
35
36use self::util::{DataChunkToRowSetAdapter, SourceSchemaCompatExt};
37use crate::catalog::table_catalog::TableType;
38use crate::error::{ErrorCode, Result};
39use crate::handler::cancel_job::handle_cancel;
40use crate::handler::kill_process::handle_kill;
41use crate::scheduler::{DistributedQueryStream, LocalQueryStream};
42use crate::session::SessionImpl;
43use crate::utils::WithOptions;
44
45mod alter_compaction_group;
46mod alter_connection_props;
47mod alter_database_param;
48mod alter_mv;
49mod alter_owner;
50mod alter_parallelism;
51mod alter_rename;
52mod alter_resource_group;
53mod alter_secret;
54mod alter_set_schema;
55mod alter_sink_props;
56mod alter_source_column;
57mod alter_source_props;
58mod alter_source_with_sr;
59mod alter_streaming_config;
60mod alter_streaming_enable_unaligned_join;
61mod alter_streaming_rate_limit;
62mod alter_subscription_retention;
63mod alter_swap_rename;
64mod alter_system;
65mod alter_table_column;
66pub mod alter_table_drop_connector;
67pub mod alter_table_props;
68mod alter_table_with_sr;
69pub mod alter_user;
70mod alter_utils;
71mod alter_watermark;
72mod backup;
73pub mod cancel_job;
74pub mod close_cursor;
75mod comment;
76pub mod create_aggregate;
77pub mod create_connection;
78mod create_database;
79pub mod create_function;
80pub mod create_index;
81pub mod create_mv;
82pub mod create_schema;
83pub mod create_secret;
84pub mod create_sink;
85pub mod create_source;
86pub mod create_sql_function;
87pub mod create_subscription;
88pub mod create_table;
89pub mod create_table_as;
90pub mod create_user;
91pub mod create_view;
92pub mod declare_cursor;
93mod delete_meta_snapshot;
94pub mod describe;
95pub mod discard;
96mod drop_connection;
97mod drop_database;
98pub mod drop_function;
99mod drop_index;
100pub mod drop_mv;
101mod drop_schema;
102pub mod drop_secret;
103pub mod drop_sink;
104pub mod drop_source;
105pub mod drop_subscription;
106pub mod drop_table;
107pub mod drop_user;
108mod drop_view;
109pub mod explain;
110pub mod explain_analyze_stream_job;
111pub mod extended_handle;
112pub mod fetch_cursor;
113mod flush;
114pub mod handle_privilege;
115pub mod kill_process;
116mod prepared_statement;
117pub mod privilege;
118pub mod query;
119mod recover;
120mod refresh;
121mod reset_source;
122pub mod show;
123mod transaction;
124mod use_db;
125pub mod util;
126pub mod vacuum;
127pub mod variable;
128mod wait;
129
130pub use alter_table_column::{
131 fetch_table_catalog_for_alter, get_new_table_definition_for_cdc_table, get_replace_table_plan,
132};
133
134pub type RwPgResponseBuilder = PgResponseBuilder<PgResponseStream>;
136
137pub type RwPgResponse = PgResponse<PgResponseStream>;
139
140#[easy_ext::ext(RwPgResponseBuilderExt)]
141impl RwPgResponseBuilder {
142 pub fn rows<T: Fields>(self, rows: impl IntoIterator<Item = T>) -> Self {
144 let fields = T::fields();
145 self.values(
146 rows.into_iter()
147 .map(|row| {
148 Row::new(
149 row.into_owned_row()
150 .into_iter()
151 .zip_eq_fast(&fields)
152 .map(|(datum, (_, ty))| {
153 datum.map(|scalar| {
154 scalar.as_scalar_ref_impl().text_format(ty).into()
155 })
156 })
157 .collect(),
158 )
159 })
160 .collect_vec()
161 .into(),
162 fields_to_descriptors(fields),
163 )
164 }
165}
166
167pub fn fields_to_descriptors(
168 fields: Vec<(&str, risingwave_common::types::DataType)>,
169) -> Vec<PgFieldDescriptor> {
170 fields
171 .iter()
172 .map(|(name, ty)| PgFieldDescriptor::new(name.to_string(), ty.to_oid(), ty.type_len()))
173 .collect()
174}
175
176pub enum PgResponseStream {
177 LocalQuery(DataChunkToRowSetAdapter<LocalQueryStream>),
178 DistributedQuery(DataChunkToRowSetAdapter<DistributedQueryStream>),
179 Rows(BoxStream<'static, RowSetResult>),
180}
181
182impl Stream for PgResponseStream {
183 type Item = std::result::Result<Vec<Row>, BoxedError>;
184
185 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
186 match &mut *self {
187 PgResponseStream::LocalQuery(inner) => inner.poll_next_unpin(cx),
188 PgResponseStream::DistributedQuery(inner) => inner.poll_next_unpin(cx),
189 PgResponseStream::Rows(inner) => inner.poll_next_unpin(cx),
190 }
191 }
192}
193
194impl From<Vec<Row>> for PgResponseStream {
195 fn from(rows: Vec<Row>) -> Self {
196 Self::Rows(stream::iter(vec![Ok(rows)]).boxed())
197 }
198}
199
200#[derive(Clone)]
201pub struct HandlerArgs {
202 pub session: Arc<SessionImpl>,
203 pub sql: Arc<str>,
204 pub normalized_sql: String,
205 pub with_options: WithOptions,
206}
207
208impl HandlerArgs {
209 pub fn new(session: Arc<SessionImpl>, stmt: &Statement, sql: Arc<str>) -> Result<Self> {
210 Ok(Self {
211 session,
212 sql,
213 with_options: WithOptions::try_from(stmt)?,
214 normalized_sql: Self::normalize_sql(stmt),
215 })
216 }
217
218 fn normalize_sql(stmt: &Statement) -> String {
224 let mut stmt = stmt.clone();
225 match &mut stmt {
226 Statement::CreateView {
227 or_replace,
228 if_not_exists,
229 ..
230 } => {
231 *or_replace = false;
232 *if_not_exists = false;
233 }
234 Statement::CreateTable {
235 or_replace,
236 if_not_exists,
237 ..
238 } => {
239 *or_replace = false;
240 *if_not_exists = false;
241 }
242 Statement::CreateIndex { if_not_exists, .. } => {
243 *if_not_exists = false;
244 }
245 Statement::CreateSource {
246 stmt: CreateSourceStatement { if_not_exists, .. },
247 ..
248 } => {
249 *if_not_exists = false;
250 }
251 Statement::CreateSink {
252 stmt:
253 CreateSinkStatement {
254 or_replace,
255 if_not_exists,
256 ..
257 },
258 } => {
259 *or_replace = false;
260 *if_not_exists = false;
261 }
262 Statement::CreateSubscription {
263 stmt: CreateSubscriptionStatement { if_not_exists, .. },
264 } => {
265 *if_not_exists = false;
266 }
267 Statement::CreateConnection {
268 stmt: CreateConnectionStatement { if_not_exists, .. },
269 } => {
270 *if_not_exists = false;
271 }
272 _ => {}
273 }
274 stmt.to_string()
275 }
276}
277
278pub async fn handle(
279 session: Arc<SessionImpl>,
280 stmt: Statement,
281 sql: Arc<str>,
282 formats: Vec<Format>,
283) -> Result<RwPgResponse> {
284 session.clear_cancel_query_flag();
285 let _guard = session.txn_begin_implicit();
286 let handler_args = HandlerArgs::new(session, &stmt, sql)?;
287
288 check_ban_ddl_for_iceberg_engine_table(handler_args.session.clone(), &stmt)?;
289
290 match stmt {
291 Statement::Explain {
292 statement,
293 analyze,
294 options,
295 } => {
296 Box::pin(explain::handle_explain(
297 handler_args,
298 *statement,
299 options,
300 analyze,
301 ))
302 .await
303 }
304 Statement::ExplainAnalyzeStreamJob {
305 target,
306 duration_secs,
307 } => {
308 explain_analyze_stream_job::handle_explain_analyze_stream_job(
309 handler_args,
310 target,
311 duration_secs,
312 )
313 .await
314 }
315 Statement::CreateSource { stmt } => {
316 create_source::handle_create_source(handler_args, stmt).await
317 }
318 Statement::CreateSink { stmt } => {
319 create_sink::handle_create_sink(handler_args, stmt, false).await
320 }
321 Statement::CreateSubscription { stmt } => {
322 create_subscription::handle_create_subscription(handler_args, stmt).await
323 }
324 Statement::CreateConnection { stmt } => {
325 create_connection::handle_create_connection(handler_args, stmt).await
326 }
327 Statement::CreateSecret { stmt } => {
328 create_secret::handle_create_secret(handler_args, stmt).await
329 }
330 Statement::CreateFunction {
331 or_replace,
332 temporary,
333 if_not_exists,
334 name,
335 args,
336 returns,
337 params,
338 with_options,
339 } => {
340 if params.language.is_none()
343 || !params
344 .language
345 .as_ref()
346 .unwrap()
347 .real_value()
348 .eq_ignore_ascii_case("sql")
349 {
350 create_function::handle_create_function(
351 handler_args,
352 or_replace,
353 temporary,
354 if_not_exists,
355 name,
356 args,
357 returns,
358 params,
359 with_options,
360 )
361 .await
362 } else {
363 create_sql_function::handle_create_sql_function(
364 handler_args,
365 or_replace,
366 temporary,
367 if_not_exists,
368 name,
369 args,
370 returns,
371 params,
372 )
373 .await
374 }
375 }
376 Statement::CreateAggregate {
377 or_replace,
378 if_not_exists,
379 name,
380 args,
381 returns,
382 params,
383 ..
384 } => {
385 create_aggregate::handle_create_aggregate(
386 handler_args,
387 or_replace,
388 if_not_exists,
389 name,
390 args,
391 returns,
392 params,
393 )
394 .await
395 }
396 Statement::CreateTable {
397 name,
398 columns,
399 wildcard_idx,
400 constraints,
401 query,
402 with_options: _, or_replace,
405 temporary,
406 if_not_exists,
407 format_encode,
408 source_watermarks,
409 append_only,
410 on_conflict,
411 with_version_columns,
412 cdc_table_info,
413 include_column_options,
414 webhook_info,
415 engine,
416 } => {
417 if or_replace {
418 bail_not_implemented!("CREATE OR REPLACE TABLE");
419 }
420 if temporary {
421 bail_not_implemented!("CREATE TEMPORARY TABLE");
422 }
423 if let Some(query) = query {
424 return create_table_as::handle_create_as(
425 handler_args,
426 name,
427 if_not_exists,
428 query,
429 columns,
430 append_only,
431 on_conflict,
432 with_version_columns
433 .iter()
434 .map(|col| col.real_value())
435 .collect(),
436 engine,
437 )
438 .await;
439 }
440 let format_encode = format_encode.map(|s| s.into_v2_with_warning());
441 Box::pin(create_table::handle_create_table(
442 handler_args,
443 name,
444 columns,
445 wildcard_idx,
446 constraints,
447 if_not_exists,
448 format_encode,
449 source_watermarks,
450 append_only,
451 on_conflict,
452 with_version_columns
453 .iter()
454 .map(|col| col.real_value())
455 .collect(),
456 cdc_table_info,
457 include_column_options,
458 webhook_info,
459 engine,
460 ))
461 .await
462 }
463 Statement::CreateDatabase {
464 db_name,
465 if_not_exists,
466 owner,
467 resource_group,
468 barrier_interval_ms,
469 checkpoint_frequency,
470 } => {
471 create_database::handle_create_database(
472 handler_args,
473 db_name,
474 if_not_exists,
475 owner,
476 resource_group,
477 barrier_interval_ms,
478 checkpoint_frequency,
479 )
480 .await
481 }
482 Statement::CreateSchema {
483 schema_name,
484 if_not_exists,
485 owner,
486 } => {
487 create_schema::handle_create_schema(handler_args, schema_name, if_not_exists, owner)
488 .await
489 }
490 Statement::CreateUser(stmt) => create_user::handle_create_user(handler_args, stmt).await,
491 Statement::DeclareCursor { stmt } => {
492 declare_cursor::handle_declare_cursor(handler_args, stmt).await
493 }
494 Statement::FetchCursor { stmt } => {
495 fetch_cursor::handle_fetch_cursor(handler_args, stmt, &formats).await
496 }
497 Statement::CloseCursor { stmt } => {
498 close_cursor::handle_close_cursor(handler_args, stmt).await
499 }
500 Statement::AlterUser(stmt) => alter_user::handle_alter_user(handler_args, stmt).await,
501 Statement::Grant { .. } => {
502 handle_privilege::handle_grant_privilege(handler_args, stmt).await
503 }
504 Statement::Revoke { .. } => {
505 handle_privilege::handle_revoke_privilege(handler_args, stmt).await
506 }
507 Statement::Describe { name, kind } => match kind {
508 DescribeKind::Fragments => {
509 describe::handle_describe_fragments(handler_args, name).await
510 }
511 DescribeKind::Plain => describe::handle_describe(handler_args, name),
512 },
513 Statement::DescribeFragment { fragment_id } => {
514 describe::handle_describe_fragment(handler_args, fragment_id.into()).await
515 }
516 Statement::Discard(..) => discard::handle_discard(handler_args),
517 Statement::ShowObjects {
518 object: show_object,
519 filter,
520 } => show::handle_show_object(handler_args, show_object, filter).await,
521 Statement::ShowCreateObject { create_type, name } => {
522 show::handle_show_create_object(handler_args, create_type, name)
523 }
524 Statement::ShowTransactionIsolationLevel => {
525 transaction::handle_show_isolation_level(handler_args)
526 }
527 Statement::Drop(DropStatement {
528 object_type,
529 object_name,
530 if_exists,
531 drop_mode,
532 }) => {
533 let cascade = if let AstOption::Some(DropMode::Cascade) = drop_mode {
534 match object_type {
535 ObjectType::MaterializedView
536 | ObjectType::View
537 | ObjectType::Sink
538 | ObjectType::Source
539 | ObjectType::Subscription
540 | ObjectType::Index
541 | ObjectType::Table
542 | ObjectType::Schema
543 | ObjectType::Connection
544 | ObjectType::Secret => true,
545 ObjectType::Database | ObjectType::User => {
546 bail_not_implemented!("DROP CASCADE");
547 }
548 }
549 } else {
550 false
551 };
552 match object_type {
553 ObjectType::Table => {
554 drop_table::handle_drop_table(handler_args, object_name, if_exists, cascade)
555 .await
556 }
557 ObjectType::MaterializedView => {
558 drop_mv::handle_drop_mv(handler_args, object_name, if_exists, cascade).await
559 }
560 ObjectType::Index => {
561 drop_index::handle_drop_index(handler_args, object_name, if_exists, cascade)
562 .await
563 }
564 ObjectType::Source => {
565 drop_source::handle_drop_source(handler_args, object_name, if_exists, cascade)
566 .await
567 }
568 ObjectType::Sink => {
569 drop_sink::handle_drop_sink(handler_args, object_name, if_exists, cascade).await
570 }
571 ObjectType::Subscription => {
572 drop_subscription::handle_drop_subscription(
573 handler_args,
574 object_name,
575 if_exists,
576 cascade,
577 )
578 .await
579 }
580 ObjectType::Database => {
581 drop_database::handle_drop_database(handler_args, object_name, if_exists).await
582 }
583 ObjectType::Schema => {
584 drop_schema::handle_drop_schema(handler_args, object_name, if_exists, cascade)
585 .await
586 }
587 ObjectType::User => {
588 drop_user::handle_drop_user(handler_args, object_name, if_exists).await
589 }
590 ObjectType::View => {
591 drop_view::handle_drop_view(handler_args, object_name, if_exists, cascade).await
592 }
593 ObjectType::Connection => {
594 drop_connection::handle_drop_connection(
595 handler_args,
596 object_name,
597 if_exists,
598 cascade,
599 )
600 .await
601 }
602 ObjectType::Secret => {
603 drop_secret::handle_drop_secret(handler_args, object_name, if_exists, cascade)
604 .await
605 }
606 }
607 }
608 Statement::DropFunction {
610 if_exists,
611 func_desc,
612 option,
613 } => {
614 drop_function::handle_drop_function(handler_args, if_exists, func_desc, option, false)
615 .await
616 }
617 Statement::DropAggregate {
618 if_exists,
619 func_desc,
620 option,
621 } => {
622 drop_function::handle_drop_function(handler_args, if_exists, func_desc, option, true)
623 .await
624 }
625 Statement::Query(_)
626 | Statement::Insert { .. }
627 | Statement::Delete { .. }
628 | Statement::Update { .. } => query::handle_query(handler_args, stmt, formats).await,
629 Statement::Copy {
630 entity: CopyEntity::Query(query),
631 target: CopyTarget::Stdout,
632 } => {
633 let response =
634 query::handle_query(handler_args, Statement::Query(query), vec![Format::Text])
635 .await?;
636 Ok(response.into_copy_query_to_stdout())
637 }
638 Statement::CreateView {
639 materialized,
640 if_not_exists,
641 name,
642 columns,
643 query,
644 with_options: _, or_replace, emit_mode,
647 } => {
648 if or_replace {
649 bail_not_implemented!("CREATE OR REPLACE VIEW");
650 }
651 if materialized {
652 create_mv::handle_create_mv(
653 handler_args,
654 if_not_exists,
655 name,
656 *query,
657 columns,
658 emit_mode,
659 )
660 .await
661 } else {
662 create_view::handle_create_view(handler_args, if_not_exists, name, columns, *query)
663 .await
664 }
665 }
666 Statement::Flush => flush::handle_flush(handler_args).await,
667 Statement::Wait(target) => wait::handle_wait(handler_args, target).await,
668 Statement::Backup => backup::handle_backup(handler_args).await,
669 Statement::DeleteMetaSnapshots { snapshot_ids } => {
670 delete_meta_snapshot::handle_delete_meta_snapshots(handler_args, snapshot_ids).await
671 }
672 Statement::Recover => recover::handle_recover(handler_args).await,
673 Statement::SetVariable {
674 local: _,
675 variable,
676 value,
677 } => {
678 if variable.real_value().eq_ignore_ascii_case("database") {
680 let x = variable::set_var_to_param_str(&value);
681 let res = use_db::handle_use_db(
682 handler_args,
683 ObjectName::from(vec![Ident::from_real_value(
684 x.as_deref().unwrap_or("default"),
685 )]),
686 )?;
687 let mut builder = RwPgResponse::builder(StatementType::SET_VARIABLE);
688 for notice in res.notices() {
689 builder = builder.notice(notice);
690 }
691 return Ok(builder.into());
692 }
693 variable::handle_set(handler_args, variable, value)
694 }
695 Statement::SetTimeZone { local: _, value } => {
696 variable::handle_set_time_zone(handler_args, value)
697 }
698 Statement::ShowVariable { variable } => variable::handle_show(handler_args, variable),
699 Statement::CreateIndex {
700 name,
701 table_name,
702 method,
703 columns,
704 include,
705 distributed_by,
706 unique,
707 if_not_exists,
708 with_properties: _,
709 } => {
710 if unique {
711 bail_not_implemented!("create unique index");
712 }
713
714 create_index::handle_create_index(
715 handler_args,
716 if_not_exists,
717 name,
718 table_name,
719 method,
720 columns.clone(),
721 include,
722 distributed_by,
723 )
724 .await
725 }
726 Statement::AlterDatabase { name, operation } => match operation {
727 AlterDatabaseOperation::RenameDatabase { database_name } => {
728 alter_rename::handle_rename_database(handler_args, name, database_name).await
729 }
730 AlterDatabaseOperation::ChangeOwner { new_owner_name } => {
731 alter_owner::handle_alter_owner(
732 handler_args,
733 name,
734 new_owner_name,
735 StatementType::ALTER_DATABASE,
736 None,
737 )
738 .await
739 }
740 AlterDatabaseOperation::SetParam(config_param) => {
741 let ConfigParam { param, value } = config_param;
742
743 let database_param = match param.real_value().to_uppercase().as_str() {
744 "BARRIER_INTERVAL_MS" => {
745 let barrier_interval_ms = match value {
746 SetVariableValue::Default => None,
747 SetVariableValue::Single(SetVariableValueSingle::Literal(
748 Value::Number(num),
749 )) => {
750 let num = num.parse::<u32>().map_err(|e| {
751 ErrorCode::InvalidInputSyntax(format!(
752 "barrier_interval_ms must be a u32 integer: {}",
753 e.as_report()
754 ))
755 })?;
756 Some(num)
757 }
758 _ => {
759 return Err(ErrorCode::InvalidInputSyntax(
760 "barrier_interval_ms must be a u32 integer or DEFAULT"
761 .to_owned(),
762 )
763 .into());
764 }
765 };
766 AlterDatabaseParam::BarrierIntervalMs(barrier_interval_ms)
767 }
768 "CHECKPOINT_FREQUENCY" => {
769 let checkpoint_frequency = match value {
770 SetVariableValue::Default => None,
771 SetVariableValue::Single(SetVariableValueSingle::Literal(
772 Value::Number(num),
773 )) => {
774 let num = num.parse::<u64>().map_err(|e| {
775 ErrorCode::InvalidInputSyntax(format!(
776 "checkpoint_frequency must be a u64 integer: {}",
777 e.as_report()
778 ))
779 })?;
780 Some(num)
781 }
782 _ => {
783 return Err(ErrorCode::InvalidInputSyntax(
784 "checkpoint_frequency must be a u64 integer or DEFAULT"
785 .to_owned(),
786 )
787 .into());
788 }
789 };
790 AlterDatabaseParam::CheckpointFrequency(checkpoint_frequency)
791 }
792 _ => {
793 return Err(ErrorCode::InvalidInputSyntax(format!(
794 "Unsupported database config parameter: {}",
795 param.real_value()
796 ))
797 .into());
798 }
799 };
800
801 alter_database_param::handle_alter_database_param(
802 handler_args,
803 name,
804 database_param,
805 )
806 .await
807 }
808 AlterDatabaseOperation::SetResourceGroup {
809 resource_group,
810 deferred,
811 } => {
812 alter_database_param::handle_alter_database_resource_group(
813 handler_args,
814 name,
815 resource_group,
816 deferred,
817 )
818 .await
819 }
820 },
821 Statement::AlterSchema { name, operation } => match operation {
822 AlterSchemaOperation::RenameSchema { schema_name } => {
823 alter_rename::handle_rename_schema(handler_args, name, schema_name).await
824 }
825 AlterSchemaOperation::ChangeOwner { new_owner_name } => {
826 alter_owner::handle_alter_owner(
827 handler_args,
828 name,
829 new_owner_name,
830 StatementType::ALTER_SCHEMA,
831 None,
832 )
833 .await
834 }
835 AlterSchemaOperation::SwapRenameSchema { target_schema } => {
836 alter_swap_rename::handle_swap_rename(
837 handler_args,
838 name,
839 target_schema,
840 StatementType::ALTER_SCHEMA,
841 )
842 .await
843 }
844 },
845 Statement::AlterTable { name, operation } => match operation {
846 AlterTableOperation::AddColumn { .. }
847 | AlterTableOperation::DropColumn { .. }
848 | AlterTableOperation::AlterColumn { .. } => {
849 Box::pin(alter_table_column::handle_alter_table_column(
850 handler_args,
851 name,
852 operation,
853 ))
854 .await
855 }
856 AlterTableOperation::AlterWatermark {
857 column_name,
858 expr,
859 with_ttl,
860 } => {
861 Box::pin(alter_watermark::handle_alter_watermark(
862 handler_args,
863 name,
864 column_name,
865 expr,
866 with_ttl,
867 ))
868 .await
869 }
870 AlterTableOperation::RenameTable { table_name } => {
871 alter_rename::handle_rename_table(handler_args, TableType::Table, name, table_name)
872 .await
873 }
874 AlterTableOperation::ChangeOwner { new_owner_name } => {
875 alter_owner::handle_alter_owner(
876 handler_args,
877 name,
878 new_owner_name,
879 StatementType::ALTER_TABLE,
880 None,
881 )
882 .await
883 }
884 AlterTableOperation::SetParallelism {
885 parallelism,
886 deferred,
887 } => {
888 alter_parallelism::handle_alter_parallelism(
889 handler_args,
890 name,
891 parallelism,
892 StatementType::ALTER_TABLE,
893 deferred,
894 )
895 .await
896 }
897 AlterTableOperation::SetBackfillParallelism {
898 parallelism,
899 deferred,
900 } => {
901 alter_parallelism::handle_alter_backfill_parallelism(
902 handler_args,
903 name,
904 parallelism,
905 StatementType::ALTER_TABLE,
906 deferred,
907 )
908 .await
909 }
910 AlterTableOperation::SetSchema { new_schema_name } => {
911 alter_set_schema::handle_alter_set_schema(
912 handler_args,
913 name,
914 new_schema_name,
915 StatementType::ALTER_TABLE,
916 None,
917 )
918 .await
919 }
920 AlterTableOperation::RefreshSchema => {
921 Box::pin(alter_table_with_sr::handle_refresh_schema(
922 handler_args,
923 name,
924 ))
925 .await
926 }
927 AlterTableOperation::SetSourceRateLimit { rate_limit } => {
928 alter_streaming_rate_limit::handle_alter_streaming_rate_limit(
929 handler_args,
930 PbThrottleTarget::Table,
931 risingwave_pb::common::PbThrottleType::Source,
932 name,
933 rate_limit,
934 )
935 .await
936 }
937 AlterTableOperation::DropConnector => {
938 Box::pin(
939 alter_table_drop_connector::handle_alter_table_drop_connector(
940 handler_args,
941 name,
942 ),
943 )
944 .await
945 }
946 AlterTableOperation::SetDmlRateLimit { rate_limit } => {
947 alter_streaming_rate_limit::handle_alter_streaming_rate_limit(
948 handler_args,
949 PbThrottleTarget::Table,
950 risingwave_pb::common::PbThrottleType::Dml,
951 name,
952 rate_limit,
953 )
954 .await
955 }
956 AlterTableOperation::SetConfig { entries } => {
957 alter_streaming_config::handle_alter_streaming_set_config(
958 handler_args,
959 name,
960 entries,
961 StatementType::ALTER_TABLE,
962 )
963 .await
964 }
965 AlterTableOperation::ResetConfig { keys } => {
966 alter_streaming_config::handle_alter_streaming_reset_config(
967 handler_args,
968 name,
969 keys,
970 StatementType::ALTER_TABLE,
971 )
972 .await
973 }
974 AlterTableOperation::SetBackfillRateLimit { rate_limit } => {
975 alter_streaming_rate_limit::handle_alter_streaming_rate_limit(
976 handler_args,
977 PbThrottleTarget::Table,
978 risingwave_pb::common::PbThrottleType::Backfill,
979 name,
980 rate_limit,
981 )
982 .await
983 }
984 AlterTableOperation::SwapRenameTable { target_table } => {
985 alter_swap_rename::handle_swap_rename(
986 handler_args,
987 name,
988 target_table,
989 StatementType::ALTER_TABLE,
990 )
991 .await
992 }
993 AlterTableOperation::AlterConnectorProps { alter_props } => {
994 alter_table_props::handle_alter_table_props(handler_args, name, alter_props).await
995 }
996 AlterTableOperation::AddConstraint { .. }
997 | AlterTableOperation::DropConstraint { .. }
998 | AlterTableOperation::RenameColumn { .. }
999 | AlterTableOperation::ChangeColumn { .. }
1000 | AlterTableOperation::RenameConstraint { .. } => {
1001 bail_not_implemented!(
1002 "Unhandled statement: {}",
1003 Statement::AlterTable { name, operation }
1004 )
1005 }
1006 },
1007 Statement::AlterIndex { name, operation } => match operation {
1008 AlterIndexOperation::RenameIndex { index_name } => {
1009 alter_rename::handle_rename_index(handler_args, name, index_name).await
1010 }
1011 AlterIndexOperation::SetParallelism {
1012 parallelism,
1013 deferred,
1014 } => {
1015 alter_parallelism::handle_alter_parallelism(
1016 handler_args,
1017 name,
1018 parallelism,
1019 StatementType::ALTER_INDEX,
1020 deferred,
1021 )
1022 .await
1023 }
1024 AlterIndexOperation::SetBackfillParallelism {
1025 parallelism,
1026 deferred,
1027 } => {
1028 alter_parallelism::handle_alter_backfill_parallelism(
1029 handler_args,
1030 name,
1031 parallelism,
1032 StatementType::ALTER_INDEX,
1033 deferred,
1034 )
1035 .await
1036 }
1037 AlterIndexOperation::SetResourceGroup {
1038 resource_group,
1039 deferred,
1040 } => {
1041 alter_resource_group::handle_alter_resource_group(
1042 handler_args,
1043 name,
1044 resource_group,
1045 StatementType::ALTER_INDEX,
1046 deferred,
1047 )
1048 .await
1049 }
1050 AlterIndexOperation::SetConfig { entries } => {
1051 alter_streaming_config::handle_alter_streaming_set_config(
1052 handler_args,
1053 name,
1054 entries,
1055 StatementType::ALTER_INDEX,
1056 )
1057 .await
1058 }
1059 AlterIndexOperation::ResetConfig { keys } => {
1060 alter_streaming_config::handle_alter_streaming_reset_config(
1061 handler_args,
1062 name,
1063 keys,
1064 StatementType::ALTER_INDEX,
1065 )
1066 .await
1067 }
1068 },
1069 Statement::AlterView {
1070 materialized,
1071 name,
1072 operation,
1073 } => {
1074 let statement_type = if materialized {
1075 StatementType::ALTER_MATERIALIZED_VIEW
1076 } else {
1077 StatementType::ALTER_VIEW
1078 };
1079 match operation {
1080 AlterViewOperation::RenameView { view_name } => {
1081 if materialized {
1082 alter_rename::handle_rename_table(
1083 handler_args,
1084 TableType::MaterializedView,
1085 name,
1086 view_name,
1087 )
1088 .await
1089 } else {
1090 alter_rename::handle_rename_view(handler_args, name, view_name).await
1091 }
1092 }
1093 AlterViewOperation::SetParallelism {
1094 parallelism,
1095 deferred,
1096 } => {
1097 if !materialized {
1098 bail_not_implemented!("ALTER VIEW SET PARALLELISM");
1099 }
1100 alter_parallelism::handle_alter_parallelism(
1101 handler_args,
1102 name,
1103 parallelism,
1104 statement_type,
1105 deferred,
1106 )
1107 .await
1108 }
1109 AlterViewOperation::SetBackfillParallelism {
1110 parallelism,
1111 deferred,
1112 } => {
1113 if !materialized {
1114 bail_not_implemented!("ALTER VIEW SET BACKFILL PARALLELISM");
1115 }
1116 alter_parallelism::handle_alter_backfill_parallelism(
1117 handler_args,
1118 name,
1119 parallelism,
1120 statement_type,
1121 deferred,
1122 )
1123 .await
1124 }
1125 AlterViewOperation::SetResourceGroup {
1126 resource_group,
1127 deferred,
1128 } => {
1129 if !materialized {
1130 bail_not_implemented!("ALTER VIEW SET RESOURCE GROUP");
1131 }
1132 alter_resource_group::handle_alter_resource_group(
1133 handler_args,
1134 name,
1135 resource_group,
1136 statement_type,
1137 deferred,
1138 )
1139 .await
1140 }
1141 AlterViewOperation::ChangeOwner { new_owner_name } => {
1142 alter_owner::handle_alter_owner(
1143 handler_args,
1144 name,
1145 new_owner_name,
1146 statement_type,
1147 None,
1148 )
1149 .await
1150 }
1151 AlterViewOperation::SetSchema { new_schema_name } => {
1152 alter_set_schema::handle_alter_set_schema(
1153 handler_args,
1154 name,
1155 new_schema_name,
1156 statement_type,
1157 None,
1158 )
1159 .await
1160 }
1161 AlterViewOperation::SetBackfillRateLimit { rate_limit } => {
1162 if !materialized {
1163 bail_not_implemented!("ALTER VIEW SET BACKFILL RATE LIMIT");
1164 }
1165 alter_streaming_rate_limit::handle_alter_streaming_rate_limit(
1166 handler_args,
1167 PbThrottleTarget::Mv,
1168 risingwave_pb::common::PbThrottleType::Backfill,
1169 name,
1170 rate_limit,
1171 )
1172 .await
1173 }
1174 AlterViewOperation::SwapRenameView { target_view } => {
1175 alter_swap_rename::handle_swap_rename(
1176 handler_args,
1177 name,
1178 target_view,
1179 statement_type,
1180 )
1181 .await
1182 }
1183 AlterViewOperation::SetStreamingEnableUnalignedJoin { enable } => {
1184 if !materialized {
1185 bail!(
1186 "ALTER VIEW SET STREAMING_ENABLE_UNALIGNED_JOIN is not supported. Only supported for materialized views"
1187 );
1188 }
1189 alter_streaming_enable_unaligned_join::handle_alter_streaming_enable_unaligned_join(handler_args, name, enable).await
1190 }
1191 AlterViewOperation::AsQuery { query } => {
1192 if !materialized {
1193 bail_not_implemented!("ALTER VIEW AS QUERY");
1194 }
1195 if !cfg!(debug_assertions) {
1197 bail_not_implemented!("ALTER MATERIALIZED VIEW AS QUERY");
1198 }
1199 alter_mv::handle_alter_mv(handler_args, name, query).await
1200 }
1201 AlterViewOperation::SetConfig { entries } => {
1202 if !materialized {
1203 bail!("SET CONFIG is only supported for materialized views");
1204 }
1205 alter_streaming_config::handle_alter_streaming_set_config(
1206 handler_args,
1207 name,
1208 entries,
1209 statement_type,
1210 )
1211 .await
1212 }
1213 AlterViewOperation::ResetConfig { keys } => {
1214 if !materialized {
1215 bail!("RESET CONFIG is only supported for materialized views");
1216 }
1217 alter_streaming_config::handle_alter_streaming_reset_config(
1218 handler_args,
1219 name,
1220 keys,
1221 statement_type,
1222 )
1223 .await
1224 }
1225 }
1226 }
1227
1228 Statement::AlterSink { name, operation } => match operation {
1229 AlterSinkOperation::AlterConnectorProps {
1230 alter_props: changed_props,
1231 } => alter_sink_props::handle_alter_sink_props(handler_args, name, changed_props).await,
1232 AlterSinkOperation::RenameSink { sink_name } => {
1233 alter_rename::handle_rename_sink(handler_args, name, sink_name).await
1234 }
1235 AlterSinkOperation::ChangeOwner { new_owner_name } => {
1236 alter_owner::handle_alter_owner(
1237 handler_args,
1238 name,
1239 new_owner_name,
1240 StatementType::ALTER_SINK,
1241 None,
1242 )
1243 .await
1244 }
1245 AlterSinkOperation::SetSchema { new_schema_name } => {
1246 alter_set_schema::handle_alter_set_schema(
1247 handler_args,
1248 name,
1249 new_schema_name,
1250 StatementType::ALTER_SINK,
1251 None,
1252 )
1253 .await
1254 }
1255 AlterSinkOperation::SetParallelism {
1256 parallelism,
1257 deferred,
1258 } => {
1259 alter_parallelism::handle_alter_parallelism(
1260 handler_args,
1261 name,
1262 parallelism,
1263 StatementType::ALTER_SINK,
1264 deferred,
1265 )
1266 .await
1267 }
1268 AlterSinkOperation::SetBackfillParallelism {
1269 parallelism,
1270 deferred,
1271 } => {
1272 alter_parallelism::handle_alter_backfill_parallelism(
1273 handler_args,
1274 name,
1275 parallelism,
1276 StatementType::ALTER_SINK,
1277 deferred,
1278 )
1279 .await
1280 }
1281 AlterSinkOperation::SetResourceGroup {
1282 resource_group,
1283 deferred,
1284 } => {
1285 alter_resource_group::handle_alter_resource_group(
1286 handler_args,
1287 name,
1288 resource_group,
1289 StatementType::ALTER_SINK,
1290 deferred,
1291 )
1292 .await
1293 }
1294 AlterSinkOperation::SetConfig { entries } => {
1295 alter_streaming_config::handle_alter_streaming_set_config(
1296 handler_args,
1297 name,
1298 entries,
1299 StatementType::ALTER_SINK,
1300 )
1301 .await
1302 }
1303 AlterSinkOperation::ResetConfig { keys } => {
1304 alter_streaming_config::handle_alter_streaming_reset_config(
1305 handler_args,
1306 name,
1307 keys,
1308 StatementType::ALTER_SINK,
1309 )
1310 .await
1311 }
1312 AlterSinkOperation::SwapRenameSink { target_sink } => {
1313 alter_swap_rename::handle_swap_rename(
1314 handler_args,
1315 name,
1316 target_sink,
1317 StatementType::ALTER_SINK,
1318 )
1319 .await
1320 }
1321 AlterSinkOperation::SetSinkRateLimit { rate_limit } => {
1322 alter_streaming_rate_limit::handle_alter_streaming_rate_limit(
1323 handler_args,
1324 PbThrottleTarget::Sink,
1325 risingwave_pb::common::PbThrottleType::Sink,
1326 name,
1327 rate_limit,
1328 )
1329 .await
1330 }
1331 AlterSinkOperation::SetBackfillRateLimit { rate_limit } => {
1332 alter_streaming_rate_limit::handle_alter_streaming_rate_limit(
1333 handler_args,
1334 PbThrottleTarget::Sink,
1335 risingwave_pb::common::PbThrottleType::Backfill,
1336 name,
1337 rate_limit,
1338 )
1339 .await
1340 }
1341 AlterSinkOperation::SetStreamingEnableUnalignedJoin { enable } => {
1342 alter_streaming_enable_unaligned_join::handle_alter_streaming_enable_unaligned_join(
1343 handler_args,
1344 name,
1345 enable,
1346 )
1347 .await
1348 }
1349 },
1350 Statement::AlterSubscription { name, operation } => match operation {
1351 AlterSubscriptionOperation::RenameSubscription { subscription_name } => {
1352 alter_rename::handle_rename_subscription(handler_args, name, subscription_name)
1353 .await
1354 }
1355 AlterSubscriptionOperation::ChangeOwner { new_owner_name } => {
1356 alter_owner::handle_alter_owner(
1357 handler_args,
1358 name,
1359 new_owner_name,
1360 StatementType::ALTER_SUBSCRIPTION,
1361 None,
1362 )
1363 .await
1364 }
1365 AlterSubscriptionOperation::SetSchema { new_schema_name } => {
1366 alter_set_schema::handle_alter_set_schema(
1367 handler_args,
1368 name,
1369 new_schema_name,
1370 StatementType::ALTER_SUBSCRIPTION,
1371 None,
1372 )
1373 .await
1374 }
1375 AlterSubscriptionOperation::SetRetention { retention } => {
1376 alter_subscription_retention::handle_alter_subscription_retention(
1377 handler_args,
1378 name,
1379 retention,
1380 )
1381 .await
1382 }
1383 AlterSubscriptionOperation::SwapRenameSubscription {
1384 target_subscription,
1385 } => {
1386 alter_swap_rename::handle_swap_rename(
1387 handler_args,
1388 name,
1389 target_subscription,
1390 StatementType::ALTER_SUBSCRIPTION,
1391 )
1392 .await
1393 }
1394 },
1395 Statement::AlterSource { name, operation } => match operation {
1396 AlterSourceOperation::AlterConnectorProps { alter_props } => {
1397 alter_source_props::handle_alter_source_connector_props(
1398 handler_args,
1399 name,
1400 alter_props,
1401 )
1402 .await
1403 }
1404 AlterSourceOperation::RenameSource { source_name } => {
1405 alter_rename::handle_rename_source(handler_args, name, source_name).await
1406 }
1407 AlterSourceOperation::AddColumn { .. } => {
1408 alter_source_column::handle_alter_source_column(handler_args, name, operation).await
1409 }
1410 AlterSourceOperation::ChangeOwner { new_owner_name } => {
1411 alter_owner::handle_alter_owner(
1412 handler_args,
1413 name,
1414 new_owner_name,
1415 StatementType::ALTER_SOURCE,
1416 None,
1417 )
1418 .await
1419 }
1420 AlterSourceOperation::SetSchema { new_schema_name } => {
1421 alter_set_schema::handle_alter_set_schema(
1422 handler_args,
1423 name,
1424 new_schema_name,
1425 StatementType::ALTER_SOURCE,
1426 None,
1427 )
1428 .await
1429 }
1430 AlterSourceOperation::FormatEncode { format_encode } => {
1431 alter_source_with_sr::handle_alter_source_with_sr(handler_args, name, format_encode)
1432 .await
1433 }
1434 AlterSourceOperation::RefreshSchema => {
1435 alter_source_with_sr::handler_refresh_schema(handler_args, name).await
1436 }
1437 AlterSourceOperation::SetSourceRateLimit { rate_limit } => {
1438 alter_streaming_rate_limit::handle_alter_streaming_rate_limit(
1439 handler_args,
1440 PbThrottleTarget::Source,
1441 risingwave_pb::common::PbThrottleType::Source,
1442 name,
1443 rate_limit,
1444 )
1445 .await
1446 }
1447 AlterSourceOperation::SwapRenameSource { target_source } => {
1448 alter_swap_rename::handle_swap_rename(
1449 handler_args,
1450 name,
1451 target_source,
1452 StatementType::ALTER_SOURCE,
1453 )
1454 .await
1455 }
1456 AlterSourceOperation::SetParallelism {
1457 parallelism,
1458 deferred,
1459 } => {
1460 alter_parallelism::handle_alter_parallelism(
1461 handler_args,
1462 name,
1463 parallelism,
1464 StatementType::ALTER_SOURCE,
1465 deferred,
1466 )
1467 .await
1468 }
1469 AlterSourceOperation::SetBackfillParallelism {
1470 parallelism,
1471 deferred,
1472 } => {
1473 alter_parallelism::handle_alter_backfill_parallelism(
1474 handler_args,
1475 name,
1476 parallelism,
1477 StatementType::ALTER_SOURCE,
1478 deferred,
1479 )
1480 .await
1481 }
1482 AlterSourceOperation::SetConfig { entries } => {
1483 alter_streaming_config::handle_alter_streaming_set_config(
1484 handler_args,
1485 name,
1486 entries,
1487 StatementType::ALTER_SOURCE,
1488 )
1489 .await
1490 }
1491 AlterSourceOperation::ResetConfig { keys } => {
1492 alter_streaming_config::handle_alter_streaming_reset_config(
1493 handler_args,
1494 name,
1495 keys,
1496 StatementType::ALTER_SOURCE,
1497 )
1498 .await
1499 }
1500 AlterSourceOperation::ResetSource => {
1501 reset_source::handle_reset_source(handler_args, name).await
1502 }
1503 },
1504 Statement::AlterFunction {
1505 name,
1506 args,
1507 operation,
1508 } => match operation {
1509 AlterFunctionOperation::SetSchema { new_schema_name } => {
1510 alter_set_schema::handle_alter_set_schema(
1511 handler_args,
1512 name,
1513 new_schema_name,
1514 StatementType::ALTER_FUNCTION,
1515 args,
1516 )
1517 .await
1518 }
1519 AlterFunctionOperation::ChangeOwner { new_owner_name } => {
1520 alter_owner::handle_alter_owner(
1521 handler_args,
1522 name,
1523 new_owner_name,
1524 StatementType::ALTER_FUNCTION,
1525 args,
1526 )
1527 .await
1528 }
1529 },
1530 Statement::AlterConnection { name, operation } => match operation {
1531 AlterConnectionOperation::SetSchema { new_schema_name } => {
1532 alter_set_schema::handle_alter_set_schema(
1533 handler_args,
1534 name,
1535 new_schema_name,
1536 StatementType::ALTER_CONNECTION,
1537 None,
1538 )
1539 .await
1540 }
1541 AlterConnectionOperation::ChangeOwner { new_owner_name } => {
1542 alter_owner::handle_alter_owner(
1543 handler_args,
1544 name,
1545 new_owner_name,
1546 StatementType::ALTER_CONNECTION,
1547 None,
1548 )
1549 .await
1550 }
1551 AlterConnectionOperation::AlterConnectorProps { alter_props } => {
1552 alter_connection_props::handle_alter_connection_connector_props(
1553 handler_args,
1554 name,
1555 alter_props,
1556 )
1557 .await
1558 }
1559 },
1560 Statement::AlterSystem { param, value } => {
1561 alter_system::handle_alter_system(handler_args, param, value).await
1562 }
1563 Statement::AlterSecret { name, operation } => match operation {
1564 AlterSecretOperation::ChangeCredential {
1565 with_options,
1566 new_credential,
1567 } => {
1568 alter_secret::handle_alter_secret(handler_args, name, with_options, new_credential)
1569 .await
1570 }
1571 AlterSecretOperation::ChangeOwner { new_owner_name } => {
1572 alter_owner::handle_alter_owner(
1573 handler_args,
1574 name,
1575 new_owner_name,
1576 StatementType::ALTER_SECRET,
1577 None,
1578 )
1579 .await
1580 }
1581 },
1582 Statement::AlterFragment {
1583 fragment_ids,
1584 operation,
1585 } => match operation {
1586 AlterFragmentOperation::AlterBackfillRateLimit { rate_limit } => {
1587 let [fragment_id] = fragment_ids.as_slice() else {
1588 return Err(ErrorCode::InvalidInputSyntax(
1589 "ALTER FRAGMENT ... SET RATE_LIMIT supports exactly one fragment id"
1590 .to_owned(),
1591 )
1592 .into());
1593 };
1594 alter_streaming_rate_limit::handle_alter_streaming_rate_limit_by_id(
1595 &handler_args.session,
1596 PbThrottleTarget::Fragment,
1597 risingwave_pb::common::PbThrottleType::Backfill,
1598 *fragment_id,
1599 rate_limit,
1600 StatementType::SET_VARIABLE,
1601 )
1602 .await
1603 }
1604 AlterFragmentOperation::SetParallelism { parallelism } => {
1605 alter_parallelism::handle_alter_fragment_parallelism(
1606 handler_args,
1607 fragment_ids.into_iter().map_into().collect(),
1608 parallelism,
1609 )
1610 .await
1611 }
1612 },
1613 Statement::AlterDefaultPrivileges { .. } => {
1614 handle_privilege::handle_alter_default_privileges(handler_args, stmt).await
1615 }
1616 Statement::AlterCompactionGroup {
1617 group_ids,
1618 operation,
1619 } => {
1620 alter_compaction_group::handle_alter_compaction_group(
1621 handler_args,
1622 group_ids,
1623 operation,
1624 )
1625 .await
1626 }
1627 Statement::StartTransaction { modes } => {
1628 transaction::handle_begin(handler_args, START_TRANSACTION, modes)
1629 }
1630 Statement::Begin { modes } => transaction::handle_begin(handler_args, BEGIN, modes),
1631 Statement::Commit { chain } => {
1632 transaction::handle_commit(handler_args, COMMIT, chain).await
1633 }
1634 Statement::Abort => transaction::handle_rollback(handler_args, ABORT, false).await,
1635 Statement::Rollback { chain } => {
1636 transaction::handle_rollback(handler_args, ROLLBACK, chain).await
1637 }
1638 Statement::SetTransaction {
1639 modes,
1640 snapshot,
1641 session,
1642 } => transaction::handle_set(handler_args, modes, snapshot, session),
1643 Statement::CancelJobs(jobs) => handle_cancel(handler_args, jobs).await,
1644 Statement::Kill(worker_process_id) => handle_kill(handler_args, worker_process_id).await,
1645 Statement::Comment {
1646 object_type,
1647 object_name,
1648 comment,
1649 } => comment::handle_comment(handler_args, object_type, object_name, comment).await,
1650 Statement::Use { db_name } => use_db::handle_use_db(handler_args, db_name),
1651 Statement::Prepare {
1652 name,
1653 data_types,
1654 statement,
1655 } => prepared_statement::handle_prepare(name, data_types, statement),
1656 Statement::Deallocate { name, prepare } => {
1657 prepared_statement::handle_deallocate(name, prepare)
1658 }
1659 Statement::Vacuum { object_name, full } => {
1660 vacuum::handle_vacuum(handler_args, object_name, full).await
1661 }
1662 Statement::Refresh { table_name } => {
1663 refresh::handle_refresh(handler_args, table_name).await
1664 }
1665 _ => bail_not_implemented!("Unhandled statement: {}", stmt),
1666 }
1667}
1668
1669fn check_ban_ddl_for_iceberg_engine_table(
1670 session: Arc<SessionImpl>,
1671 stmt: &Statement,
1672) -> Result<()> {
1673 if let Statement::AlterTable { name, operation } = stmt {
1674 let (table, schema_name) = get_table_catalog_by_table_name(session.as_ref(), name)?;
1675 if table.is_iceberg_engine_table() {
1676 let has_auto_refresh_schema_sink = if matches!(
1677 operation,
1678 AlterTableOperation::AddColumn { .. } | AlterTableOperation::DropColumn { .. }
1679 ) {
1680 let catalog_reader = session.env().catalog_reader().read_guard();
1681 let db_name = session.database();
1682 let sink_name = format!("{}{}", ICEBERG_SINK_PREFIX, table.name());
1683 let sink = catalog_reader
1684 .get_schema_by_name(&db_name, &schema_name)
1685 .ok()
1686 .and_then(|schema| schema.get_created_sink_by_name(&sink_name));
1687 sink.and_then(|s| s.auto_refresh_schema_from_table)
1688 .is_some()
1689 } else {
1690 false
1691 };
1692
1693 check_ban_alter_table_operation_for_iceberg_engine_table(
1694 operation,
1695 &schema_name,
1696 name,
1697 has_auto_refresh_schema_sink,
1698 )?;
1699 }
1700 }
1701
1702 Ok(())
1703}
1704
1705fn check_ban_alter_table_operation_for_iceberg_engine_table(
1706 operation: &AlterTableOperation,
1707 schema_name: &str,
1708 table_name: &ObjectName,
1709 has_auto_refresh_schema_sink: bool,
1710) -> Result<()> {
1711 match operation {
1712 AlterTableOperation::AddColumn { .. } => {
1713 if !has_auto_refresh_schema_sink {
1714 bail!(
1715 "ALTER TABLE {} is not supported for iceberg table without auto schema change sink: {}.{}",
1716 operation,
1717 schema_name,
1718 table_name
1719 );
1720 }
1721 }
1722 AlterTableOperation::DropColumn { .. } => {
1723 if !has_auto_refresh_schema_sink {
1724 bail!(
1725 "ALTER TABLE {} is not supported for iceberg table without auto schema change sink: {}.{}",
1726 operation,
1727 schema_name,
1728 table_name
1729 );
1730 }
1731 }
1732 AlterTableOperation::RenameColumn { .. }
1733 | AlterTableOperation::ChangeColumn { .. }
1734 | AlterTableOperation::AlterColumn { .. } => {
1735 bail!(
1736 "ALTER TABLE {} is not supported for iceberg table: {}.{}. Existing column schema mutation is not supported currently",
1737 operation,
1738 schema_name,
1739 table_name
1740 );
1741 }
1742 AlterTableOperation::RenameTable { .. } => {
1743 bail!(
1744 "ALTER TABLE RENAME is not supported for iceberg table: {}.{}",
1745 schema_name,
1746 table_name
1747 );
1748 }
1749 AlterTableOperation::SetParallelism { .. } => {
1750 bail!(
1751 "ALTER TABLE SET PARALLELISM is not supported for iceberg table: {}.{}",
1752 schema_name,
1753 table_name
1754 );
1755 }
1756 AlterTableOperation::SetBackfillParallelism { .. } => {
1757 bail!(
1758 "ALTER TABLE SET BACKFILL PARALLELISM is not supported for iceberg table: {}.{}",
1759 schema_name,
1760 table_name
1761 );
1762 }
1763 AlterTableOperation::SetSchema { .. } => {
1764 bail!(
1765 "ALTER TABLE SET SCHEMA is not supported for iceberg table: {}.{}",
1766 schema_name,
1767 table_name
1768 );
1769 }
1770 AlterTableOperation::RefreshSchema => {
1771 bail!(
1772 "ALTER TABLE REFRESH SCHEMA is not supported for iceberg table: {}.{}",
1773 schema_name,
1774 table_name
1775 );
1776 }
1777 AlterTableOperation::SetSourceRateLimit { .. } => {
1778 bail!(
1779 "ALTER TABLE SET SOURCE RATE LIMIT is not supported for iceberg table: {}.{}",
1780 schema_name,
1781 table_name
1782 );
1783 }
1784 AlterTableOperation::AlterWatermark { .. } => {
1785 bail!(
1786 "ALTER TABLE ALTER WATERMARK is not supported for iceberg table: {}.{}",
1787 schema_name,
1788 table_name
1789 );
1790 }
1791 _ => {}
1792 }
1793 Ok(())
1794}