cli/metadata/repair/
alter_table.rs

1// Copyright 2023 Greptime Team
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 client::api::v1::alter_table_expr::Kind;
16use client::api::v1::region::{region_request, AlterRequests, RegionRequest, RegionRequestHeader};
17use client::api::v1::{AddColumn, AddColumns, AlterTableExpr};
18use common_meta::ddl::alter_logical_tables::make_alter_region_request;
19use common_meta::peer::Peer;
20use common_meta::rpc::router::{find_leader_regions, RegionRoute};
21use operator::expr_helper::column_schemas_to_defs;
22use snafu::ResultExt;
23use store_api::storage::{RegionId, TableId};
24use table::metadata::RawTableInfo;
25
26use crate::error::{CovertColumnSchemasToDefsSnafu, Result};
27
28/// Generates alter table expression for all columns.
29pub fn generate_alter_table_expr_for_all_columns(
30    table_info: &RawTableInfo,
31) -> Result<AlterTableExpr> {
32    let schema = &table_info.meta.schema;
33
34    let mut alter_table_expr = AlterTableExpr {
35        catalog_name: table_info.catalog_name.to_string(),
36        schema_name: table_info.schema_name.to_string(),
37        table_name: table_info.name.to_string(),
38        ..Default::default()
39    };
40
41    let primary_keys = table_info
42        .meta
43        .primary_key_indices
44        .iter()
45        .map(|i| schema.column_schemas[*i].name.clone())
46        .collect::<Vec<_>>();
47
48    let add_columns = column_schemas_to_defs(schema.column_schemas.clone(), &primary_keys)
49        .context(CovertColumnSchemasToDefsSnafu)?;
50
51    alter_table_expr.kind = Some(Kind::AddColumns(AddColumns {
52        add_columns: add_columns
53            .into_iter()
54            .map(|col| AddColumn {
55                column_def: Some(col),
56                location: None,
57                add_if_not_exists: true,
58            })
59            .collect(),
60    }));
61
62    Ok(alter_table_expr)
63}
64
65/// Makes an alter region request for a peer.
66pub fn make_alter_region_request_for_peer(
67    logical_table_id: TableId,
68    alter_table_expr: &AlterTableExpr,
69    schema_version: u64,
70    peer: &Peer,
71    region_routes: &[RegionRoute],
72) -> Result<RegionRequest> {
73    let regions_on_this_peer = find_leader_regions(region_routes, peer);
74    let mut requests = Vec::with_capacity(regions_on_this_peer.len());
75    for region_number in &regions_on_this_peer {
76        let region_id = RegionId::new(logical_table_id, *region_number);
77        let request = make_alter_region_request(region_id, alter_table_expr, schema_version);
78        requests.push(request);
79    }
80
81    Ok(RegionRequest {
82        header: Some(RegionRequestHeader::default()),
83        body: Some(region_request::Body::Alters(AlterRequests { requests })),
84    })
85}