Skip to main content

metric_engine/engine/alter/
validate.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 datatypes::schema::COMPRESSION_KEY;
16use snafu::ensure;
17use store_api::region_request::{AlterKind, RegionAlterRequest};
18use store_api::storage::RegionId;
19
20use crate::error::{Result, UnexpectedRequestSnafu, UnsupportedAlterKindSnafu};
21
22/// Validate the alter region requests.
23pub fn validate_alter_region_requests(requests: &[(RegionId, RegionAlterRequest)]) -> Result<()> {
24    for (_, request) in requests {
25        ensure!(
26            matches!(request.kind, AlterKind::AddColumns { .. }),
27            UnsupportedAlterKindSnafu {
28                kind: request.kind.as_ref()
29            }
30        );
31        if let AlterKind::AddColumns { columns } = &request.kind {
32            for column in columns {
33                ensure!(
34                    !column.column_metadata.column_schema.metadata().contains_key(COMPRESSION_KEY),
35                    UnexpectedRequestSnafu {
36                        reason: "COMPRESSION is not supported on logical tables; configure it on the physical table".to_string(),
37                    }
38                );
39            }
40        }
41    }
42
43    Ok(())
44}
45
46#[cfg(test)]
47mod tests {
48    use api::v1::SemanticType;
49    use common_error::ext::ErrorExt;
50    use common_error::status_code::StatusCode;
51    use datatypes::prelude::ConcreteDataType;
52    use datatypes::schema::{ColumnSchema, CompressionOptions};
53    use store_api::metadata::ColumnMetadata;
54    use store_api::region_request::AddColumn;
55
56    use super::*;
57
58    #[test]
59    fn test_reject_logical_column_compression() {
60        let column_schema = ColumnSchema::new("host", ConcreteDataType::string_datatype(), true)
61            .with_compression_options(CompressionOptions {
62                level: Some(3),
63                ..Default::default()
64            })
65            .unwrap();
66        let request = RegionAlterRequest {
67            kind: AlterKind::AddColumns {
68                columns: vec![AddColumn {
69                    column_metadata: ColumnMetadata {
70                        column_schema,
71                        semantic_type: SemanticType::Tag,
72                        column_id: 3,
73                    },
74                    location: None,
75                }],
76            },
77        };
78        let err = validate_alter_region_requests(&[(RegionId::new(1, 1), request)]).unwrap_err();
79        assert_eq!(StatusCode::InvalidArguments, err.status_code());
80        assert!(
81            err.to_string()
82                .contains("configure it on the physical table")
83        );
84    }
85}