risingwave_frontend/handler/
alter_resource_group.rs1use pgwire::pg_response::StatementType;
16use risingwave_common::bail;
17use risingwave_common::util::worker_util::DEFAULT_RESOURCE_GROUP;
18use risingwave_sqlparser::ast::{ObjectName, SetVariableValue, SetVariableValueSingle, Value};
19
20use super::{HandlerArgs, RwPgResponse};
21use crate::Binder;
22use crate::catalog::root_catalog::SchemaPath;
23use crate::catalog::table_catalog::TableType;
24use crate::error::{ErrorCode, Result};
25
26pub async fn handle_alter_resource_group(
27 handler_args: HandlerArgs,
28 obj_name: ObjectName,
29 resource_group: Option<SetVariableValue>,
30 stmt_type: StatementType,
31 deferred: bool,
32) -> Result<RwPgResponse> {
33 let session = handler_args.session;
34 let db_name = session.database();
35 let (schema_name, real_table_name) =
36 Binder::resolve_schema_qualified_name(&db_name, obj_name.clone())?;
37 let search_path = session.config().search_path();
38 let user_name = &session.auth_context().user_name;
39 let schema_path = SchemaPath::new(schema_name.as_deref(), &search_path, user_name);
40
41 risingwave_common::license::Feature::ResourceGroup
42 .check_available()
43 .map_err(|e| anyhow::anyhow!(e))?;
44
45 let table_id = {
46 let reader = session.env().catalog_reader().read_guard();
47
48 match stmt_type {
49 StatementType::ALTER_MATERIALIZED_VIEW => {
50 let (table, schema_name) =
51 reader.get_created_table_by_name(&db_name, schema_path, &real_table_name)?;
52
53 match (table.table_type(), stmt_type) {
54 (TableType::MaterializedView, StatementType::ALTER_MATERIALIZED_VIEW) => {}
55 _ => {
56 return Err(ErrorCode::InvalidInputSyntax(format!(
57 "cannot alter resource group of {} {} by {}",
58 table.table_type().to_prost().as_str_name(),
59 table.name(),
60 stmt_type,
61 ))
62 .into());
63 }
64 }
65
66 session.check_privilege_for_drop_alter(schema_name, &**table)?;
67 table.id.table_id()
68 }
69 _ => bail!(
70 "invalid statement type for alter resource group: {:?}",
71 stmt_type
72 ),
73 }
74 };
75
76 let resource_group = resource_group
77 .map(resolve_resource_group)
78 .transpose()?
79 .flatten();
80
81 let mut builder = RwPgResponse::builder(stmt_type);
82
83 let catalog_writer = session.catalog_writer()?;
84 catalog_writer
85 .alter_resource_group(table_id, resource_group, deferred)
86 .await?;
87
88 if deferred {
89 builder = builder.notice("DEFERRED is used, please ensure that automatic parallelism control is enabled on the meta, otherwise, the alter will not take effect.".to_owned());
90 }
91
92 Ok(builder.into())
93}
94
95pub(crate) fn resolve_resource_group(resource_group: SetVariableValue) -> Result<Option<String>> {
97 Ok(match resource_group {
98 SetVariableValue::Single(SetVariableValueSingle::Ident(ident)) => Some(ident.real_value()),
99 SetVariableValue::Single(SetVariableValueSingle::Literal(Value::SingleQuotedString(v)))
100 if v.as_str().eq_ignore_ascii_case(DEFAULT_RESOURCE_GROUP) =>
101 {
102 None
103 }
104 SetVariableValue::Single(SetVariableValueSingle::Literal(Value::SingleQuotedString(v))) => {
105 Some(v)
106 }
107 SetVariableValue::Default => None,
108 _ => {
109 return Err(ErrorCode::InvalidInputSyntax(
110 "target resource group must be a valid string or default".to_owned(),
111 )
112 .into());
113 }
114 })
115}