common_grpc_expr/
delete.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 std::collections::HashMap;
16
17use api::helper::ColumnDataTypeWrapper;
18use api::v1::{Column, DeleteRequest as GrpcDeleteRequest};
19use datatypes::prelude::ConcreteDataType;
20use snafu::{ensure, ResultExt};
21use table::requests::DeleteRequest;
22
23use crate::error::{ColumnDataTypeSnafu, IllegalDeleteRequestSnafu, Result};
24use crate::insert::add_values_to_builder;
25
26pub fn to_table_delete_request(
27    catalog_name: &str,
28    schema_name: &str,
29    request: GrpcDeleteRequest,
30) -> Result<DeleteRequest> {
31    let row_count = request.row_count as usize;
32
33    let mut key_column_values = HashMap::with_capacity(request.key_columns.len());
34    for Column {
35        column_name,
36        values,
37        null_mask,
38        datatype,
39        datatype_extension,
40        ..
41    } in request.key_columns
42    {
43        let Some(values) = values else { continue };
44
45        let datatype: ConcreteDataType =
46            ColumnDataTypeWrapper::try_new(datatype, datatype_extension)
47                .context(ColumnDataTypeSnafu)?
48                .into();
49        let vector = add_values_to_builder(datatype, values, row_count, null_mask)?;
50
51        ensure!(
52            key_column_values
53                .insert(column_name.clone(), vector)
54                .is_none(),
55            IllegalDeleteRequestSnafu {
56                reason: format!("Duplicated column '{column_name}' in delete request.")
57            }
58        );
59    }
60
61    Ok(DeleteRequest {
62        catalog_name: catalog_name.to_string(),
63        schema_name: schema_name.to_string(),
64        table_name: request.table_name,
65        key_column_values,
66    })
67}
68
69#[cfg(test)]
70mod tests {
71    use std::sync::Arc;
72
73    use api::v1::column::Values;
74    use api::v1::ColumnDataType;
75    use datatypes::prelude::{ScalarVector, VectorRef};
76    use datatypes::vectors::{Int32Vector, StringVector};
77
78    use super::*;
79
80    #[test]
81    fn test_to_table_delete_request() {
82        let grpc_request = GrpcDeleteRequest {
83            table_name: "foo".to_string(),
84            key_columns: vec![
85                Column {
86                    column_name: "id".to_string(),
87                    values: Some(Values {
88                        i32_values: vec![1, 2, 3],
89                        ..Default::default()
90                    }),
91                    datatype: ColumnDataType::Int32 as i32,
92                    ..Default::default()
93                },
94                Column {
95                    column_name: "name".to_string(),
96                    values: Some(Values {
97                        string_values: vec!["a".to_string(), "b".to_string(), "c".to_string()],
98                        ..Default::default()
99                    }),
100                    datatype: ColumnDataType::String as i32,
101                    ..Default::default()
102                },
103            ],
104            row_count: 3,
105        };
106
107        let mut request =
108            to_table_delete_request("foo_catalog", "foo_schema", grpc_request).unwrap();
109
110        assert_eq!(request.catalog_name, "foo_catalog");
111        assert_eq!(request.schema_name, "foo_schema");
112        assert_eq!(request.table_name, "foo");
113        assert_eq!(
114            Arc::new(Int32Vector::from_slice(vec![1, 2, 3])) as VectorRef,
115            request.key_column_values.remove("id").unwrap()
116        );
117        assert_eq!(
118            Arc::new(StringVector::from_slice(&["a", "b", "c"])) as VectorRef,
119            request.key_column_values.remove("name").unwrap()
120        );
121        assert!(request.key_column_values.is_empty());
122    }
123}