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)?;
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.check_available()?;
42
43 let table_id = {
44 let reader = session.env().catalog_reader().read_guard();
45
46 match stmt_type {
47 StatementType::ALTER_MATERIALIZED_VIEW => {
48 let (table, schema_name) =
49 reader.get_created_table_by_name(&db_name, schema_path, &real_table_name)?;
50
51 match (table.table_type(), stmt_type) {
52 (TableType::MaterializedView, StatementType::ALTER_MATERIALIZED_VIEW) => {}
53 _ => {
54 return Err(ErrorCode::InvalidInputSyntax(format!(
55 "cannot alter resource group of {} {} by {}",
56 table.table_type().to_prost().as_str_name(),
57 table.name(),
58 stmt_type,
59 ))
60 .into());
61 }
62 }
63
64 session.check_privilege_for_drop_alter(schema_name, &**table)?;
65 table.id.table_id()
66 }
67 _ => bail!(
68 "invalid statement type for alter resource group: {:?}",
69 stmt_type
70 ),
71 }
72 };
73
74 let resource_group = resource_group
75 .map(resolve_resource_group)
76 .transpose()?
77 .flatten();
78
79 let mut builder = RwPgResponse::builder(stmt_type);
80
81 let catalog_writer = session.catalog_writer()?;
82 catalog_writer
83 .alter_resource_group(table_id, resource_group, deferred)
84 .await?;
85
86 if deferred {
87 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());
88 }
89
90 Ok(builder.into())
91}
92
93pub(crate) fn resolve_resource_group(resource_group: SetVariableValue) -> Result<Option<String>> {
95 Ok(match resource_group {
96 SetVariableValue::Single(SetVariableValueSingle::Ident(ident)) => Some(ident.real_value()),
97 SetVariableValue::Single(SetVariableValueSingle::Literal(Value::SingleQuotedString(v)))
98 if v.as_str().eq_ignore_ascii_case(DEFAULT_RESOURCE_GROUP) =>
99 {
100 None
101 }
102 SetVariableValue::Single(SetVariableValueSingle::Literal(Value::SingleQuotedString(v))) => {
103 Some(v)
104 }
105 SetVariableValue::Default => None,
106 _ => {
107 return Err(ErrorCode::InvalidInputSyntax(
108 "target resource group must be a valid string or default".to_owned(),
109 )
110 .into());
111 }
112 })
113}