Skip to main content

risingwave_frontend/handler/
mod.rs

1// Copyright 2022 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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
134/// The [`PgResponseBuilder`] used by RisingWave.
135pub type RwPgResponseBuilder = PgResponseBuilder<PgResponseStream>;
136
137/// The [`PgResponse`] used by RisingWave.
138pub type RwPgResponse = PgResponse<PgResponseStream>;
139
140#[easy_ext::ext(RwPgResponseBuilderExt)]
141impl RwPgResponseBuilder {
142    /// Append rows to the response.
143    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    /// Get normalized SQL from the statement.
219    ///
220    /// - Generally, the normalized SQL is the unparsed (and formatted) result of the statement.
221    /// - For `CREATE` statements, the clauses like `OR REPLACE` and `IF NOT EXISTS` are removed to
222    ///   make it suitable for the `SHOW CREATE` statements.
223    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            // For general udf, `language` clause could be ignored
341            // refer: https://github.com/risingwavelabs/risingwave/pull/10608
342            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: _, // It is put in OptimizerContext
403            // Not supported things
404            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        // XXX: should we reuse Statement::Drop for DROP FUNCTION?
609        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: _, // It is put in OptimizerContext
645            or_replace,      // not supported
646            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            // special handle for `use database`
679            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                    // `ALTER MATERIALIZED VIEW AS QUERY` is only available in development build now.
1196                    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}